Skip to content

zig cc -l :path/to/lib.so sets the DSO paths incorrectly #15743

Description

@motiejus

Summary: zig cc -l :path/to/lib.so behavior differs across gcc/clang and zig cc:

$ make test
readelf -d dylib_client.zig-cc | grep -E "runpath|versioned" | sort
 0x0000000000000001 (NEEDED)             Shared library: [x/libversioned.so.2]
 0x000000000000001d (RUNPATH)            Library runpath: [$ORIGIN/x:x]
readelf -d dylib_client.gcc | grep -E "runpath|versioned" | sort
 0x0000000000000001 (NEEDED)             Shared library: [libversioned.so.2]
 0x000000000000001d (RUNPATH)            Library runpath: [$ORIGIN/x]

As we can see, gcc/clang-16 store only the basename, whereas zig cc stores the full path. In case of gcc/clang, the resulting binary still works, because the x folder is added to runpath.

Documentation is not clear about this, but as a result of the behavior difference, rules_go unit tests fail when executed with zig cc.

Collapsed: full repro case

dylib_client.c

extern int foo();

int main() {
        return foo();
}

x-imported.c

int foo() { return 0; }

Makefile

ZIG ?= zig

.PHONY: test
test: t-rpath.zig-cc t-rpath.gcc t-plain.gcc t-plain.zig-cc x/libversioned.so.2
        @echo gcc rpath:
        @readelf -d t-rpath.gcc | grep -E "runpath|versioned" | sort
        @echo gcc plain:
        @readelf -d t-plain.gcc | grep -E "runpath|versioned" | sort
        @echo zig cc rpath:
        @readelf -d t-rpath.zig-cc | grep -E "runpath|versioned" | sort
        @echo zig cc plain:
        @readelf -d t-plain.zig-cc | grep -E "runpath|versioned" | sort

RPATHFLAGS='-Wl,-rpath,$$ORIGIN/x' -L x -l :libversioned.so.2
PLAINFLAGS=-L x -l :libversioned.so.2

x/imported.c: x-imported.c
        mkdir x
        cp $< $@

t-rpath.zig-cc: dylib_client.c x/libversioned.so.2
        $(ZIG) cc $< $(RPATHFLAGS) -o $@

t-rpath.gcc: dylib_client.c x/libversioned.so.2
        gcc $< $(RPATHFLAGS) -o $@

t-plain.zig-cc: dylib_client.c x/libversioned.so.2
        $(ZIG) cc $< $(PLAINFLAGS) -o $@

t-plain.gcc: dylib_client.c x/libversioned.so.2
        gcc $< $(PLAINFLAGS) -o $@

x/libversioned.so.2: x/imported.c
        $(CC) -shared -o x/libversioned.so.2 x/imported.c

clean:
        rm -f x/libversioned.so.2 t-*cc

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions