ocra icon indicating copy to clipboard operation
ocra copied to clipboard

Problems with tk gem on windows

Open basex opened this issue 7 years ago • 14 comments

In the past I had a ruby 2.2 app with a GUI with tk that I was able to create an executable in ocra and run in any computer.

I recently upgraded the development environment to ruby 2.5, created an executable with ocra and now when I run the executable in a different machine I get the error:

C:/Users/ADMINI~1/AppData/Local/Temp/2/ocr4FD8.tmp/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require': 126:
The specified module could not be found.   - C:/Users/Administrator/AppData/Local/Temp/2/ocr4FD8.tmp/lib/ruby/gems/2.5.0/gems/tk-0.2.0/lib/tcltklib.so (LoadError)
  • The development environment and the machine where I run the executable are both Windows.
  • The error is when running: require 'tk'
  • tcltklib.so is inside the correct folder. I checked by creating the executable with --debug-extract.

The problem is solved on the machine where I run the executable if I install ruby 2.5 and do gem install tk. After that, the executable runs without errors.

Anyone have an idea how to solve this? With ruby 2.4 the same problem happens.

basex avatar Jan 13 '18 16:01 basex

I am currently still facing this issue with Ruby 2.6.5. Did you or someone else found a solution by now? It sucks being forced to change GUI just because of this.

crazynoob04 avatar Mar 13 '20 01:03 crazynoob04

With current RubyInstaller and Devkit, tcl/tk dependencies now live outside the ruby installation and the tk Gem. Makes it kind of hard to auto-detect what files are required to be able to run.

larsch avatar Mar 15 '20 14:03 larsch

Is there any workaround for this? I tried to add TK path as last argument when compiling with OCRA, but that returned the same error.

crazynoob04 avatar Mar 16 '20 00:03 crazynoob04

It may be possible to copy the correct dependencies (DLL's, tcl init files, etc) from the DevKit installation into the project directory and add everything as additional files, making sure that the files end up in the necessary locations.

To implement support for this in OCRA would require having special "profiles" for Tk and other 3rd party dependencies, which seem even more fragile than OCRA already is. Pulling in the entire DevKit also doesn't sound appealing.

larsch avatar Mar 16 '20 10:03 larsch

I am just an amateur but adding the TK directory when compiling with OCRA sounds promising. I guess i will check for good where OCRA expects TK to be, then do it manually. I will give a try soon and i will update this issue.

(With Ruby 2.3.3 it was possible to just add TK path as option for the --window argument, i tried the same with 2.6.5, linking the TK gem directory but it didn't work)

crazynoob04 avatar Mar 17 '20 00:03 crazynoob04

I tried adding TK folder inside my project folder and packing it with Ocra, but that didn't help. My knowledge also doesn't let me to try further, but i will be open to test any workaround suggested, if any.

crazynoob04 avatar Mar 23 '20 01:03 crazynoob04

I have been able to get a Ruby-Tk (Ruby 2.6, Tk 8.6) application working with the new version of Ocra by fiddling quite a bit with the Tk libraries, to put them in a spot where the Tk gem will find them. Here is an outline of my process:

  1. Copy tcl86.dll and tk86.dll from C:/ruby26-x64/msys64/mingw64/bin to C:/ruby26-x64/bin.

  2. Copy tcl8, tcl8.6 and tk8.6 from ruby26-x64/msys64/mingw64/lib to C:/ruby26-x64/lib. Make sure dde1.4 and reg1.3 are installed in the tcl8.6 directory.

  3. Copy tcl8, tcl8.6 and tk8.6 from ruby26-x64/msys64/mingw64/lib to a "lib" folder in your own script's source directory, i.e. srcdir/lib.

  4. Add these lines to the beginning of your main Ruby script, before calling 'require tk':

require 'fileutils'
begin
    FileUtils.cp_r(File.dirname(__FILE__) + '/lib/tcl8.6/.', File.dirname(File.dirname(File.dirname(__FILE__))) + '/lib/tcl8.6', remove_destination: true)
    FileUtils.cp_r(File.dirname(__FILE__) + '/lib/tcl8/.', File.dirname(File.dirname(File.dirname(__FILE__))) + '/lib/tcl8', remove_destination: true)
    FileUtils.cp_r(File.dirname(__FILE__) + '/lib/tk8.6/.', File.dirname(File.dirname(File.dirname(__FILE__))) + '/lib/tk8.6', remove_destination: true)
rescue
    raise
end

This will put the Tcl libraries in a location where the Tk gem can find them when your app executable is unpacked.

  1. Finally, build your app with this invocation:

ocra srcdir/yourscript.rb srcdir/lib/**/* --no-autoload -–add-all-core --gem-full=tk --dll tcl86.dll --dll tk86.dll --no-enc

You can add the "--debug-extract" to inspect the output of the unpacked app, if you want.

The startup time for your app will be a bit long, but at the end you will see the same Tk window displaying as when you just ran the script with "ruby myscript.rb."

I hope this is helpful.

codebykevin avatar Apr 20 '20 02:04 codebykevin

Thanks for this! Unfortunately, after weeks of tries, i ended up going back to ruby 2.3.3. I will test again on 2.6 soon, when i have some free time. I'm sure this will work, i tried something similar as you can read above, but i would never get to this point, i'm not an expert at all. Really thank you for your hard work!

crazynoob04 avatar Apr 20 '20 02:04 crazynoob04

codebykevin, when i try your solution i get the following error: /AppData/Local/Temp/1/ocrE8D0.tmp/lib/ruby/gems/2.6.0/gems/tk-0.2.0/lib/tk.rb:32:in `initialize': Can't find a usable init.tcl in the following directories: (RuntimeError) .../AppData/Local/Temp/1/ocrE8D0.tmp/lib/tcl8.6 .../AppData/Local/Temp/1/ocrE8D0.tmp/lib/tcl8.6 .../AppData/Local/Temp/1/lib/tcl8.6 .../AppData/Local/Temp/1/ocrE8D0.tmp/library .../AppData/Local/Temp/1/library .../AppData/Local/Temp/1/tcl8.6.9/library .../AppData/Local/Temp/tcl8.6.9/library This probably means that Tcl wasn't installed properly.

do you have any advice on this?

ericramsey-bread avatar May 13 '20 14:05 ericramsey-bread

Try putting the Tcl libraries (the ones that the script copies) into a directory called "lib" in your source directory (where your main script is). I don't think I mentioned this earlier, sorry about that. Otherwise the files won't get copied to the right place when the exe is unpacked, is my guess.

codebykevin avatar May 13 '20 21:05 codebykevin

@codebykevin I did try that, still got the same error. I have given up on using tk and have moved onto fxruby and am just going to create my own windows.

ericramsey-bread avatar May 15 '20 12:05 ericramsey-bread

I realized my app was working because I had built it with ocra using the --debug-extract flag, and the temporary directory was being dumped into my app directory alongside my Tk libraries that were placed in a directory called "lib." That happens to be one of Tk's search paths for its libraries. So that's how I decided to deploy the app -- omit the Tk libraries from the exe, just install them alongside the app in "./lib" in my setup.exe. That works. It's messy, because a temporary directory is dumped into the app folder every time my app is run, but it works. And so I've released it this way and am moving forward.

codebykevin avatar May 20 '20 11:05 codebykevin

add file/directory \msys32\usr\bin\msys-2.0.dll \msys32\mingw32\lib\tcl8.6 \msys32\mingw32\lib\tk8.6

ocra tk_test.rb C:\Ruby26\msys32\usr\bin\msys-2.0.dll C:\Ruby26\msys32\mingw32\lib\tcl8.6 C:\Ruby26\msys32\mingw32\lib\tk8.6 --no-autoload --add-all-core --no-lzma --gem-all

takka-tfact avatar Sep 04 '20 04:09 takka-tfact

here is a working example packing a ruby/tk app. ocra test.rb --dll ruby_builtin_dlls\libssp-0.dll --dll ruby_builtin_dlls\libssl-1_1-x64.dll --dll ruby_builtin_dlls\libcrypto-1_1-x64.dll --gem-file C:\Ruby26-x64\ssl C:\Ruby26-x64\msys64\usr\bin\msys-2.0.dll C:\Ruby26-x64\msys64\mingw64\bin\tk86.dll C:\Ruby26-x64\msys64\mingw64\lib\tcl8.6 C:\Ruby26-x64\msys64\mingw64\lib\tk8.6 --no-autoload --add-all-core --no-lzma --gem-all --output .\release\test.exe --debug-extract --chdir-first

ruby_builtin_dlls\libssl-1_1-x64.dll ruby_builtin_dlls\libcrypto-1_1-x64.dll C:\Ruby26-x64\ssl these should be specific to my app.

hupeng2006 avatar Dec 07 '21 07:12 hupeng2006