I have observed that under OS X 10.6 (at least), libraries loaded with Tcl's load are not visible from other libraries, also loaded with load.
Thus if you load a library A, and then load a library B that depends on A, library B is not loaded if A does not resides on a directory the dynamic linker searches for libraries. It is not recognised that library A is already loaded in the process.
This seems OS X specific, as I cannot reproduce at least under windows & linux.
I know that load calls dlopen(..., RTLD_GLOBAL); which does not seem to do as advertised.
I had to call NSAddImage(NSADDIMAGE_OPTION_RETURN_ON_ERROR |
NSADDIMAGE_OPTION_WITH_SEARCHING |
NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME ), after I loaded lib A, to be able to load lib B.
However, NSAddImage is already deprecated in 10.6.
The relevant thread is here:
http://groups.google.gr/group/comp.lang.tcl/browse_thread/thread/87266afd63143a11/f9b735ee56100d57
On second thought, I realize that the error message is not at the symbol level, but at the dependency level, so indeed RTLD_GLOBAL is not really concerned. Now, there are two ways of loading a library: either implicitly through dependency, or programmatically with dlopen(). A is loaded through dlopen(), then B too, and B implicitly needs A, but at this point in time, A is *not* "implicitly loaded".
So, *if* OSX maintains two separate lists of dylds, one implicitly loaded, the other dlopened(), that could explain the behavior. Daniel, is this possible ?
And if it is the case, then the solution is to refactor A so that it contains only the Tcl API entry points needed for an extension, and shove all the useful shareable code into a 3rd library C, on which A depends. Hence, [load A] also loads C but on the implicit list. Then do the same for B, and C should be reused as is.
Can you clarify the versions of Tcl and OS X involved?
tcl/unix/tclLoadDyld.c was switched to use RTLD_GLOBAL on 2009-04-10, anything built from sources earlier than that is using RTLD_LOCAL.
I have observed this behaviour under OS X 10.6, and ActiveTcl 8.6.0.0b3.
I don't remember the date ActiveTcl 8.6.0.0b3 was released. And it is true that I looked at the latest CVS head for the sources, when concluding that RTLD_GLOBAL is used by load.
Looking at the dates of files, i.e. wish8.6 in /usr/local/bin, I see a date of May 20. But I don't know if they include the change or not.
See: <http://www.tcl.tk/cgi-bin/tct/tip/416>
Since Tcl 8.6, [load -global] can be used to remedy this.