libtool
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

crossgcc mingw32 dll FAQ


From: Guido Draheim
Subject: crossgcc mingw32 dll FAQ
Date: Wed, 25 Jul 2001 16:29:45 +0200

   does anyone have another Q/A that could go into an FAQ?
   anynone a webpage already with some (same|other) explanation?

Q: can I use libtool 1.3.x to build dlls?
Q: where can I get a nice mingw32 crosscompiler
Q: I'm getting a libtool message saying "dunno-yo-lib"
Q: "dunno-yo-lib" but the lib is there, in a sys_lib of the gcc 
Q: dll in another subdirectory, found but "cannot execute binary"
Q: dll in another subdirectory, found but many unresolved symbols
Q: everything is resolved but a data-symbol from my dll

   ===========================================================================
Q: can I use libtool 1.3.x to build dlls?
A: Theoretically yes, practically no. Using libtool-1.4 is a far
   better choice, or use the patched version you can find in the
   SDL tarball living at http://libsdl.org. In any case, for 
   either 1.3.5 or 1.4 (but not the sdl-patched 1.3.x): 

               DO NEVER FORGET TO SET "-no-undefined"  

   as a linker flag, libtool won't do it automatically just for being
   needed in enable-shared mode. (Libtool can create about any win32
   static-libs even with undefined_allowed, but it would not do so
   with -no-undefined plus failures in creating the dll just before.)
   Since you are already doing a [case "$host" mingw*) ADD_FLAGS=xx]
   in your configure.ac, then you can go and have a look at some
   other useful options for win32/dll creation.
   -no-inhibit-exec ... but rarely with an effect, instead it may
              obscure some bugs during compiling. But it is sometimes
              helpful while deep in the development stage of your project.
   -mconsole or -mwindows ... links with different startup code,
              the latter assumes your code opens a GUI window on its own
              and likes to be run detached from console. Real windows
              developers even know about threaded libc, differences
              about dos-box/nt-box, stdout/stderr handling for GUI-apps,
              and quickwin options to have console unfold its own 
              window even when started on console - be lucky to have
              just the choice between two -m/machine options.
   --export-all-symbols ... a dlltool option, ignoring hints from
              gcc given via in-source __attribute__(dllexport) marks.
              There are other options, especially about export-lists
              from your handcrafted def-file, or regex-definition
              on symbols. But usually you just use this one.
   -export-dynamic ... the libtool option you would normally use
              to export functions - just as there are other defintions
              including regex-variants.
   -avoid-version ... a libtool option - since 1.4 the generated dll
              file be named as if for a unixish ld.so system - where it
              would be libmylib.2.5.8.so on ld.so system, it is now
              libmylib-2-5-8.dll for win32 compiling. This is roughneck
              style towards win32 naming scheme - remember that windows
              does not support symlinks, and therefore windows-dllloader 
              will never see files like libmylib.dll or libmylib2.dll
              or libmylib25.dll - they are simply not existant. Unless
              it is a private-lib, you want to something about, e.g. :
    -release ... a libtool option - on unix systems you would simply
              use "-release $VERSION" unless you care about the
              interface-age that you could tell via "-version-info".
              you might want to make it settable from configure.ac where
              you just delete the patch-level from the version-spec.
    -module  ... another libtool option that will make it to *not* put 
              the "lib"-prefix up front of your dll-name. However I do
              not recommend to use it - it makes compiling with unixish
              tools (including libtool) a lot more problematic, so just
              leave it and make everyone know that this dll is originally
              a unixish one. Use -module only for real dll-modules that
              are private to your app and imported via LoadLibrary.

   If you feel this is complicated then you have not seen the
   additional Makefile-rules and dlltool checks that were needed
   just a few years back. Be lucky that libtool is intelligent
   enough to make the needed dlltool calls on its own, and that
   you just need to guide it into the better directions with a
   few additional commandline options that nicely fit into
   automake's  _LIBADD, _LDFLAGS makevars.

Q: where can I get a nice mingw32 crosscompiler
A: RedHat has commercial offers for about any crosscompiler you
   want to have, and they possibly have a cygwin one prepackaged for free.
   There are a lot of infos how to compile a set of gcc/binutils but
   they are often outdated just as their prepackaged tools are - they
   have been in use by just one person alone, and they posted their
   tools to the net for reusage. After they got no feedback, it withered.
   The current best source for a linux-based mingw32 crosscompiler 
   lives at http://libsdl.org/Xmingw32 - this compiler is in frequent
   use for multiple dozen projects, so it has most of the initial 
   compile bugs clean out. It has correct gcc, binutils and windows-headers
   and offers also prebuilt cross-packages for commonly used libs

Q: I'm getting a libtool message saying
   *** Warning: This library needs some functionality provided by XXX.
   *** I have the capability to make that library automatically link in when
   *** you link to this library.  But I can only do this if you have a
   *** shared version of the library, which you do not appear to have.
   what's wrong?
A: current libtool has this message in six (!!) different places, so
   that there are six different answer to what's wrong. In general your
   linker line contains a "-lxxx" statement, and libtool was trying one
   of the six ways to handle it. Which method it did invoke is not
   visible, and there are mostly no further diagnostics. This FAQ
   can not help you either before libtool maintainers make the six
   messages screens simply different.

   for the rest of this faq, let's call the message screen "dunno-yo-lib"
 
Q: I get the "dunno-yo-lib" message screen but I do know that I have the 
   lib as it is installed in ..../cross-tools/.../i386-mingw../lib.
A: libtool wants to find the real lib-file before running the actual
   linker (dlltool friends). However there is a bug in the libtool.m4
   about the setting of sys_lib_search_path_spec being only correct
   for native-compiling (it has a $PATH_SEPARATOR ";" hardcoded). 

   Fix it by using a patched libtool.m4, 
   and a quick fix is to hardcode the path_spec.

Q: I try to link to a dll living in another subdirectory than the
   local target, the output screen says
       extracting exported symbol list from `libpfe-0-31-57.dll'
       [some text looking like monkey typing]
      ./libtool: .libs/impgen: cannot execute binary file
A: libtool needs an import-lib to resolve dependencies with the
   dll living in another's .libs-builddir. It tries to make one
   on the fly but binutils does not bring a dlltool with the
   required functionality. The monkey-typing is actually an effort
   to create an executable that can build extract a def-file that
   holds the exported-symbols-list from the dll that it had found.
   This exported-symbols-list-extractor is called "impgen", and
   the sourcecode impgen.c is shipped as part of your libtool. 
   The libtool has now created this impgen.c on the fly, and it
   did call a C compiler to compile it - but since you used a
   cross-compiler, the resulting executable is a win32-exe, and
   when called your operating system says "cannot execute binary file".

   quick fix: you need to set an AC_SUBST(HOST_CC) in your Makefile via
   configure.ac, and have that HOST_CC different from the current CC,
   there are possible ac-macros you can use, or try one yourself.

   debug fix: go the relevant .libs directory, remove about everything
   including "impgen", `cc impgen.c -o impgen ; ln -s impgen impgen.exe`

Q: I try to link to a dll living in another subdirectory, just as
   above, I have done everything correct, including the required -L,
   but I get a long set of "unresolved symbols" where I know that
   my other lib has them.
A: You have missed the impgen-message from above - the current
   impgen-hack uses a shell-redirection to create the def-file
   that contains the exported-symbols. If it can not execute then
   the def-file is still created but it is empty. The rest of the
   steps will continue, creating a nice libimpmylib that contains
   nothing but glue and no symbols at all.

   quick fix: you need to fix the impgen-crossgcc-bug as described
   above, go to your local ".libs"-builddir, and remove imp-defs
   like `rm libimp* ; rm *-def` so that the import-libs are going 
   to get rebuild on next linker-call

Q: everything is resolved but a data-symbol from my dll, is there
   another dllexport needed or what?
A: Theoretically you can both export and import data-symbols
   via dlls too, but practically you don't want to. Avoid it
   like hell. If you need to reference a data-table from another
   dll into something else, start adding a function-wrapper
   into your sources. That is
   NEVER TRY TO DO:
     lib1.c:
        _export data_entry datatable[] = { .... };
     lib2.c:
        extern data_entry datatable[];
        callwith(datatable);

   INSTEAD YOU DO:
      lib1.c:
         _export data_entry* datatable () {
               static data_entry _datatable[] = { .... }
               return _datatable;
         }
      lib2.c:
         extern data_entry* datatable ();
         callwith (datatable());

   In fact, if you declare an export-def for a data-symbol,
   the import-def needs to be declared as a pointer to it.
   The windows-loader will not patch your code section
   [ at "callwith(datatable)" the argument-push for the
     function-call is in the code-segment, and the address
     of datatable would be needed to be patched in]
   instead it has an import-table for you that it can
   fill with the address of the datatable in that other dll.
   [ you would ask for "callwith(*datatable)" where the
     datatable is a symbol (of simple pointer type) in the 
     import-section of your executable that gets filled 
     with the datatable-address of the (other, same-named)
    symbol in the dll (which is a real field in the example) ]



reply via email to

[Prev in Thread] Current Thread [Next in Thread]