From: fjh AT cs DOT mu DOT OZ DOT AU (Fergus Henderson) Subject: Re: Some problems in making DLL's for C++ programs with GCC 14 Feb 1997 12:44:11 -0800 Approved: cygnus DOT gnu-win32 AT cygnus DOT com Distribution: cygnus Message-ID: <199702141304.AAA26871.cygnus.gnu-win32@mundook.cs.mu.OZ.AU> Content-Type: text Original-To: Nick AT fys DOT ruu DOT nl (Nick van Eijndhoven) Original-Cc: gnu-win32 AT cygnus DOT com (gnu-win32) In-Reply-To: <199702121245.NAA12202@ruunf0.fys.ruu.nl> from "Nick van Eijndhoven" at Feb 12, 97 01:45:30 pm X-Mailer: ELM [version 2.4 PL24] Original-Sender: owner-gnu-win32 AT cygnus DOT com Nick van Eijndhoven wrote: > > > 1) Put all your compiled c++ stuff into a library using ar > > ar rc lib.a [...] > > 2) generate the .def file from lib.a > > echo EXPORTS > foo.def > > nm lib.a | grep " [CT] " | sed '/ _/s// /' | awk '{print $3; }' >> foo.def I'm using %.def: %.a echo EXPORTS > $@ nm $< | grep '^........ [T] _' | sed 's/[^_]*_//' >> $@ %.exp %.stubs.a : %.def dlltool --def $< --dllname $*.dll \ --output-exp $*.exp \ --output-lib $*.stubs.a in my GNUMake file. > ld -o foo.dll foo.exp *.o > > --> here I got the following error msgs with the result that no .dll was created. > The error msgs were : > > ...../LD.EXE: warning: cannot find entry symbol _mainCRTStartup: > defaulting to 00401000 That one seems safe to ignore. > aap.o<.text +0x10>:aap.cc: undefined reference to `cout' > ... and some more undef refs. to standard iostream stuff. [...] > I therefore tried : > > g++ -o foo.dll foo.exp *.o THat is a bad idea, I think. That will link in `crt0.o', which you don't want to do. `crt0.o' is the startup code that calls main(), and it has an undefined reference to main(). > ..../i386-cygwin32/lib/libcygwin.a: In function `main': > /pizza/mushroom/noer/beta17/src/winsup/libcmain.cc:30: > undefined reference to `WinMain AT 16' > > This error message I really don't understand (note that I didn't provide > a main() at all) and would appreciate if someone could help me out. This is the due to the linker dragging in main() from the library. libcmain.cc has a definition of main() that calls WinMain(). Instead of `g++ -o foo.dll foo.exp *.o', just use ld -o foo.dll foo.exp *.o `gcc --print-file-name=libg++.a` This will link in libg++.a. Actually I'm not sure whether this will link in _all_ of libg++.a, even the bits you're not using. If so, it would be better to do LIBGPP_FILE=`gcc --print-file-name=libg++.a`; LIBGPP_DIR=`dirname $LIBGPP_FILE`; ld -o foo.dll foo.exp *.o -L$(LIBGPP_DIR) -lg++ Now, even this is not quite enough. I have found that you need to change that to LIBGPP_FILE=`gcc --print-file-name=libg++.a`; LIBGPP_DIR=`dirname $LIBGPP_FILE`; ld -o foo.dll fixup.o foo.exp *.o -L$(LIBGPP_DIR) -lg++ ^^^^^^^ where fixup.s contains the following assembler code: .section .idata $3 .long 0,0,0,0, 0,0,0,0 This avoids various problems where the file links OK but won't run. Now, can anyone tell me what the situation with global variables in DLLs is? -- Fergus Henderson | "I have always known that the pursuit WWW: | of excellence is a lethal habit" PGP: finger fjh AT 128 DOT 250 DOT 37 DOT 3 | -- the last words of T. S. Garp. - For help on using this list, send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".