Hi, I'm using glib within an own application (a jabber client lib) because of data types and portability support. My first target is windows, so I wanted to manage the build process on this platform (for example to be able to produce debug symbols for glib). Below I give a recipe how to build glib-2.0.4 on cygwin using standalone mingw and 'autoconfiscation' because I didn't find one but read in the archives that such descriptions are also needed by other people. BTW, thanks for this good piece of software.
First thing I tried, was to use msvc makefiles. After some fiddeling the make process ran through and I had a usable dll. Unfortunately there was a nasty bug: a file handle opened with 'open' wasn't accepted by 'fstat' (both in the microsoft runtime). Although I haven't further investigated I think the reason is that the dll linked in both msvcrt.lib and msvcrtd.lib. 'open' was resolved from msvcrt.lib and 'fstat' was resolved from msvcrtd.lib. I believe this is because the makefile.msvc in the build/win32/dirent subfolder doesn't honor debug settings in modules.def/make.msvc and links always against msvcrt.lib. So take care, if you want to build with msvc. Although this could be easily fixed there is no generic way to build with msvc (when upgrading the glib source tree, you'll always have to perform manual intervention). So I decided to try a mingw build with autotools. That resulted in me fighting libtool for almost a week which is not only libtool's fault but also mine because till now I had no idea how to use the autotools as a developer ;-). 1) System setup I have reinstalled a very late cygwin into the root directory of an own partition (i.e. I didn't use the usual 'c:/cygwin' but just 'f:/' as installation folder). This makes things easier when using cygwin tools like make, bash etc. together with native compilers like mingw or cl because all paths on this partition are understood by both cygwin and non-cygwin tools. Note that the cygwin guys explicitley discourage this way of installation. Till now I had no problems with this setup and I hope that most of the issues will be circumvented by not using 'c:/'. You can probably manage the build process with cygwin in the default 'c:/cygwin' but you will have to perfom some extra steps. If you choose to try, here are two hints: * When you provide additional include (-I) and library (-L) paths to the configure script, specify every path twice: once in cygwin syntax and once again in windows syntax. Example: CPPFLAGS='-I/usr/local/include -Ic:/cygwin/usr/local/include' \ ./configure (Note that this is *one* commandline.) * You will almost certainly have to patch the libtool script, esp. where it uses 'pwd' to determine the path of some file that is further given to one of the mingw tools as a command line argument. Example: There are some places in libtool that look like 'xabs=`pwd`"/$xlib"'. Some lines later on, 'xabs' is used as an argument to 'ar' like in '$run eval "(cd \$xdir && $AR x \$xabs)"'. Immediately before this call to 'ar' you will have to do something like 'xabs=`cygpath -w \$xabs`'. 2) Versions I use following versions of the tools: * mingw 1.1 installed to f:/mingw * the autoconf-devel package of cywin (2.53a) * the automake-devel package of cygwin (1.6.2) * the libtool-devel-20020705 package of cygwin 3) Dependencies Till now I didn't manage to build libintl by myself. So I use the binary package as provided by the gimp-win32 guys. Unfortunately this dll also has been linked against both msvcrt.lib and msvcrtd.lib. I will try to get it built with mingw within the next days. I use libiconv-1.8 built with msvc. Although this one seems to be clean I will try to rebuild it with mingw. Unfortunately the autoconf step of glib produces an unfortune 'sys_lib_search_path_spec' in the libtool script (I don't think this is glib's fault, I think autoconf is broken here). The problem is that cygwin library directories are included esp. '/lib'. Unfortunately this one contains export libraries of both libintl and libiconv. Normally this should be no problem because the paths specified on the commandline are searched first. Unfortunately it seems that libtool searches all given paths for .la files before it looks for .a files in all paths. Cygwin provides such .la files for its versions of both libintl and libiconv but neither the binary package of libintl nor the msvc built libiconv contain such files so that libtool 'thinks' it should use the cygwin ones. This would make the resulting glib GPLed implicitely and I wouldn't be allowed to use it. So I simply produced my own .la files. I'm sure you could make libtool generate them for you, but I don't know how. Therefore I wrote them with an editor. Both of them are attached. If you use them you need to need to adjust the 'libdir' entry. When I manage to build libintl and libiconv autoconfiscated with mingw this step won't be necessary anymore. An alternative to the .la files could be to correct the value of 'sys_lib_search_path_spec' in the libtool script but I didn't try that one; it might be easier than creating the .la files. 4) Get new autotools These are the needed commands (execute them in cygwin bash): $ cd glib $ tar-jxvf glib-2.0.4.tar.bz2 $ cd glib-2.0.4 $ mv configure configure.old $ aclocal $ autoconf -f $ automake -a -c -f $ libtoolize -c -f 5) Configure the package These are the needed commands: $ mkdir ../build_debug $ cd ../build_debug $ export PATH=/mingw/bin:$PATH $ CC='gcc -mpentium -fnative-struct' \ CPPFLAGS='-I/home/ama2fr/projects/webti_events/libiconv-1.8/include \ -I/home/ama2fr/projects/webti_events/libintl/include' \ LDFLAGS='-L/home/ama2fr/projects/webti_events/libiconv-1.8/lib \ -L/home/ama2fr/projects/webti_events/libintl/lib' \ ../glib-2.0.4/configure --with-libiconv --disable-static \ --prefix=/home/ama2fr/projects/webti_events/local \ --host=i386-pc-mingw32 --enable-maintainer-mode Note that you have to put the last command completely into one line, i.e. you can't just copy and paste it in one shot, but rather line by line. Anyway you will need to customize the paths. The configure script warns about four things: * configure: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used. * configure: WARNING: I can't find the MACRO to enable thread safety on your platform (normally it's _REENTRANT). I'll not use any flag on compilation now, but then your programs might not work. Please provide information on how it is done on your system. * configure: WARNING: the 'g_get_(user_name|real_name|home_dir|tmp_dir)' functions will not be MT-safe during their first call because there is no working 'getpwuid_r' on your system. * configure: WARNING: the 'g_date_set_time' function will not be MT-safe because there is no 'localtime_r' on your system. The first warning should be rather unimportant. For the other three I would like to hear (by the maintainers or other people) what they mean for the thread-safeness of my application (esp. because the functions in msvcrt.lib should be thread-safe). Anyone? 6) Patches At first patch the libtool script as follows: $ patch <glib-2.0.4-libtool.patch The patch is attached. Please do yourself a favour and don't apply this patch blindly against other versions of glib (for example the 2.0.6, which I didn't try out yet). I think libtool is broken here but the patch is certainly not general enough to propose it to the libtool maintainer because I know far too few about libtool. I only know that this patch works for glib-2.0.4 (hopefully, that is :-). There is another small thing left to be done. In the following Makefile's at the given line there is a call to msvc's lib.exe to generate an export library. This call is just 'lib' which doesn't work in my bash. This may be because I have it badly configured or because my current version is buggy or because of something completely different. By just replacing the string 'lib' (only the first occurency please!) with the string 'LIB.EXE' everything worked for me. * gthread/Makefile:484 * gobject/Makefile:867 * gmodule/Makefile:522 * glib/Makefile:863 I didn't bother to write a script for that because it could possibly be integrated into the correspondig Makefile.am's by the glib maintainers, if it turns out that it is not just a local problem with my setup. It shouldn't break anything that worked till now anyway. 7) Workaround for Makefile shortcomings Because I don't build within the source tree but in a separate build tree (which makes it easy to concurrently maintain a debug and a release build), I found some shortcomings in the Makefile's of glib, which use special files that are located in the source tree but can't be relocated to the build tree by the usual make mechanisms. Therefore they are simply not found during the build. You can perform the following steps to cope with that (if your build tree and your source tree are the same you can forget the following): $ cp ../glib-2.0.4/glib/glib.def glib $ cp ../glib-2.0.4/gobject/gobject.def gobject $ cp ../glib-2.0.4/gmodule/gmodule.def gmodule $ cp ../glib-2.0.4/gthread/gthread.def gthread If you want to 'make install' there are still some other files to be copied: $ cp ../glib-2.0.4/glib/libcharset/ref-add.sed glib/libcharset $ cp ../glib-2.0.4/glib/libcharset/ref-del.sed glib/libcharset 8) Make it Finally you should now be able to make and install glib: $ make $ make install There are some minor issues left which I couldn't solve till now. One is that mingw exports global variables regardless of the def-file. Does anyone know of a way to get around this, i.e. no export for global variables? HTH, andreas ames
# localcharset.lo - a libtool object file # Generated by ltmain.sh - GNU libtool 1.4e (1.1125 2002/06/26 07:15:36) # # Please DO NOT delete this file! # It is necessary for linking the library. dlname='libintl-1.dll' library_names='libintl.dll.a' libdir=/home/ama2fr/projects/webti_events/libintl/lib
# localcharset.lo - a libtool object file # Generated by ltmain.sh - GNU libtool 1.4e (1.1125 2002/06/26 07:15:36) # # Please DO NOT delete this file! # It is necessary for linking the library. dlname='iconv.dll' library_names='iconv.lib' libdir=/home/ama2fr/projects/webti_events/libiconv-1.8/lib
--- libtool.old 2002-08-14 18:33:42.000000000 +0200 +++ libtool 2002-08-14 18:22:16.000000000 +0200 @@ -193,30 +193,17 @@ old_archive_from_expsyms_cmds="\$DLLTOOL --as=\$AS --dllname \$soname --def \$output_objdir/\$soname-def --output-lib \$output_objdir/\$newlib" # Commands used to build and install a shared archive. -archive_cmds="" -archive_expsym_cmds="if test \\\"x\\\`sed 1q \$export_symbols\\\`\\\" = xEXPORTS; then - cp \$export_symbols \$output_objdir/\$soname-def; - else - echo EXPORTS > \$output_objdir/\$soname-def; - _lt_hint=1; - cat \$export_symbols | while read symbol; do - set dummy \\\$symbol; - case \\\$# in - 2) echo \\\" \\\$2 @ \\\$_lt_hint ; \\\" >> \$output_objdir/\$soname-def;; - 4) echo \\\" \\\$2 \\\$3 \\\$4 ; \\\" >> \$output_objdir/\$soname-def; _lt_hint=\\\`expr \\\$_lt_hint - 1\\\`;; - *) echo \\\" \\\$2 @ \\\$_lt_hint \\\$3 ; \\\" >> \$output_objdir/\$soname-def;; - esac; - _lt_hint=\\\`expr 1 + \\\$_lt_hint\\\`; - done; - fi~ - - \$CC -Wl,--base-file,\$output_objdir/\$soname-base -mdll -Wl,-e,_DllMainCRTStartup@12 -o \$output_objdir/\$soname \$libobjs \$deplibs \$compiler_flags~ - \$DLLTOOL --as=\$AS --dllname \$soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 --def \$output_objdir/\$soname-def --base-file \$output_objdir/\$soname-base --output-exp \$output_objdir/\$soname-exp~ - \$CC -Wl,--base-file,\$output_objdir/\$soname-base \$output_objdir/\$soname-exp -mdll -Wl,-e,_DllMainCRTStartup@12 -o \$output_objdir/\$soname \$libobjs \$deplibs \$compiler_flags~ - \$DLLTOOL --as=\$AS --dllname \$soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 --def \$output_objdir/\$soname-def --base-file \$output_objdir/\$soname-base --output-exp \$output_objdir/\$soname-exp --output-lib \$output_objdir/\$libname.dll.a~ - \$CC \$output_objdir/\$soname-exp -mdll -Wl,-e,_DllMainCRTStartup@12 -o \$output_objdir/\$soname \$libobjs \$deplibs \$compiler_flags" -postinstall_cmds="" -postuninstall_cmds="" +archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags -o \$output_objdir/\$soname \${wl}--image-base=0x10000000 \${wl}--out-implib,\$lib" +archive_expsym_cmds="\$CC -shared \$export_symbols \$libobjs \$deplibs \$compiler_flags -o \$output_objdir/\$soname \${wl}--out-implib,\$lib -Wl,--base-file,\$output_objdir/\$soname-base~ + \$DLLTOOL --as=\$AS --dllname \$soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 --def \$export_symbols --base-file \$output_objdir/\$soname-base --output-exp \$output_objdir/\$soname-exp --output-lib \$output_objdir/\$libname.dll.a" +postinstall_cmds="base_file=\\\`basename \\\${file}\\\`~ + dlpath=\\\`bash 2>&1 -c '. \$dir/'\\\${base_file}'i;echo \\\$dlname'\\\`~ + dldir=\$destdir/\\\`dirname \\\$dlpath\\\`~ + test -d \\\$dldir || mkdir -p \\\$dldir~ + \$install_prog \$dir/\$dlname \\\$dldir/\$dlname" +postuninstall_cmds="dldll=\\\`bash 2>&1 -c '. \$file; echo \\\$dlname'\\\`~ + dlpath=\$dir/\\\$dldll~ + \$rm \\\$dlpath" # Commands to strip libraries. old_striplib="strip --strip-debug" @@ -325,7 +312,7 @@ # The commands to list exported symbols. export_symbols_cmds=" \$DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 --output-def \$output_objdir/\$soname-def \$libobjs \$convenience~ - sed -e \\\"1,/EXPORTS/d\\\" -e \\\"s/ @ [0-9]*//\\\" -e \\\"s/ *;.*\$//\\\" < \$output_objdir/\$soname-def > \$export_symbols" + cp \$output_objdir/\$soname-def \$export_symbols" # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds="test -f \$output_objdir/impgen.c || \\\\ @@ -3746,7 +3733,7 @@ if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" + export_symbols="$output_objdir/$libname.def" $run $rm $export_symbols eval cmds=\"$export_symbols_cmds\" save_ifs="$IFS"; IFS='~'