GNOME Bugzilla – Bug 684123
glib build only tries -D_GNU_SOURCE if glibc is detected
Last modified: 2013-07-27 23:00:04 UTC
glib's build system wants to detect various GNU/Linux extension functionality from the standard library which is only available when the _GNU_SOURCE feature test macro is defined. However it only adds -D_GNU_SOURCE to the CFLAGS if glibc is detected. This makes it impossible for other platforms (other unices, or other libcs on Linux) to offer compatible functionality under the _GNU_SOURCE feature test macro and have it be properly used by glib; in reality, what happens is that glib's configure script detects said functionality in the libraries, but by omitting -D_GNU_SOURCE, does not get the right types and declarations from the system header files, and therefore runs into various errors during build. This is causing problems building glib on musl libc based systems, unless -D_GNU_SOURCE is added to CFLAGS manually by the user. I see several possible fixes: 1. Always use -D_GNU_SOURCE and assume it will be a no-op on systems that don't have GNU-compatible extensions. I'm not sure if this is safe/reliable. 2. Add a configure test to see if -D_GNU_SOURCE works to get the extended functionality glib wants, rather than assuming it works on glibc and nowhere else. OR 3. Fix the configure tests for extension functions so that they don't just check for the existence of the symbol in the library, but also check that the function is prototyped and that the necessary types, macros, etc. needed for using it are defined. Actually, item 3 is not mutually exclusive with 1 or 2, and should really be done however this situation is resolved. For example, using splice() just because a symbol named splice is found, without checking whether the macros and loff_t type it needs for its arguments are also defined, is fragile; if a completely different system happened to have an extension function named splice, but with completely different signature and semantics, in its libc, then building glib would break on that system.
Do other C libraries besides musl implement _GNU_SOURCE? Anyways if that's the path that musl has chosen, the obvious thing to do here is detect it in configure and do the same thing we do for glibc.
uClibc implements _GNU_SOURCE, but lies that it's glibc; if not for that, glib would be broken on uClibc too. Actually this kind of breakage is exactly the reason uClibc lies that it's glibc... As for detecting musl, I would strongly recommend a behavior-based test for _GNU_SOURCE rather than hard-coding assumptions about musl. musl intentionally does not provide any documented way to detect it, and although there are some ways one could go about doing detection, it's fragile.
_GNU_SOURCE should not have any tests at all - it is a declaration about the requirements of your source. We should always define it.
Reportedly some BSDs do not treat _GNU_SOURCE as a purely additive feature test macro, and instead hide or disable some functionality that's visible by default if _GNU_SOURCE is defined. I have not confirmed this behavior myself, but it's the reason I suggested that it might be necessary to test whether it's safe/necessary to add it. On the other hand, if glib is never trying to use BSD-specific functionality anyway that might be hidden by _GNU_SOURCE on such systems, it's probably fine to just always define _GNU_SOURCE. In any case, I think all tests that just try linking against symbols should be fixed to also check for the correct prototype and definition of any types needed. This would at least prevent breakage from configure detecting the presence of a symbol but not using the right feature test macros to expose it in the headers.
(In reply to comment #4) > Reportedly some BSDs do not treat _GNU_SOURCE as a purely additive feature test > macro, and instead hide or disable some functionality that's visible by default > if _GNU_SOURCE is defined. I have not confirmed this behavior myself, but it's > the reason I suggested that it might be necessary to test whether it's > safe/necessary to add it. If that's true, I'd guess that it would be due to conflicts between GNU and BSD extensions to POSIX; stuff like getline(). But GLib is a replacement for all of that crap - we don't need to use any of it internally. > On the other hand, if glib is never trying to use BSD-specific functionality > anyway that might be hidden by _GNU_SOURCE on such systems, it's probably fine > to just always define _GNU_SOURCE. So, this does indeed seem to be the best fix. Ideally we'd have a BSD-based buildbot so we have at least a rough idea when we break it.
Ping.
Created attachment 250192 [details] [review] configure: Use AC_USE_SYSTEM_EXTENSIONS ...instead of detecting glibc and using _GNU_SOURCE manually. This should fix the build when using glibc-emulating libraries; we can defer portability work to autoconf.
Comment on attachment 250192 [details] [review] configure: Use AC_USE_SYSTEM_EXTENSIONS ok
https://git.gnome.org/browse/glib/commit/?id=d2bb019533bbcbd1cee3891822ac7ba6ff55ad3d
See https://bugzilla.gnome.org/show_bug.cgi?id=704999 for some fallout.