After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 682896 - glib doesn't build on mingw32
glib doesn't build on mingw32
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: win32
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtk-win32 maintainers
gtk-win32 maintainers
Depends on:
Blocks:
 
 
Reported: 2012-08-28 19:20 UTC by Behdad Esfahbod
Modified: 2013-02-26 04:27 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
win32-Fallback-implementation-for-Interlocked-And-Or.patch (2.00 KB, patch)
2012-08-29 19:16 UTC, Hans Breuer
none Details | Review
win32-Fallback-implementation-for-Interlocked-And-Or.patch (2.00 KB, patch)
2012-08-29 20:49 UTC, Hans Breuer
none Details | Review

Description Behdad Esfahbod 2012-08-28 19:20:19 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.
Comment 1 Behdad Esfahbod 2012-08-28 19:42:21 UTC
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.
Comment 2 Behdad Esfahbod 2012-08-28 19:46:22 UTC
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.
Comment 3 Behdad Esfahbod 2012-08-28 19:50:08 UTC
Meh.  The pthread.h bug still happens even trying -march=i586 for me.  Not sure what exactly is going on.
Comment 4 Behdad Esfahbod 2012-08-28 22:14:11 UTC
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.
Comment 5 Hans Breuer 2012-08-29 19:16:32 UTC
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.
Comment 6 Behdad Esfahbod 2012-08-29 20:05:01 UTC
> +#define InterlockedXor(a,b) (g_error("InterlockedXor"), 0)

?
Comment 7 Hans Breuer 2012-08-29 20:49:52 UTC
Created attachment 222844 [details] [review]
win32-Fallback-implementation-for-Interlocked-And-Or.patch

Sorry for the noise, now the full version.
Comment 8 Hans Breuer 2012-08-29 20:54:08 UTC
Sorry again. Using the right definition for InterlockedXor(a,b) is left as an exercise to the reader. I'm not doing another attachement;)
Comment 9 Behdad Esfahbod 2012-08-29 21:27:33 UTC
Lol.  Can you push this?  I can try to sort out the other bits...
Comment 10 Behdad Esfahbod 2013-02-26 04:27:26 UTC
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"
-
 #