OT: crossgcc mingw32 dll FAQ

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

[I did run this one through libtool-ML, but I guess there are even more developers on the SDL-ML who do regularly use some crossgcc mingw32 for their current projects, sorry for being a bit offtopic]

Q: can I use libtool 1.3.x to build dlls?
Q: where can I get a nice mingw32 crosscompiler
Q: what about debian 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_os” in mingw*) _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 do something about it, 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 can 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 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, the webpages
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 cleaned out. It has correct gcc, binutils and windows-headers
and offers also prebuilt cross-packages for commonly used libs

Q: what about the debian mingw32 crosscompiler? what about debian at win?
A: in 2000, some debian developers started a project to port a decent set
of unixish tools to windows, most of the based on GPL cygwin environment.
Right there you will also find a good mingw32 crosscompiler package
in the unstable/testing section of the debian repository that you can
use. There had been plans (and still are) to add a windows platform
(cygwin, mingw, pw32) for the automatic test building of debian
systems - the release of Qt at win for free use will further efforts
in that direction in the next time. This is no social effort from
trolltech.com, it is meant so that kde-based apps (like kde itself is
now) will more and more detach itself from X11 which renders them at
the same time to be compilable on top of embedded-Qt and handheld-OS.
Anyway, this move (just a few weeks old at the time of writing) will
involve more people into the process of cross-compiling to windows
targets, thereby using libtool’s functionality about it.
(btw, debian’s target is i586-mingw32msvc which according to the
packager makes sense because the target OS do not run on i386).

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* ; rem *-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
_export data_entry datatable[] = { … };
extern data_entry datatable[];

_export data_entry* datatable () {
static data_entry _datatable[] = { … }
return _datatable;
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) ]