andreas-kupries / critcl

Critcl lets you easily embed C code in Tcl. Online documentation at
http://andreas-kupries.github.io/critcl
Other
72 stars 19 forks source link

clibraries limited to compile search path. Not used at runtime #121

Closed andreas-kupries closed 2 years ago

andreas-kupries commented 2 years ago

From https://github.com/andreas-kupries/critcl/issues/116#issuecomment-1037809980

[esternin] figured out what is not working with the libraries outside of the default LD_LIBRARY_PATH. The crit::clibraries does get used when compiling the code, but not when running it. The loader does not get passed this via, for example, the setting of LD_LIBRARY_PATH at run-time. I think this is a bug. The workaround is to only use libraries that are in default locations, like /usr/local/lib. This probably is a separate issue, I'll let you decide.

From later in the thread

[aku] forgot to respond to

[esternin] think the issue is the inconsistency, because C is a compiled language, and tcl is interpreted, I am expecting that if the code did not raise a flag at compile time - it found the routines specified in crit::clibraries - then the code should run as well.

earlier. ... This was actually a good argument for me to see it as a bug to be fixed. Less about the C/Tcl difference, and more that while I use critcl pretty much exclusively in package mode (i.e. ahead of time compilation via critcl -pkg ...) it does have a compile and run mode where you simply package require the critcl-based package and it compiles and loads the C code for you on the fly (if you have a working cc, with caching under ~/.critcl/). Without a fix this mode breaks on non-standard library locations.

To fix.

andreas-kupries commented 2 years ago

@esternin PR #122 is a tentative fix.

andreas-kupries commented 2 years ago

And not working out. The idea was to extend env(LD_LIBRARY_PATH) of the running tclsh. This does not have any effect. I can confirm that the desired path is added, and yet the library is not found. OTOH, setting LD_... before starting tclsh I see the path doubled (expected), and the library now is found. I suspect that the dynamic loader, i.e. libdl, looks at LD_... once, at startup, and then never again.

Ok, the other idea I had works:

lappend cmdline -Wl,-rpath,$path

I.e. put the search path for the dependency into the package shlib during linking.

My problem with this solution is portability. Will this work for Solaris, HPUX, AIX compilers ? How about Windows?

Even with these questions, it looks to be better than before, it should work for anything using gcc.