build: Fix build for variety of musl-based Linux distributions
Before this change, build.rs had two problems which were making it impossible to build on different musl-based Linux environments:
- It was assuming that the C++ library on all musl-based systems is
LLVM libc++.
- In the most cases, it's the opposite. LLVM packaged in Alpine is linked against GNU libstdc++, as well as LLVM tarballs in Rust CI.
- Gentoo with musl-llvm profile, even though it links LLVM against
libc++, has a different name for the system-wide static library
(
/usr/lib/libc++_static.ainstead of/usr/lib/libc++.a, which is a link script).
- When linking runtime libraries statically (
crt-static), Cargo doesn't look for the system-wide static libraries in/usr/lib, unless that directory is added to the link flags with-L.
The first point is addressed by:
- Linking to libstdc++ by default, even for musl systems.
- Ability to override that choice with
LLVM_SYS_LIBCPPenvironment variable for environments which use LLVM libc++.
The second point is addressed by:
- Adding
/usr/liband other system dirs tocargo::rustc-link-searchon Linux withcrt-staticbuilds. - Exposing
LLVM_SYS_SYSTEM_LIBRARY_DIRSenvironment variable, where callers can add additional paths.
After this change, building llvm-sys on Alpine can be done just with
the usual cargo build and LLVM_SYS_191_PREFIX variable pointing to
the LLVM 19 prefix. In CI, we are using Rust CI tarballs for that.
On any Linux environment where LLVM is linked against libc++, llvm-sys can be built with:
LLVM_SYS_LIBCPP=c++ cargo build --no-default-features
Building llvm-sys Gentoo with llvm-musl profile, where libc++ static
library is called libc++_static.a and it needs libc++abi.a to work,
can be done with:
LLVM_SYS_LIBCPP=c++_static RUSTFLAGS="-lc++abi" cargo test --no-default-features
Unfortunately, the latter configurations are not tested in CI - as for now, there are no publicly available libLLVM binary blobs linked against LLVM libc++ - such configuration requires compilation of LLVM.