zig icon indicating copy to clipboard operation
zig copied to clipboard

zig cc/c++: Statically linking libc++ can change program semantics

Open topolarity opened this issue 1 year ago • 2 comments

Zig Version

0.10.0-dev.3028+337147068

Steps to Reproduce

Hit this one on https://github.com/ziglang/zig/issues/11168 and realized it's a more general problem for libraries compiled with Zig.

// foo.cpp
#include <system_error>
std::error_condition foo() {
	return std::generic_category().default_error_condition(ENOENT);
}
// main.cpp
#include <system_error>
std::error_condition foo();
int main() {
	if (foo() != std::generic_category().default_error_condition(ENOENT)) {
		fprintf(stderr, "error: errors compare unequal.\n");
	}
}

With clang:

$ clang++ foo.cpp -o libfoo.so -shared
$ clang++ main.cpp -lfoo -L. -lstdc++ -rpath . -o main
$ ./main

With zig c++:

$ zig c++ foo.cpp -o libfoo.so -shared
$ zig c++ main.cpp -lfoo -L. -lstdc++ -rpath . -o main
./build/zig c++ main.cpp -lfoo -L. -lstdc++ -rpath . -o main
zig: warning: -rpath .: 'linker' input unused [-Wunused-command-line-argument]
$ ./main
error: errors compare unequal.

Expected Behavior

Library should behave the same when compiled with Zig and with Clang.

Actual Behavior

Behavior diverges because Zig links libstdc++ statically by default

topolarity avatar Jul 17 '22 04:07 topolarity

Related: https://github.com/ziglang/zig/pull/12085#pullrequestreview-1036761330

topolarity avatar Jul 17 '22 04:07 topolarity

I believe one consequence of this is that you cannot use Zig to build LLVM/Clang correctly as a shared library (-DLLVM_BUILD_LLVM_DYLIB=ON -DLLVM_LINK_LLVM_DYLIB=ON)

topolarity avatar Jul 17 '22 21:07 topolarity

Wanted to briefly document the result of discussions on Discord (cc @kubkon). The current plan of action is to improve Zig's automatic handling of -lc++ so that it links libc++ dynamically:

  1. if libc++ appears anywhere in the dynamic dependency tree, OR
  2. if creating a shared library

In the meantime, users can workaround this by providing the libc++ .so / .tbd file as an object to force dynamic linking (e.g. zig c++ main.cpp /path/to/libc++.so)

topolarity avatar Aug 30 '22 19:08 topolarity