test6-ltdlopen Try again to allow the module to reference symbols in the executable. But this time, eliminate direct symbol references from the executable to the module, so that the executable can be linked first. I believe this will work ok for win32 and it's closer to how plugins need to work. On win32, what's needed is to make an executable that exports some symbols so that the plugins can import them. So far I have been unable to get libtool to make an executable that exports symbols. One trick that I tried was to compile main.lo into a dynamic library libmain.la. Then plugins linked against libmain.la and the executable could be build from libmain.la. But even for a trivial application, when the main() is in a DLL on my cygwin box it crashes. It doesn't ever find the main() symbol, or something. So for cygwin/win32 I will have to use a separate makefile target instead of libtool. Try using the makefiles that work (non-libtool) from test7-win32dll with libltdl code. Can it work? It only searched the first directory in my PATH, /usr/local/bin. Why? Because of this bug: Index: ltdl.c =================================================================== RCS file: /cvsroot/bochs/bochs-testing/plugin-test/libltdl/ltdl.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ltdl.c 14 Oct 2002 21:05:06 -0000 1.3 +++ ltdl.c 15 Oct 2002 20:56:27 -0000 1.4 @@ -2257,7 +2257,7 @@ lt_ptr ignored; { lt_dlhandle *handle = (lt_dlhandle *) data; - int found = access (filename, R_OK); + int found = (0 == access (filename, R_OK)); /* Bail out if file cannot be read... */ if (!found) With that patch, it searches all paths in the pathname list. Also I had trouble with lt_dlopenext(). It seems to quit after trying just the ".la" extension, when it's supposed to try several different extensions. I made couple more changes in ltdl.c, another clear boolean logic bug. It should only stop searching if errors>0 and the error WAS file not found. With this change, it searches more than just the .la extension. Index: ltdl.c =================================================================== RCS file: /cvsroot/bochs/bochs-testing/plugin-test/libltdl/ltdl.c,v retrieving revision 1.4 diff -u -r1.4 ltdl.c @@ -2971,7 +2979,7 @@ failed, it is better to return an error message here than to report FILE_NOT_FOUND when the alternatives (foo.so etc) are not in the module search path. */ - if (handle || ((errors > 0) && file_not_found ())) + if (handle || ((errors > 0) && !file_not_found ())) { LT_DLFREE (tmp); return handle; @@ -2998,7 +3006,7 @@ /* As before, if the file was found but loading failed, return now with the current error message. */ - if (handle || ((errors > 0) && file_not_found ())) + if (handle || ((errors > 0) && !file_not_found ())) { LT_DLFREE (tmp); return handle; This patch causes try_dlopen to return FILE_NOT_FOUND when the library cannot be found, instead of returning crap. Index: ltdl.c =================================================================== RCS file: /cvsroot/bochs/bochs-testing/plugin-test/libltdl/ltdl.c,v retrieving revision 1.4 diff -u -r1.4 ltdl.c @@ -2858,7 +2866,7 @@ #endif ))) { - tryall_dlopen (&newhandle, filename); + errors += tryall_dlopen (&newhandle, filename); } if (!newhandle) I cannot figure out why libtool does #define LTDL_SHLIB_EXT "dll.a" for cygwin. Isn't .libs/libNAME.dll.a an intermediate step created by dlltool, while the real DLL is called .libs/cygNAME-0.dll ? Based on the size of the .dll.a and the contents, it looks like it is an import library for cygNAME-0.dll. But then, if another library refers to libNAME.la, libtool makes another import lib: it says "generating import library for cygNAME-0.dll" and creates libimp-cygNAME-0.a which seems identical to the other except for the name. Is there any use for the libNAME.dll.a? And why would LTDL want to load it instead of the DLL itself? ------------------------------------------------- BUG: LTDL_SYSSEARCHPATH is set up using a path separator determined at configure time using this code: case "$host" in *-*-mingw*) pathsep=";" ;; *) pathsep=":" ;; esac But then in ltdl.h LT_PATHSEP_CHAR uses different rules to set LT_PATHSEP_CHAR. On cygwin with -mno-cygwin, the LTDL_SYSSEARCHPATH is set to "/lib:/usr/lib" but the LT_PATHSEP_CHAR is ';'. Obviously when the time comes to separate "/lib:/usr/lib" using the semicolon delimiter, it fails to separate them into two different paths. If I manually change LTDL_SYSSEARCHPATH in config.h to have a semicolon separator, then it splits up the string and searches in both /lib and /usr/lib. A second, related problem, is that since I'm using mingw libraries, not cygwin libraries, paths like "/lib" are not recognzied. If I change LTDL_SYSSEARCHPATH to "d:/cygwin/lib;d:/cygwin/usr/lib" then finally I can find modules in these directories. ------------------------------------- BUG: If you try to include in a source file that is compiled by libtool, you will probably have trouble with multiple definitions of a few variables (function pointers...**FIXME**). These variables should be declared extern in ltdl.h file, and then actually defined in ltdl.c. Otherwise every source file that includes ltdl.h will declare its own symbol for them. The problem is related to LT_SCOPE. Defining LT_SCOPE to extern before including ltdl.h fixed it.