commit: 7a20a50d0784ca4875f675371ef11140033e8d87 Author: Z. Liu <zhixu.liu <AT> gmail <DOT> com> AuthorDate: Fri Oct 3 12:13:23 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Sun Oct 26 01:02:48 2025 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=7a20a50d
dev-lang/rust: fix bootstrap build under llvm profile When bootstrapping Rust with the llvm profile (both glibc and musl), the build fails at the mrustc stage due to two issues related to C++ standard library handling. 1. Compilation failure When llvm-core/llvm is built with clang, 'llvm-config --cxxflags' includes '-stdlib=libc++', but not when built with GCC. But under musl profile, GCC has a known bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122409) in handling the '-stdlib=libc++' option. It fails to search '/usr/include/c++/v1', causing standard headers such as <cstddef> to be missing unless the include path is manually specified via '-I/usr/include/c++/v1'. This patch fixes the issue by wrapping llvm-config calls and explicitly appending libc++'s header path whenever '-stdlib=libc++' is detected. Below is the relevant error log: > Calling > /var/tmp/portage/dev-lang/rust-1.74.1-r101/work/bootstrap/mrustc-stage0/rustc-build/build_rustc_llvm_run > failed (see > /var/tmp/portage/dev-lang/rust-1.74.1-r101/work/bootstrap/mrustc-stage0/rustc-build/build_rustc_llvm.txt_failed.txt > for stdout) /var/tmp/portage/dev-lang/rust-1.74.1-r101/work/bootstrap/mrustc-stage0/rustc-build/build_rustc_llvm.txt_failed.txt > running: "x86_64-pc-linux-musl-g++" "-O2" "-ffunction-sections" > "-fdata-sections" "-fPIC" "-gdwarf-4" "-fno-omit-frame-pointer" "-m64" "-O2" > "-pipe" "-I/usr/lib/llvm/17/include" "-std=c++17" "-stdlib=libc++" > "-D__STDC_CONSTANT_MACROS" "-D__STDC_FORMAT_MACROS" "-D__STDC_LIMIT_MACROS" > "-DLLVM_COMPONENT_AARCH64" "-DLLVM_COMPONENT_AMDGPU" "-DLLVM_COMPONENT_ARM" > "-DLLVM_COMPONENT_ASMPARSER" "-DLLVM_COMPONENT_AVR" > "-DLLVM_COMPONENT_BITREADER" "-DLLVM_COMPONENT_BITWRITER" > "-DLLVM_COMPONENT_BPF" "-DLLVM_COMPONENT_COVERAGE" "-DLLVM_COMPONENT_HEXAGON" > "-DLLVM_COMPONENT_INSTRUMENTATION" "-DLLVM_COMPONENT_IPO" > "-DLLVM_COMPONENT_LINKER" "-DLLVM_COMPONENT_LOONGARCH" "-DLLVM_COMPONENT_LTO" > "-DLLVM_COMPONENT_MIPS" "-DLLVM_COMPONENT_MSP430" "-DLLVM_COMPONENT_NVPTX" > "-DLLVM_COMPONENT_POWERPC" "-DLLVM_COMPONENT_RISCV" "-DLLVM_COMPONENT_SPARC" > "-DLLVM_COMPONENT_SYSTEMZ" "-DLLVM_COMPONENT_WEBASSEMBLY" > "-DLLVM_COMPONENT_X86" "-o" > "/var/tmp/portage/dev-lang/rust-1.74.1-r101/work/bootstrap/mrustc-stage0/r ustc-build/build_rustc_llvm/llvm-wrapper/PassWrapper.o" "-c" "llvm-wrapper/PassWrapper.cpp" > cargo:warning=llvm-wrapper/PassWrapper.cpp:3:10: fatal error: cstddef: No > such file or directory > cargo:warning= 3 | #include <cstddef> > cargo:warning= | ^~~~~~~~~ > cargo:warning=compilation terminated. > exit status: 1 2. Linker failure Found on llvm profile for both glibc and musl if llvm-core/llvm is built by GCC. The bundled llvm is always built by gcc because bootstrap with murst requires gcc. Under the llvm profile `LLVM_USE_LIBCXX=1` is defined, causing Rust build scripts to link with `-lc++` instead of `-lstdc++`. Since mrustc’s g++-compiled objects depend on libstdc++, linking fails with (glibc): > /.../x86_64-pc-linux-musl/bin/ld: > /var/tmp/portage/dev-lang/rust-1.74.1-r101/work/bootstrap/mrustc-stage0/rustc-build/build_rustc_llvm/libllvm-wrapper.a(PassWrapper.o): > undefined reference to symbol '_ZNSt6localeD1Ev@ <AT> GLIBCXX_3.4' > /.../x86_64-pc-linux-musl/bin/ld: > /usr/lib/gcc/x86_64-pc-linux-musl/15/libstdc++.so.6: error adding symbols: > DSO missing from command line or (musl): > /.../x86_64-pc-linux-musl/bin/ld: warning: x86_64.o: missing .note.GNU-stack > section implies executable stack > /.../x86_64-pc-linux-musl/bin/ld: NOTE: This behaviour is deprecated and will > be removed in a future version of the linker > /.../x86_64-pc-linux-musl/bin/ld: > /var/tmp/portage/dev-lang/rust-1.74.1-r101/work/bootstrap/mrustc-stage0/rustc-build/build_rustc_llvm/libllvm-wrapper.a(PassWrapper.o): > in function `std::_Rb_tree_iterator<std::pair<unsigned long const, > llvm::GlobalValue::LinkageTypes> >::operator--()': > /usr/lib/gcc/x86_64-pc-linux-musl/14/include/g++-v14/bits/stl_tree.h:298:(.text._ZNSt8_Rb_treeImSt4pairIKmN4llvm11GlobalValue12LinkageTypesEESt10_Select1stIS5_ESt4lessImESaIS5_EE24_M_get_insert_unique_posERS1_.isra.0+0x93): > undefined reference to `std::_Rb_tree_decrement(std::_Rb_tree_node_base*)' Fix by unsetting `LLVM_USE_LIBCXX` during bootstrap, ensuring that the build links against libstdc++ instead of libc++. See the relevant Rust code in `compiler/rustc_llvm/build.rs`. Note: llvm-config may refer to the bundled LLVM if USE="-system-llvm", so we avoid relying on tc-get-cxx-stdlib in this context. Signed-off-by: Z. Liu <zhixu.liu <AT> gmail.com> Part-of: https://github.com/gentoo/gentoo/pull/44129 Closes: https://github.com/gentoo/gentoo/pull/44129 Signed-off-by: Sam James <sam <AT> gentoo.org> dev-lang/rust/rust-1.74.1-r101.ebuild | 62 +++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/dev-lang/rust/rust-1.74.1-r101.ebuild b/dev-lang/rust/rust-1.74.1-r101.ebuild index 2aeca76715d5..910c77941d1e 100644 --- a/dev-lang/rust/rust-1.74.1-r101.ebuild +++ b/dev-lang/rust/rust-1.74.1-r101.ebuild @@ -237,7 +237,10 @@ pkg_setup() { if use mrustc-bootstrap; then if ! tc-is-gcc; then - die "USE=mrustc-bootstrap reqires that the build environment use GCC" + # USE="mrustc-bootstrap" reqires that the build environment use GCC + export CC=${CHOST}-gcc + export CXX=${CHOST}-g++ + tc-is-gcc || die "tc-is-gcc failed in spite of CC=${CC}" fi else rust_pkg_setup @@ -459,7 +462,11 @@ src_configure() { ranlib = "$(tc-getRANLIB)" llvm-libunwind = "$(usex llvm-libunwind $(usex system-llvm system in-tree) no)" _EOF_ - if use system-llvm; then + if use mrustc-bootstrap; then + cat <<- _EOF_ >> "${S}"/config.toml + llvm-config = "${WORKDIR}/llvm-config" + _EOF_ + elif use system-llvm; then cat <<- _EOF_ >> "${S}"/config.toml llvm-config = "$(get_llvm_prefix)/bin/llvm-config" _EOF_ @@ -648,13 +655,64 @@ mrustc_bootstrap() { # These flags are used in every invocation of our bootstrap `cargo`. local cargo_flags="--target ${CFG_COMPILER_HOST_TRIPLE} -j $(makeopts_jobs) --release --verbose" + # for bootstrap, let's using the built-in stdlib of compiler (could be the bundled one) + filter-flags '-stdlib=*' + + # mrustc requires gcc, so disable libcxx to avoid linker failure on w/o '-lstdc++' + [[ "${LLVM_USE_LIBCXX}" == "1" ]] && unset LLVM_USE_LIBCXX + + local llvm_config_wrapper_cxxflags=0 + if use system-llvm; then export LLVM_CONFIG="$(get_llvm_prefix)/bin/llvm-config" + + local llvm_config_cxxflags=$(${LLVM_CONFIG} --cxxflags) + elog "Checking llvm-config --cxxflags: '${llvm_config_cxxflags}'" + [[ "${llvm_config_cxxflags}" =~ (^|[[:space:]])-stdlib=libc\+\+([[:space:]]|$) ]] && { + elog "Found LLVM CXXFLAGS has \"--stdlib=libc++\"" + llvm_config_wrapper_cxxflags=1 + } else llvm_bootstrap export LLVM_CONFIG="${WORKDIR}/bootstrap/llvm/bin/llvm-config" fi + elog "LLVM_CONFIG before wrappers: ${LLVM_CONFIG}" + + # workaround for gcc bug 122409 on musl by wrapping llvm-config + # to append libc++ header if has "-stdlib=libc++" + elog "Preparing wrapper of llvm-config (${WORKDIR}/llvm-config)" + cat > ${WORKDIR}/llvm-config <<-EOF || die + #!/bin/bash + + RULES=() + for flag in "\$@"; do + case "\${flag}" in + $([[ "${llvm_config_wrapper_cxxflags}" == 1 ]] && { + echo " --cxxflags) RULES+=( \"-E\" \"s@(^|[[:space:]]+)(-stdlib=libc\\+\\+)(\\$|[[:space:]])@\\1-I${EPREFIX}/usr/include/c++/v1 \\2\\3@g\" ) ;;" + }) + *) + ;; + esac + done + + [[ -z "\${RULES}" ]] && { + ${LLVM_CONFIG} "\$@" + } || { + ${LLVM_CONFIG} "\$@" | \\ + tee -a ${T}/llvm-config.0.log | \\ + sed "\${RULES[@]}" | \\ + tee -a ${T}/llvm-config.1.log + exit \${PIPESTATUS[0]} + } + EOF + export LLVM_CONFIG="${WORKDIR}/llvm-config" + chmod +x ${WORKDIR}/llvm-config || die + + einfo "llvm-config wrapper contents:" + cat "${LLVM_CONFIG}" || die + echo + # define the mrustc sysroot and common minicargo arguments. local mrustc_sysroot="${BROOT}/usr/lib/rust/mrustc-${MRUSTC_VERSION}/lib/rustlib/${CFG_COMPILER_HOST_TRIPLE}/lib" local minicargo_common_args=(
