From 4d7172def0a985ced97f197cee7973f304a5cc51 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Wed, 21 Jul 1999 19:18:03 +0000 Subject: [PATCH] Win32: With the latest gcc (2.95, pre-release), we can have binary compatibility with MSVC by using the switch -fnative-struct. No longer build DLLs with .gcc in the name when using gcc. * README.win32: Renew gcc build instructions. * build-dll: Comments change, handle also .a files. * makefile.cygwin.in * tests/makefile.cygwin.in: Remove .gcc from DLL name. --- README.win32 | 94 +++++++++++++++++++++++------------------------- build-dll | 8 ++--- makefile.cygwin.in | 50 +++++++++++++------------- tests/makefile.cygwin.in | 4 +-- 4 files changed, 75 insertions(+), 81 deletions(-) diff --git a/README.win32 b/README.win32 index ad4b683..36b9b51 100644 --- a/README.win32 +++ b/README.win32 @@ -10,11 +10,12 @@ library is used. To build GLib on Win32, you can use either the Microsoft compiler and tools, or gcc. Both the compiler from MSVC 5.0 and from MSVC 6.0 have -been used successfully. With gcc I mean egcs-1.1.2 (as distributed by -Mumit Khan), running under cygwin-b20.1. To successfully use gcc, -follow the instructions below. We want to use gcc -mno-cygwin, -i.e. produce executables (.exe and .dll files) that do *not* require -the cygwin runtime library. This is sometimes called "mingw32". +been used successfully. With gcc I mean the gcc-2.95 pre-release as +distributed by Mumit Khan, running under cygwin-b20.1. To successfully +use gcc, follow the instructions below. We want to use gcc +-mno-cygwin, i.e. produce executables (.exe and .dll files) that do +*not* require the cygwin runtime library. This is sometimes called +"mingw32". To test the GLib functions, go to the tests subdirectory and enter `nmake -f makefile.msc check` or `make -f makefile.cygwin check`. @@ -46,7 +47,7 @@ GLib (or GTk+, which uses GLib). Additionally, there are the compiler-specific macros: - _MSC_VER is defined when using the Microsoft compiler -- __GNUC__ is defined when using GCC (i.e. egcs) +- __GNUC__ is defined when using GCC Some of the usage of these macros used to be a bit mixed up, and had to be straightened out when adding the gcc support. In particular, I @@ -90,44 +91,20 @@ Building with gcc ================= The gcc support was added quite recently, but seems to work. Debugging -with gdb works. I prefer to use the msvcrt runtime and not the default -crtdll. Especially, as the pthread library also uses msvcrt, using -crtdll would probably not be a good idea at all. Using msvcrt can be -achieved by applying the following diff to the specs file, which -typically is installed as -C:\cygnus\cygwin-b20\H-i586-cygwin32\lib\gcc-lib\i586-cygwin32\egcs-2.91.66\specs. - -Sorry for the illegibility of this diff, but the specs file is like -that... This patch replaces -lcrtdll with -lmsvcrt, replaces crt1 with -crt2, removes -lmoldname (because using functions from it would pull -in crtdll.dll), and defines __MSVCRT__. - ---- specs.ORIG Sun Apr 25 00:40:40 1999 -+++ specs Sun Apr 25 00:48:04 1999 -@@ -23 +23 @@ --%{pg:-lgmon} %{!mno-cygwin:-lcygwin} %{mno-cygwin:-lmingw32 -lmoldname -lcrtdll} %{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32 -ladvapi32 -lshell32 -+%{pg:-lgmon} %{!mno-cygwin:-lcygwin} %{mno-cygwin:-lmingw32 -lmsvcrt} %{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32 -ladvapi32 -lshell32 -@@ -29 +29 @@ --%{mdll: %{!mno-cygwin:dllcrt0%O%s} %{mno-cygwin:dllcrt1%O%s}} %{!mdll: %{!mno-cygwin:crt0%O%s} %{mno-cygwin:crt1%O%s} %{pg:gcrt0%O%s}} -+%{mdll: %{!mno-cygwin:dllcrt0%O%s} %{mno-cygwin:dllcrt2%O%s}} %{!mdll: %{!mno-cygwin:crt0%O%s} %{mno-cygwin:crt2%O%s} %{pg:gcrt0%O%s}} -@@ -38 +38 @@ ---Di386 -D_WIN32 -DWINNT -D_X86_=1 -D__STDC__=1 -D__stdcall=__attribute__((__stdcall__)) -D__cdecl=__attribute__((__cdecl__)) -D__declspec(x)=__attribute__((x)) -Asystem(winnt) -Acpu(i386) -Amachine(i386) -+-Di386 -D_WIN32 %{mno-cygwin:-D__MSVCRT__ } -DWINNT -D_X86_=1 -D__STDC__=1 -D__stdcall=__attribute__((__stdcall__)) -D__cdecl=__attribute__((__cdecl__)) -D__declspec(x)=__attribute__((x)) -Asystem(winnt) -Acpu(i386) -Amachine(i386) - -You should also fix two bugs in the mingw32 headers: The type of -_dev_t in the header mingw32/sys/types.h should be unsigned int, not -short. The type for st_uid in sys/stat.h to be short, not int. This is -what the Microsoft's headers and runtime library use. Otherwise -accessing the fields in a stat struct as filled in by the stat and -fstat functions in the MS library will cause various interesting -failures. - -You also will have to get the mingw32 runtime source from -ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/runtime/source-1999-04-05.tar.gz -(this is the source to the "mingw32" part of Mumit Khan's egcs-1.1.2 -distribution.) Unpack it and fix the prototype and call to -__getmainargs() in init.c to include one more parameter, an int *, -which should be passed the address of a zero int. Code snippets below: +with gdb works. I use the latest and greatest gcc and mingw32. +Somewhat earlier versions will also work, but you are on your own. + +Fetch the gcc-2.95 developer snapshot from +ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/cygwin/snapshots/gcc-2.95-19990715/. +Install it somewhere, for instance \gcc-2.95. + +Fetch the mingw runtime snapshot from 1999-07-15 from +ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/runtime/. You +must fix two bugs in it: + +1) Fix the prototype and call to __getmainargs() in init.c to include +one more parameter, an int *, which should be passed the address of a +zero int. Code snippets below: ... #ifdef __MSVCRT__ @@ -140,12 +117,29 @@ extern void __getmainargs(int *, char***, char***, int, int *); #else ... -Remake dllcrt2.o (which is the file which gets linked into dlls when -using msvcrt, as per the specs file above), and move it into place -(typically C:\cygnus\cygwin-b20\H-i586-cygwin32\i586-cygwin32\lib\dllcrt2.o). +2) Fix the type of the function __p___argv() in stdlib.h to be char***, +not char**. + +Build the mingw32 runtime and install the libraries in the +gcc-2.95\H-i586-cygwin32\lib directory, and the headers in the +gcc-2.95\H-i586-cygwin32\i586-cygwin32\include\mingw32 directory. +Remember to build and install also the w32api import libraries and +headers. + +I prefer to use the msvcrt runtime and not the default +crtdll. Especially, as the pthread library also uses msvcrt, using +crtdll would probably not be a good idea at all. Using msvcrt can be +achieved by applying a few changes to the specs file. + +The specs file is in gcc-2.95\H-i586-cygwin32\lib\gcc-lib\i586-cygwin32\2.95 + +The necessary changes are: replace -lcrtdll with -lmsvcrt, replace +crt1 with crt2, change -lmoldname to -lmoldname-msvc, and define +__MSVCRT__. -Next, go back to the GLib directory and build using `make -f makefile.cygwin`. -Building the dlls uses the script build-dll which is an awful hack. But -I couldn't get things working in a cleaner way. +Next, go back to the GLib directory and build using `make -f +makefile.cygwin`. Building the dlls uses the script build-dll which +is somewhat of a hack. But I couldn't get things working in a cleaner +way. --Tor Lillqvist diff --git a/build-dll b/build-dll index 1f5c381..958b45f 100644 --- a/build-dll +++ b/build-dll @@ -1,11 +1,11 @@ #!/bin/sh # Temporary hack until building dlls or executables with exported -# entry points is easier with gcc -mno-cygwin. +# entry points is easier with gcc -mno-cygwin ("mingw32"). # This is usable with cygwin b20.1 and egcs-2.91.66 19990314 -# (egcs-1.1.2 release) as distributed by Mumit Khan. For other combinations, -# no idea. +# (egcs-1.1.2 release) or gcc-2.95 as distributed by Mumit Khan. For +# other combinations, no idea. GCC=gcc DLLTOOL=dlltool @@ -25,7 +25,7 @@ dllfile=$libname.dll for F in $ldargs; do case $F in - *.o) objs="$objs $F";; + *.[ao]) objs="$objs $F";; esac done diff --git a/makefile.cygwin.in b/makefile.cygwin.in index aa65d86..f12e9be 100644 --- a/makefile.cygwin.in +++ b/makefile.cygwin.in @@ -19,7 +19,7 @@ OPTIMIZE = -g -O # Nothing much configurable below -CC = gcc -mno-cygwin -mpentium +CC = gcc -mno-cygwin -mpentium -fnative-struct CP = cp LD = ld @@ -33,19 +33,19 @@ CFLAGS = $(OPTIMIZE) -I. -DHAVE_CONFIG_H all : \ config.h \ glibconfig.h \ - glib-$(GLIB_VER).gcc.dll \ + glib-$(GLIB_VER).dll \ gmodule/gmoduleconf.h \ - gmodule-$(GLIB_VER).gcc.dll \ - gthread-$(GLIB_VER).gcc.dll \ + gmodule-$(GLIB_VER).dll \ + gthread-$(GLIB_VER).dll \ testglib.exe \ testgmodule.exe \ testgdate.exe \ testgdateparser.exe install : all - $(INSTALL) glib-$(GLIB_VER).gcc.dll $(BIN) - $(INSTALL) gmodule-$(GLIB_VER).gcc.dll $(BIN) - $(INSTALL) gthread-$(GLIB_VER).gcc.dll $(BIN) + $(INSTALL) glib-$(GLIB_VER).dll $(BIN) + $(INSTALL) gmodule-$(GLIB_VER).dll $(BIN) + $(INSTALL) gthread-$(GLIB_VER).dll $(BIN) glib_OBJECTS = \ garray.o \ @@ -77,8 +77,8 @@ glib_OBJECTS = \ gscanner.o \ gutils.o -glib-$(GLIB_VER).gcc.dll : $(glib_OBJECTS) glib.def - ./build-dll glib $(GLIB_VER).gcc glib.def $(glib_OBJECTS) -luser32 -lwsock32 +glib-$(GLIB_VER).dll : $(glib_OBJECTS) glib.def + ./build-dll glib $(GLIB_VER) glib.def $(glib_OBJECTS) -luser32 -lwsock32 glibconfig.h: glibconfig.h.win32 $(CP) glibconfig.h.win32 glibconfig.h @@ -92,8 +92,8 @@ config.h: config.h.win32 gmodule_OBJECTS = \ gmodule.o -gmodule-$(GLIB_VER).gcc.dll : $(gmodule_OBJECTS) gmodule/gmodule.def - ./build-dll gmodule $(GLIB_VER).gcc gmodule/gmodule.def $(gmodule_OBJECTS) -L. -lglib-$(GLIB_VER).gcc -lwsock32 +gmodule-$(GLIB_VER).dll : $(gmodule_OBJECTS) gmodule/gmodule.def + ./build-dll gmodule $(GLIB_VER) gmodule/gmodule.def $(gmodule_OBJECTS) -L. -lglib-$(GLIB_VER) -lwsock32 gmodule.o : gmodule/gmodule.c gmodule/gmodule-win32.c $(CC) $(CFLAGS) -Igmodule -c -DG_LOG_DOMAIN=g_log_domain_gmodule gmodule/gmodule.c @@ -104,51 +104,51 @@ gmodule/gmoduleconf.h: gmodule/gmoduleconf.h.win32 gthread_OBJECTS = \ gthread-impl.o -gthread-$(GLIB_VER).gcc.dll : $(gthread_OBJECTS) glib-$(GLIB_VER).gcc.dll gthread/gthread.def - ./build-dll gthread $(GLIB_VER).gcc gthread/gthread.def $(gthread_OBJECTS) -L. -lglib-$(GLIB_VER).gcc $(PTHREAD_LIB) +gthread-$(GLIB_VER).dll : $(gthread_OBJECTS) glib-$(GLIB_VER).dll gthread/gthread.def + ./build-dll gthread $(GLIB_VER) gthread/gthread.def $(gthread_OBJECTS) -L. -lglib-$(GLIB_VER) $(PTHREAD_LIB) gthread-impl.o : gthread/gthread-impl.c gthread/gthread-posix.c $(CC) $(CFLAGS) $(PTHREAD_INC) -DG_LOG_DOMAIN=\"GThread\" -c gthread/gthread-impl.c -testglib.exe : glib-$(GLIB_VER).gcc.dll testglib.o - $(CC) $(CFLAGS) -o testglib testglib.o -L. -lglib-$(GLIB_VER).gcc $(LDFLAGS) +testglib.exe : glib-$(GLIB_VER).dll testglib.o + $(CC) $(CFLAGS) -o testglib testglib.o -L. -lglib-$(GLIB_VER) $(LDFLAGS) testglib.o : testglib.c $(CC) -c $(CFLAGS) testglib.c -testgdate.exe : glib-$(GLIB_VER).gcc.dll testgdate.o - $(CC) $(CFLAGS) -o testgdate.exe testgdate.o -L. -lglib-$(GLIB_VER).gcc $(LDFLAGS) +testgdate.exe : glib-$(GLIB_VER).dll testgdate.o + $(CC) $(CFLAGS) -o testgdate.exe testgdate.o -L. -lglib-$(GLIB_VER) $(LDFLAGS) testgdate.o : testgdate.c $(CC) -c $(CFLAGS) testgdate.c -testgdateparser.exe : glib-$(GLIB_VER).gcc.dll testgdateparser.o - $(CC) $(CFLAGS) -o testgdateparser.exe testgdateparser.o -L. -lglib-$(GLIB_VER).gcc $(LDFLAGS) +testgdateparser.exe : glib-$(GLIB_VER).dll testgdateparser.o + $(CC) $(CFLAGS) -o testgdateparser.exe testgdateparser.o -L. -lglib-$(GLIB_VER) $(LDFLAGS) testgdateparser.o : testgdateparser.c $(CC) -c $(CFLAGS) testgdateparser.c -testgmodule.exe : glib-$(GLIB_VER).gcc.dll gmodule-$(GLIB_VER).gcc.dll testgmodule.o libgplugin_a.dll libgplugin_b.dll +testgmodule.exe : glib-$(GLIB_VER).dll gmodule-$(GLIB_VER).dll testgmodule.o libgplugin_a.dll libgplugin_b.dll # Wow, do we really have to do it like this to get some symbols # exported from a .exe? Apparently yes. Does the __declspec(dllexport) # actually do anything in egcs-1.1.2? - $(CC) $(CFLAGS) -Wl,--base-file,testgmodule.base -o testgmodule.exe testgmodule.o -L. -lglib-$(GLIB_VER).gcc -lgmodule-$(GLIB_VER).gcc $(LDFLAGS) + $(CC) $(CFLAGS) -Wl,--base-file,testgmodule.base -o testgmodule.exe testgmodule.o -L. -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) $(LDFLAGS) $(DLLTOOL) --base-file testgmodule.base --output-exp testgmodule.exp testgmodule.o - $(CC) $(CFLAGS) -Wl,--base-file,testgmodule.base,testgmodule.exp -o testgmodule.exe testgmodule.o -L. -lglib-$(GLIB_VER).gcc -lgmodule-$(GLIB_VER).gcc $(LDFLAGS) + $(CC) $(CFLAGS) -Wl,--base-file,testgmodule.base,testgmodule.exp -o testgmodule.exe testgmodule.o -L. -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) $(LDFLAGS) $(DLLTOOL) --base-file testgmodule.base --output-exp testgmodule.exp testgmodule.o - $(CC) $(CFLAGS) -Wl,testgmodule.exp -o testgmodule.exe testgmodule.o -L. -lglib-$(GLIB_VER).gcc -lgmodule-$(GLIB_VER).gcc $(LDFLAGS) + $(CC) $(CFLAGS) -Wl,testgmodule.exp -o testgmodule.exe testgmodule.o -L. -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) $(LDFLAGS) testgmodule.o : gmodule/testgmodule.c $(CC) $(CFLAGS) -Igmodule -c gmodule/testgmodule.c libgplugin_a.dll : libgplugin_a.o - ./build-dll libgplugin_a - - libgplugin_a.o -L. -lglib-$(GLIB_VER).gcc -lgmodule-$(GLIB_VER).gcc + ./build-dll libgplugin_a - - libgplugin_a.o -L. -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) libgplugin_a.o : gmodule/libgplugin_a.c $(CC) $(CFLAGS) -Igmodule -c gmodule/libgplugin_a.c libgplugin_b.dll : libgplugin_b.o - ./build-dll libgplugin_b - - libgplugin_b.o -L. -lglib-$(GLIB_VER).gcc -lgmodule-$(GLIB_VER).gcc + ./build-dll libgplugin_b - - libgplugin_b.o -L. -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) libgplugin_b.o : gmodule/libgplugin_b.c $(CC) $(CFLAGS) -Igmodule -c gmodule/libgplugin_b.c diff --git a/tests/makefile.cygwin.in b/tests/makefile.cygwin.in index b2aa967..9f02e15 100644 --- a/tests/makefile.cygwin.in +++ b/tests/makefile.cygwin.in @@ -7,7 +7,7 @@ OPTIMIZE = -g -O # Nothing much configurable below -CC = gcc -mno-cygwin -mpentium +CC = gcc -mno-cygwin -mpentium -fnative-struct GLIB_VER = @GLIB_MAJOR_VERSION@.@GLIB_MINOR_VERSION@ @@ -37,7 +37,7 @@ all : $(TESTS) .c.exe : $(CC) $(CFLAGS) -c $< - $(CC) $(CFLAGS) -o $@ $< -L.. -lglib-$(GLIB_VER).gcc -lgthread-$(GLIB_VER).gcc + $(CC) $(CFLAGS) -o $@ $< -L.. -lglib-$(GLIB_VER) -lgthread-$(GLIB_VER) check: all @for P in $(TESTS) ; do echo $$P; ./$$P; done -- 2.7.4