ziglang / zig

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

pthread is always linked to the binary with `zig cc` #20919

Closed faptc closed 1 week ago

faptc commented 1 month ago

Zig Version

0.14.0-dev.829+2e26cf83c

Steps to Reproduce and Observed Behavior

Given this helloworld.c file:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    puts("hello world");
    system("/bin/ls"); // <-- Maybe this trigger zig to link to pthread
    return 0;
}

Build it with zig cc

> zig cc -target x86_64-linux-gnu -g ./helloworld.c
> ldd a.out
linux-vdso.so.1 (0x000078a750191000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x000078a750173000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000078a74fe00000)
/lib64/ld-linux-x86-64.so.2 (0x000078a750193000)
> rm a.out
> zig cc -target x86_64-linux-gnu -no-pthread -g ./helloworld.c
zig: warning: argument unused during compilation: '-no-pthread' [-Wunused-command-line-argument]
> ldd a.out 
linux-vdso.so.1 (0x000079cd50baf000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x000079cd50b91000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000079cd50800000)
/lib64/ld-linux-x86-64.so.2 (0x000079cd50bb1000)
> rm a.out
> /bin/clang -target x86_64-linux-gnu -g ./helloworld.c
> ldd a.out
linux-vdso.so.1 (0x0000751aa49ff000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000751aa4600000)
/lib64/ld-linux-x86-64.so.2 (0x0000751aa4a01000)

libpthread is always linked to the binary by zig, even with -no-pthread option.

Expected Behavior

No pthread is linked in this case maybe.

Context

I'm trying to build a .c file with glibc 2.25 or lower. If the binary linked with pthread. I cannot run it locally due to this error:

relocation error: ./a.out: symbol system, version GLIBC_2.2.5 not defined in file libpthread.so.0 with link time reference

So for the temporary solution, I viewed ouput of zig cc -v and manually run ld.lld without libpthread.o.

nektro commented 1 month ago

does it still happen if you use -target x86_64-linux-gnu.2.2.5 ?

faptc commented 1 month ago

Still it is

> zig cc -target x86_64-linux-gnu.2.2.5 -g ./helloworld.c
> ldd ./a.out 
        linux-vdso.so.1 (0x0000738ea580b000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x0000738ea57ed000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000738ea5400000)
        /lib64/ld-linux-x86-64.so.2 (0x0000738ea580d000)
> ./a.out # ok
> patchelf --set-interpreter ./ld-2.23.so --set-rpath ./ a.out
> ./a.out 
./a.out: relocation error: ./a.out: symbol system, version GLIBC_2.2.5 not defined in file libpthread.so.0 with link time reference
alexrp commented 1 week ago
 system:
  library: libpthread.so
  versions: 2.2.5
  targets: x86_64-linux-gnu
 system:
  library: libc.so
  versions: 2.2.5
  targets: x86_64-linux-gnu

The libpthread symbol is being picked by the linker because it happens to come first:

ld.lld ... /home/alexrp/.cache/zig/o/b6afba54524a1bf7e477237233de72d6/libpthread.so.0 /home/alexrp/.cache/zig/o/b6afba54524a1bf7e477237233de72d6/libc.so.6 ...

The reason you're not seeing the same with Clang or GCC, even with -pthread, is that, since glibc 2.34, libpthread is empty and just forwards to libc (likewise for libdl, librt, and libutil).