ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.35k stars 2.43k forks source link

Cannot build with `arc4random_buf` on Linux glibc #20426

Closed hcoona closed 1 month ago

hcoona commented 1 month ago

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

cat >a.c <<EOF
#include <stdlib.h>

int main(void) {
    int a[100];
    arc4random_buf(a, 100);
    return 0;
}
EOF
zig cc -o a -std=gnu11 -D_GNU_SOURCE=1 a.c -target x86_64-linux-gnu.2.35

Output:

ld.lld: error: undefined symbol: arc4random_buf
>>> referenced by a.c:5
>>>               /home/shuaiz/.cache/zig/o/1143050e0f6c9bc272947fe861f0e341/a.o:(main)

Expected Behavior

Either the function arc4random_buf not declared or correctly linked.

For example:

zig cc -o a -std=gnu11 -D_GNU_SOURCE=1 a.c -lc -target x86_64-linux-musl

This would report arc4random_buf not declared.

a.c:5:2: error: call to undeclared function 'arc4random_buf'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    5 |         arc4random_buf(a, 100);
      |         ^
1 error generated.

and

zig cc -o a -std=gnu11 -D_GNU_SOURCE=1 a.c -lc -target x86_64-macos

This would success with no error.

daurnimator commented 1 month ago
x86_64-linux-gnu.2.35

arc4random_buf was added in glibc 2.36, so it's not expected to exist when targeting 2.35 https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;h=8420a65cd06874ee09518366b8fba746a557212a;hb=6f4e0fcfa2d2b0915816a3a3a1d48b4763a7dee2

The way that zig generates glibc headers, I don't think you can depend on the absence of declarations?

hcoona commented 1 month ago

Thanks for the information. It confused me because I can find the declaration of arc4random_buf in stdlib.h but it failed to link. You answered why it failed to link. And, we remained the problem whether it should be present in the header.

If the philosophy of zig is to always compile with the new glibc header, it should be presence and leave the problem to zig user to maintain the compatible issue. If the philosophy of zig is to keep compatibility, maybe it better to hide too new API breaking or use old glibc if user compile targeting old glibc.

The way that zig generates glibc headers, I don't think you can depend on the absence of declarations?

Do you mean it's by design zig generate glibc headers align to a specific glibc version no matter what target I'm using? It's as expected that I can find the declaration of arc4random_buf in stdlib.h but the implementation is absent, isn't it?

rootbeer commented 1 month ago

The Zig glibc headers are currently manually patched to represent all versions of glibc (see https://github.com/ziglang/zig/tree/master/lib/libc/glibc#readme for details). The arc4random_buf symbol should be behind version-checking ifdefs in the Zig copy of the header file, but it was missed during an upgrade. See https://github.com/ziglang/zig/pull/17610 for an example of adding such guards for the reallocarray symbol.