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
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
Summary:
zig cc -l :path/to/lib.sobehavior differs acrossgcc/clangandzig cc:As we can see, gcc/clang-16 store only the basename, whereas
zig ccstores the full path. In case of gcc/clang, the resulting binary still works, because thexfolder is added to runpath.Documentation is not clear about this, but as a result of the behavior difference,
rules_gounit tests fail when executed withzig cc.Collapsed: full repro case
dylib_client.c
x-imported.c
Makefile