core: fix build on musl libc (Alpine) - stray #undef _GNU_SOURCE in lib/url.c - #4119
core: fix build on musl libc (Alpine) - stray #undef _GNU_SOURCE in lib/url.c#4119Lt-Flash wants to merge 2 commits into
Conversation
url.c defined _GNU_SOURCE only around <stdio.h>/<string.h> and then
undefined it again before including ut.h. On musl libc the feature-test
macros are re-evaluated by every system header, so once _GNU_SOURCE is
removed the later <time.h> (pulled in through ut.h and dprint.h) no
longer exposes clock_gettime(), CLOCK_REALTIME or ctime_r(). The core
then fails to compile on Alpine/musl with gcc 15:
lib/../mem/../dprint.h:204: implicit declaration of 'ctime_r'
lib/../ut.h:1401: implicit declaration of 'clock_gettime'
lib/../ut.h:1401: 'CLOCK_REALTIME' undeclared
glibc is unaffected: it latches internal __USE_* macros at the first
header inclusion, which the later #undef does not clear.
Keep _GNU_SOURCE defined for the whole translation unit, matching how
other core files (io_wait.h, transformations.c) enable it.
Both mathops sources define _XOPEN_SOURCE/_GNU_SOURCE for <math.h>, then
undefine them again before including the OpenSIPS headers - the same
pattern lib/url.c had.
musl re-evaluates the feature-test macros in every system header rather
than only on the first one, and its features.h turns on the permissive
default set only when no source macro is defined at all. Once the block
above has defined them, undefining them leaves the translation unit with
none of them set, so <time.h> stops declaring ctime_r() and dprint.h no
longer compiles:
Compiling mathops.c
../../parser/../dprint.h:204:9: error: implicit declaration of function
'ctime_r'; did you mean 'ctime'?
Since gcc 14 an implicit declaration is an error, so this is a hard build
failure of the module on Alpine. Keep the macros defined for the rest of
each file, as lib/url.c now does.
|
Pushed a second commit: the exact same defect exists in While building the full module set in an Alpine 3.24 container (musl 1.2.x, gcc 15.2.0) with the Both #ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#define _ADDED_XOPEN
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <math.h> /* this is what the macros are for */
#ifdef _ADDED_XOPEN
#undef _ADDED_XOPEN
#undef _XOPEN_SOURCE
#undef _GNU_SOURCE /* <-- same problem as lib/url.c */
#endif
#include "../../pvar.h" /* ... eventually dprint.h, which needs ctime_r */The mechanism is the one described in the PR body: musl re-evaluates the feature-test macros in every system header, and its The fix is the same as for Verified: with this commit, Separately, and not part of this PR since it is a different defect class, building the full module set on musl also turns up a plain missing-include problem: Files affected in my build: |
What
Fixes the OpenSIPS core failing to compile on musl libc (Alpine Linux) with a modern GCC. A single stray
#undef _GNU_SOURCEinlib/url.chides the POSIX time prototypes on musl, so the very first core object (lib/url.o) never builds.Symptom
Building
masterin a stock Alpine 3.24 container (musl 1.2.x, gcc 15.2.0) dies immediately:With gcc 14+,
-Wimplicit-function-declarationis an error by default, so this is a hard build failure, not a warning. The same tree builds fine on glibc.Root cause
lib/url.copens with:The difference between the two libcs is when the feature-test macros are evaluated:
musl re-checks the feature-test macros in every system header. Its
features.honly turns on the permissive default set (_BSD_SOURCE+_XOPEN_SOURCE 700, which is what exposesclock_gettime/ctime_r) when no source macro is defined:When
<stdio.h>first includesfeatures.h,_GNU_SOURCEis defined, so that default block is skipped andfeatures.hlatches (include guard). The following#undef _GNU_SOURCEthen leaves the translation unit with no feature-test macro at all. Whenut.hlater includes<time.h>,features.his guard-skipped and never re-derives the defaults, sotime.h's guarded prototypes (clock_gettime,ctime_r,CLOCK_REALTIME) are all absent -> implicit declarations -> build error.glibc latches internal
__USE_POSIX*/__USE_GNUmacros at the first header inclusion. The later#undef _GNU_SOURCEdoes not clear those, so the prototypes stay visible and the build succeeds. That is why this has gone unnoticed.A one-line reproducer confirms the mechanism on musl:
The fix
Drop the
#undefand keep_GNU_SOURCEdefined for the whole translation unit (with a comment explaining why). This matches how other core sources already enable it unconditionally (io_wait.h,transformations.c), and is a no-op on glibc.Testing
make opensipsfails atlib/url.obefore this change; builds to completion after it. Full core binary produced, modules build and load, runtime verified.#undefwas already a no-op there).lib/url.cis the only core file that uses this#define/#undef _GNU_SOURCEbracket, so this one file is the whole fix for the core.Opening as a draft for maintainer review of the approach (per-file fix here vs. defining
_GNU_SOURCEtree-wide in the build).