Bug#1008951: openldap FTBFS on musl-linux-any: conflicting declaration of calloc
Helmut Grohne
helmut at subdivi.de
Mon Apr 4 20:54:13 BST 2022
Source: openldap,musl
Tags: upstream
User: helmutg at debian.org
Usertags: rebootstrap
Hi,
openldap fails to build from source on musl-linux-any. The issue is not
Debian-specific and has been reported for gentoo already
(https://bugs.gentoo.org/546556). The visible issue is this:
| In file included from ../../../../libraries/librewrite/context.c:22:
| ../../../../libraries/librewrite/rewrite-int.h:44:25: error: conflicting types for ‘ber_memcalloc’; have ‘void *(size_t, size_t)’ {aka ‘void *(unsigned int, unsigned int)’}
| 44 | #define calloc(x,y) ber_memcalloc(x,y)
| | ^~~~~~~~~~~~~
| In file included from ../../../../libraries/librewrite/rewrite-int.h:34:
| ../../../../include/lber.h:608:1: note: previous declaration of ‘ber_memcalloc’ with type ‘void *(ber_len_t, ber_len_t)’ {aka ‘void *(long unsigned int, long unsigned int)’}
| 608 | ber_memcalloc LDAP_P((
| | ^~~~~~~~~~~~~
The gentoo bug explains this quite well. LBER_LEN_T is statically
defined as "long" in configure.ac. Then include/lber_types.h uses that:
| typedef unsigned LBER_LEN_T ber_len_t;
And then, it declares ber_memcalloc using ber_len_t in include/lber.h.
Finally, it #defines calloc (as be seen above) to point to
ber_memcalloc. That #define lives in libraries/librewrite/rewrite-int.h,
which happens to be #included before some musl header that happens to
pull the definition of calloc. Thus musl's declaration is renamed to
ber_memcalloc and since it uses size_t, which happens to be defined as
unsigned int rather than unsigned long, we get a conflicting
declaration.
Looking deeper things get a little surprising. rewrite-int.h is careful
to #include <ac/stdlib.h> early. Presumably, it wants to avoid such
conflicting declarations. Indeed, that's not the place the conflicting
ber_memcalloc declaration originates. After the #define calloc, there is
an #include <ldap_pvt_thread.h>, which happens to indirectly #include
<pthread.h>, which happens to #include <sched.h>, which happens to
declare calloc, which was defined as ber_memcalloc earlier.
This is sounds doubly wrong. Why would openldap re#define calloc and
then #include system headers? That's risky and it makes the build fail.
Why would musl declare calloc in a header different from stdlib.h? I
understand neither and fixing either fixes the build.
The gentoo bug has a few more details and proposed two distinct
workarounds:
a. Drop the _GNU_SOURCE define. Doing so makes musl's sched.h not emit
a calloc declaration. I don't know what other consequences this
would have.
b. Change LBER_LEN_T to size_t. I suppose doing so would break ABI on
64bit architectures.
Any clue how we can move forward here?
Helmut
More information about the Pkg-openldap-devel
mailing list