GNOME Bugzilla – Bug 682896
glib doesn't build on mingw32
Last modified: 2013-02-26 04:27:26 UTC
mingw32 is different from visual studio in that: - It has win32-style mutexes (CriticalSection, etc) - It doesn't have VisualStudio-style atomic intrinsics OR intel-style atomic intrinsics. And of course, it doesn't have pthreads. Confusing these things can result in build breakage. Right now, gatomic.c has this line: /* We are not permitted to call into any GLib functions from here, so we * can not use GMutex. * * Fortunately, we already take care of the Windows case above, and all * non-Windows platforms on which glib runs have pthreads. Use those. */ #include <pthread.h> The comment is wrong. All we took care of so far was Visual-Studio, not all of Windows. As such, with mingw32 we end up including pthread.h, which wouldn't work. Really, need to make it possible to use GMutex from here.
This is inherently broken in that now we can't use glib compiled using VisualStudio on mingw32, because the compiled glib will assume that it can use lock-free atomic ops, but they won't be available. It's confusing a compiler feature with a platform feature... It's messy.
Looks like this may be a non-issue: (03:44:23 PM) dieterv: behdad: depending on what exact mingw "distro" you are using, you'll need to add -march=i486 to your CFLAGS (or 586 or 686) Maybe we can warn or something.
Meh. The pthread.h bug still happens even trying -march=i586 for me. Not sure what exactly is going on.
Update: - mingw32 doesn't have intrinsics, but there are windows functions that can be used. I'm using this in harfbuzz now: #elif !defined(HB_NO_MT) && defined(_MSC_VER) || defined(__MINGW32__) #define WIN32_LEAN_AND_MEAN #include <windows.h> /* mingw32 does not have MemoryBarrier. * MemoryBarrier may be defined as a macro or a function. * Just make a failsafe version for ourselves. */ #ifdef MemoryBarrier #define HBMemoryBarrier MemoryBarrier #else static inline void HBMemoryBarrier (void) { long dummy = 0; InterlockedExchange (&dummy, 1); } #endif typedef long hb_atomic_int_t; #define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) #define hb_atomic_ptr_get(P) (HBMemoryBarrier (), (void *) *(P)) #define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) The pthread problem seems to be caused by a wrong assumption in configure: dnl We can currently support the atomic ops natively when building GLib dnl with recent versions of GCC or MSVC. MSVC doesn't run ./configure, dnl so we skip that case here and define G_ATOMIC_LOCK_FREE exactly when dnl we are using GCC. The following hack _fixes_ it: diff --git a/configure.ac b/configure.ac index 9eb02b6..8e2495a 100644 --- a/configure.ac +++ b/configure.ac @@ -2354,6 +2354,11 @@ AC_CACHE_CHECK([for lock-free atomic intrinsics], glib_cv [glib_cv_g_atomic_lock_free=yes], [glib_cv_g_atomic_lock_free=no])]) +case $host in + *-*-mingw*) + glib_cv_g_atomic_lock_free=yes + ;; +esac if test "$glib_cv_g_atomic_lock_free" = "no"; then SAVE_CFLAGS="${CFLAGS}" CFLAGS="-march=i486" But then gatomic barfs again, because it tries to use intrinsics instead of functions. This helps there: diff --git a/glib/gatomic.c b/glib/gatomic.c index 2df2bcc..dfd83a1 100644 --- a/glib/gatomic.c +++ b/glib/gatomic.c @@ -467,7 +467,7 @@ gsize #elif defined (G_PLATFORM_WIN32) #include <windows.h> -#if !defined(_M_AMD64) && !defined (_M_IA64) && !defined(_M_X64) +#if !defined(_M_AMD64) && !defined (_M_IA64) && !defined(_M_X64) && !defined(__MINGW32__) #define InterlockedAnd _InterlockedAnd #define InterlockedOr _InterlockedOr #define InterlockedXor _InterlockedXor After that we hit more issues: /home/behdad/gnome/glib/winbuild/glib/../../glib/gatomic.c:548: undefined reference to `_MemoryBarrier' .libs/gatomic.o: In function `g_atomic_int_get': /home/behdad/gnome/glib/winbuild/glib/../../glib/gatomic.c:482: undefined reference to `_MemoryBarrier' .libs/gatomic.o: In function `g_atomic_pointer_xor': /home/behdad/gnome/glib/winbuild/glib/../../glib/gatomic.c:610: undefined reference to `_InterlockedXor' .libs/gatomic.o: In function `g_atomic_int_xor': /home/behdad/gnome/glib/winbuild/glib/../../glib/gatomic.c:539: undefined reference to `_InterlockedXor' .libs/gatomic.o: In function `g_atomic_pointer_or': /home/behdad/gnome/glib/winbuild/glib/../../glib/gatomic.c:599: undefined reference to `_InterlockedOr' .libs/gatomic.o: In function `g_atomic_int_or': /home/behdad/gnome/glib/winbuild/glib/../../glib/gatomic.c:532: undefined reference to `_InterlockedOr' .libs/gatomic.o: In function `g_atomic_pointer_and': /home/behdad/gnome/glib/winbuild/glib/../../glib/gatomic.c:588: undefined reference to `_InterlockedAnd' .libs/gatomic.o: In function `g_atomic_int_and': /home/behdad/gnome/glib/winbuild/glib/../../glib/gatomic.c:525: undefined reference to `_InterlockedAnd' .libs/gatomic.o: In function `g_atomic_pointer_set': /home/behdad/gnome/glib/winbuild/glib/../../glib/gatomic.c:559: undefined reference to `_MemoryBarrier' .libs/gatomic.o: In function `g_atomic_int_set': /home/behdad/gnome/glib/winbuild/glib/../../glib/gatomic.c:491: undefined reference to `_MemoryBarrier' Those are simply not defined by my 3yr old mingw32. MemoryBarrier is easy to implement. Interlocked bitwise ops harder but not impossible. Anyway, maybe newer mingw32 has fixed this. I'll try. But there's a few bits that need fixing in glib regardless.
Created attachment 222831 [details] [review] win32-Fallback-implementation-for-Interlocked-And-Or.patch For the missing Interlocked functions you should either update the win32 SDK used or might want to extend the attached patch for the mingw case.
> +#define InterlockedXor(a,b) (g_error("InterlockedXor"), 0) ?
Created attachment 222844 [details] [review] win32-Fallback-implementation-for-Interlocked-And-Or.patch Sorry for the noise, now the full version.
Sorry again. Using the right definition for InterlockedXor(a,b) is left as an exercise to the reader. I'm not doing another attachement;)
Lol. Can you push this? I can try to sort out the other bits...
I pushed out the following changes that fix mingw32 build for me, except for the stupid -Werror stuff in configure.ac [1]: commit 547221b486473ed9b7f85634ce162f937e5912b1 Author: Behdad Esfahbod <behdad@behdad.org> Date: Mon Feb 25 22:48:03 2013 -0500 [win32] Fix atomic ops on mingw* Bug 682896 - glib doesn't build on mingw32 commit e1ccae841658854a5db0d907edb2b1f2c0a68ef5 Author: Behdad Esfahbod <behdad@behdad.org> Date: Mon Feb 25 22:01:11 2013 -0500 [win32] Add fallback implementations for gatomic.c on mingw32 Bug 682896 - glib doesn't build on mingw32 [1] diff --git a/configure.ac b/configure.ac index 8745702..e133ce7 100644 --- a/configure.ac +++ b/configure.ac @@ -3614,15 +3614,6 @@ case "$host" in esac AC_SUBST(GLIB_HIDDEN_VISIBILITY_CFLAGS) -dnl Compiler flags; macro originates from systemd -dnl See https://bugzilla.gnome.org/show_bug.cgi?id=608953 -CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ - -Wall -Wstrict-prototypes -Werror=declaration-after-statement \ - -Werror=missing-prototypes -Werror=implicit-function-declaration \ - -Werror=pointer-arith -Werror=init-self -Werror=format-security \ - -Werror=format=2 -Werror=missing-include-dirs]) -CFLAGS="$with_cflags $CFLAGS" - #