TLDR: zig is using "too new" glibc headers, which sometimes references undefined symbols. This fails compilation for at least sqlite and libuv when older glibc is selected, because it redefines fcntl to fcntl64, which is present only in newer glibcs.
main.c
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main() {
printf("address to fcntl: %p\n", fcntl);
}
This fails when target is glibc 2.27 or older:
$ zig cc --target=x86_64-linux-gnu.2.27 main.c
ld.lld: error: undefined symbol: fcntl64
>>> referenced by main.c
>>> /home/motiejus/.cache/zig/o/921a4d8978936f8450e53a6103470e2c/main.o:(main)
>>> did you mean: fcntl64@GLIBC_2.28
>>> defined in: /home/motiejus/.cache/zig/o/6dd7f9446c261fd02c47b1aad02ab90b/libc.so.6
And works with glibc 2.28+:
$ zig cc --target=x86_64-linux-gnu.2.28 main.c
$ ./a.out
address to fcntl: 0x7f46a328e330
This task gives a small reproducible test case; the problem was well explained in #5882 (comment) , includes a workaround (for x86_64 only though). While the workaround works, it may be nicer if zig provided headers of the requested version, and make this problem go away?
TLDR: zig is using "too new" glibc headers, which sometimes references undefined symbols. This fails compilation for at least sqlite and libuv when older glibc is selected, because it redefines
fcntltofcntl64, which is present only in newer glibcs.main.cThis fails when target is glibc 2.27 or older:
And works with glibc 2.28+:
This task gives a small reproducible test case; the problem was well explained in #5882 (comment) , includes a workaround (for x86_64 only though). While the workaround works, it may be nicer if zig provided headers of the requested version, and make this problem go away?