views:

141

answers:

1

Hello:

Does anyone know what files are required for MySql to work with a Tcl Starkit? Currently, I have libmySQL.dll, libmysqltcl.dll, and pkgIndex.tcl. The pkgIndex.tcl has the following code:

proc loadmysqltcl {dir} {
   set oldcwd [pwd]
   cd $dir
   load libmysqltcl[info sharedlibextension]
   cd $oldcwd
  }

package ifneeded mysqltcl 3.03 [list loadmysqltcl $dir]

These files are located in my Tcl application lib folder. So far, after I wrap my application and run the exe. file, I get an error:

couldn't load library "C:/...TCL1055.tmp": this library or a dependent library could not be found in library path while executing "load libmysqltcl[info sharedlibextension]"

Furthermore, I notice that the missing .tmp file changes every time I try to run my application.

Has anyone had success with Tcl/MySql starkit (for Windows)?

Thanks,

DFM

+6  A: 

Starkits use some fancy tricks in order to be able to load libraries that are stored in the virtual filesystem bundled into the starkit itself. On Unix, you can direct the OS library loader to load a library from an arbitrary block of data, but on Windows, you can only load libraries from actual files on disk.

In order to accommodate that limitation, Windows starkits first copy the library out of the virtual filesystem to the real filesystem as a temp file. That's where your temp file names are coming from.

Now, all of that works fine as long as the libraries in your starkit do not themselves have dependencies on other libraries in your starkit. In your case, your libmysqltcl.dll probably depends on libmySQL.dll. At the time of loading, both of those have been copied to the real filesystem, but with temp file names, so the loader is not able to find libmySQL.dll.

You have a couple choices for working around this:

  1. Eliminate these second-level dependencies from your libraries. In this case, that means rebuilding libmysqltcl.dll with static linkage to the stuff in libmySQL.dll, rather than dynamically linking it against the dll.

  2. Before the package require in your startup script, explicitly copy the second-level dependencies out of your starkit to a location on the real filesystem, then update the PATH environment variable to include that directory.

Option #2 would look something like this:

set dirname [file dirname [info script]]
set tmpdir  [file join $env(TEMP) __myapp__]
file mkdir $tmpdir
foreach dll {libmySQL.dll} {
    if { ![file exists [file join $tmpdir $dll]] } {
        file copy -force [file join $dirname bin $dll] $tmpdir
    }
}
set ::env(PATH) "$tmpdir;$env(PATH)"

Then you should be able to do your package require as expected.

It's a bit clunky for sure, but the blame lies pretty squarely on Windows for not allowing you to load libary code from memory rather than from a file.

Eric Melski
Thanks Eric - I tried option number 2 with no luck. I placed your code below "package require mysqltcl" in my application. I then wrapped it and tried running it with no luck. I also placed your code in the pkgIndex.tcl file, with and without the included code, and it did not work. It sounds like your answer should work so I think I am doing something wrong. Also, I changed "_myapp_" to the real application name, which is Small_Business_Database_application. I hope the underscores in the name didn't affect my results. Do you have any suggestions?Thanks,DFM
DFM
This code has to come before the "package require". Also, if you put this code in a proc, be sure to change "$env(TEMP)" to "$::env(TEMP)".
Eric Melski
Thank you for the follow up. I really appreciate your help. Everything is working properly now. Regards,DFM
DFM