Skip to content

zig c++ linker puts relative path into NEEDED section of dynamically linked executable breaking rpath resolution #21219

@FabianHahn

Description

@FabianHahn

Zig Version

0.14.0-dev.1320+492cc2ef8

Steps to Reproduce and Observed Behavior

I'm trying to link an executable dynamically against a shared library. The shared library and the output executable are located in separate lib/ and bin/ directories, respectively. I'm further setting an rpath so the executable will point to the relative library location correctly:

$ ~/zig-0.14.0-dev.1320+492cc2ef8 c++ -target x86_64-linux-gnu.2.27 -o bin/dynamic -Xlinker -rpath -Xlinker '$ORIGIN/../lib/' -Llib test.o -lfoo
$ ldd bin/dynamic 
	linux-vdso.so.1 (0x00007ffcf7198000)
	lib/libfoo.so (0x00007f786fdd7000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f786fd95000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f786fba3000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f786fb9d000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f786fddc000)
$ objdump -x bin/dynamic | grep libfoo
  NEEDED               lib/libfoo.so

This is unexpected and not what I want! The executable now links against the entire relative path lib/libfoo.so rather than just libfoo.so. It also means that the rpath is useless when I try to invoke the executable from the bin/ directory:

$ (cd bin; ldd dynamic)
	linux-vdso.so.1 (0x00007ffd3afac000)
	lib/libfoo.so => not found
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f21ddc9a000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f21ddaa8000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f21ddaa2000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f21ddcde000)

I'm reporting this on the latest 0.14.0-dev snapshot version to demonstrate that the problem is still there, however, the bug has been present since 0.11.0.

Expected Behavior

Zig 0.10.1 is the last released version that exhibits the correct behavior:

$ ~/zig-0.10.1 c++ -target x86_64-linux-gnu.2.27 -o bin/dynamic -Xlinker -rpath -Xlinker '$ORIGIN/../lib/' -Llib test.o -lfoo
$ ldd bin/dynamic
	linux-vdso.so.1 (0x00007ffc459f8000)
	libfoo.so => /home/fabian/repro/bin/../lib/libfoo.so (0x00007f0fbfa8e000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0fbfa4c000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0fbf85a000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f0fbf854000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f0fbfa93000)
$ objdump -x bin/dynamic | grep libfoo
  NEEDED               libfoo.so
$ (cd bin; ldd dynamic)
	linux-vdso.so.1 (0x00007ffd5fcef000)
	libfoo.so => /home/fabian/repro/bin/./../lib/libfoo.so (0x00007f721a419000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f721a3d7000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f721a1e5000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f721a1df000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f721a41e000)

Note how the executable now depends on libfoo.so directly and makes correct use of the rpath no matter where it is executed from.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions