commit:     3e1fbdb654f537f530cbd4945d0384ed6d67faeb
Author:     Michal Rostecki <vadorovsky <AT> protonmail <DOT> com>
AuthorDate: Mon Aug  4 11:37:28 2025 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Wed Aug  6 12:29:15 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=3e1fbdb6

llvm-runtimes/libcxx: Support crosspkg build

Inherit the `crossdev` eclass, use clang for the current `CTARGET` and
install libcxx into a cross sysroot, if package belongs to any crossdev
category. That allows to bootstrap libcxx with crossdev by installing
`cross_*/libcxx`.

Extend the compiler test with the case when the (cross) toolchain has
a runtime, but doesn't have stdlib yet (because it's about to be built).
In such case, a build with default arguments fails, but a build with
`-nostdlib` succeeds. libc++ doesn't need stdlib to build, so that's
fine.

Signed-off-by: Michal Rostecki <vadorovsky <AT> protonmail.com>
Part-of: https://github.com/gentoo/gentoo/pull/39280
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>
Part-of: https://github.com/gentoo/gentoo/pull/39280
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>

 llvm-runtimes/libcxx/libcxx-19.1.7.ebuild      | 50 ++++++++++++++++++--------
 llvm-runtimes/libcxx/libcxx-20.1.8.ebuild      | 48 ++++++++++++++++++-------
 llvm-runtimes/libcxx/libcxx-21.1.0.9999.ebuild | 48 ++++++++++++++++++-------
 llvm-runtimes/libcxx/libcxx-22.0.0.9999.ebuild | 48 ++++++++++++++++++-------
 4 files changed, 141 insertions(+), 53 deletions(-)

diff --git a/llvm-runtimes/libcxx/libcxx-19.1.7.ebuild 
b/llvm-runtimes/libcxx/libcxx-19.1.7.ebuild
index 12bee325ccd4..00dd72b37153 100644
--- a/llvm-runtimes/libcxx/libcxx-19.1.7.ebuild
+++ b/llvm-runtimes/libcxx/libcxx-19.1.7.ebuild
@@ -3,9 +3,9 @@
 
 EAPI=8
 
-PYTHON_COMPAT=( python3_{10..13} )
-inherit cmake-multilib flag-o-matic llvm.org llvm-utils python-any-r1
-inherit toolchain-funcs
+PYTHON_COMPAT=( python3_{11..13} )
+inherit cmake-multilib crossdev flag-o-matic llvm.org llvm-utils
+inherit python-any-r1 toolchain-funcs
 
 DESCRIPTION="New implementation of the C++ standard library, targeting C++11"
 HOMEPAGE="https://libcxx.llvm.org/";
@@ -67,12 +67,15 @@ test_compiler() {
 src_configure() {
        llvm_prepend_path "${LLVM_MAJOR}"
 
+       local install_prefix=${EPREFIX}
+       is_crosspkg && install_prefix+=/usr/${CTARGET}
+
        # note: we need to do this before multilib kicks in since it will
        # alter the CHOST
        local cxxabi cxxabi_incs
        if use libcxxabi; then
                cxxabi=system-libcxxabi
-               cxxabi_incs="${EPREFIX}/usr/include/c++/v1"
+               cxxabi_incs="${install_prefix}/usr/include/c++/v1"
        else
                local 
gcc_inc="${EPREFIX}/usr/lib/gcc/${CHOST}/$(gcc-fullversion)/include/g++-v$(gcc-major-version)"
                cxxabi=libsupc++
@@ -84,8 +87,8 @@ src_configure() {
 
 multilib_src_configure() {
        if use clang; then
-               local -x CC=${CHOST}-clang
-               local -x CXX=${CHOST}-clang++
+               local -x CC=${CTARGET}-clang
+               local -x CXX=${CTARGET}-clang++
                strip-unsupported-flags
        fi
 
@@ -93,18 +96,25 @@ multilib_src_configure() {
        local use_compiler_rt=OFF
        [[ $(tc-get-c-rtlib) == compiler-rt ]] && use_compiler_rt=ON
 
-       # bootstrap: cmake is unhappy if compiler can't link to stdlib
-       local nolib_flags=( -nodefaultlibs -lc )
-       if ! test_compiler; then
-               if test_compiler "${nolib_flags[@]}"; then
-                       local -x LDFLAGS="${LDFLAGS} ${nolib_flags[*]}"
-                       ewarn "${CXX} seems to lack runtime, trying with 
${nolib_flags[*]}"
+       # Scenarios to consider:
+       #
+       # 1. Compiler test works with the default flags.
+       # 2. There is a runtime library, but no stdlib. In that case, leave the
+       #    LDFLAGS untouched, since there is no self-dependency in libc++.
+       # 3. There is no runtime library nor stdlib. In that case, overwrite the
+       #    LDFLAGS.
+       local nostdlib_flags=( -nostdlib --rtlib=compiler-rt -lc )
+       local nort_flags=( -nodefaultlibs -lc )
+       if ! test_compiler && ! test_compiler "${nostdlib_flags[@]}"; then
+               if test_compiler "${nort_flags[@]}"; then
+                       local -x LDFLAGS="${LDFLAGS} ${nort_flags[*]}"
+                       ewarn "${CXX} seems to lack runtime, trying with 
${nort_flags[*]}"
                fi
        fi
 
        local libdir=$(get_libdir)
        local mycmakeargs=(
-               -DCMAKE_CXX_COMPILER_TARGET="${CHOST}"
+               -DCMAKE_CXX_COMPILER_TARGET="${CTARGET}"
                -DPython3_EXECUTABLE="${PYTHON}"
                -DLLVM_ENABLE_RUNTIMES=libcxx
                -DLLVM_INCLUDE_TESTS=OFF
@@ -124,7 +134,18 @@ multilib_src_configure() {
                # this is broken with standalone builds, and also meaningless
                -DLIBCXXABI_USE_LLVM_UNWINDER=OFF
        )
-
+       if is_crosspkg; then
+               # Needed to target built libc headers
+               local -x CFLAGS="${CFLAGS} -isystem 
${ESYSROOT}/usr/${CTARGET}/usr/include"
+               mycmakeargs+=(
+                       # Without this, the compiler will compile a test program
+                       # and fail due to no builtins.
+                       -DCMAKE_C_COMPILER_WORKS=1
+                       -DCMAKE_CXX_COMPILER_WORKS=1
+                       # Install inside the cross sysroot.
+                       -DCMAKE_INSTALL_PREFIX="${EPREFIX}/usr/${CTARGET}/usr"
+               )
+       fi
        if use test; then
                mycmakeargs+=(
                        -DLLVM_EXTERNAL_LIT="${EPREFIX}/usr/bin/lit"
@@ -153,6 +174,7 @@ multilib_src_install() {
        # since we've replaced libc++.{a,so} with ldscripts, now we have to
        # install the extra symlinks
        if [[ ${CHOST} != *-darwin* ]] ; then
+               is_crosspkg && into /usr/${CTARGET}
                dolib.so lib/libc++_shared.so
                use static-libs && dolib.a lib/libc++_static.a
        fi

diff --git a/llvm-runtimes/libcxx/libcxx-20.1.8.ebuild 
b/llvm-runtimes/libcxx/libcxx-20.1.8.ebuild
index 6d27e7859c55..3b1f3f487fa0 100644
--- a/llvm-runtimes/libcxx/libcxx-20.1.8.ebuild
+++ b/llvm-runtimes/libcxx/libcxx-20.1.8.ebuild
@@ -4,8 +4,8 @@
 EAPI=8
 
 PYTHON_COMPAT=( python3_{11..14} )
-inherit cmake-multilib flag-o-matic llvm.org llvm-utils python-any-r1
-inherit toolchain-funcs
+inherit cmake-multilib crossdev flag-o-matic llvm.org llvm-utils
+inherit python-any-r1 toolchain-funcs
 
 DESCRIPTION="New implementation of the C++ standard library, targeting C++11"
 HOMEPAGE="https://libcxx.llvm.org/";
@@ -69,12 +69,15 @@ test_compiler() {
 src_configure() {
        llvm_prepend_path "${LLVM_MAJOR}"
 
+       local install_prefix=${EPREFIX}
+       is_crosspkg && install_prefix+=/usr/${CTARGET}
+
        # note: we need to do this before multilib kicks in since it will
        # alter the CHOST
        local cxxabi cxxabi_incs
        if use libcxxabi; then
                cxxabi=system-libcxxabi
-               cxxabi_incs="${EPREFIX}/usr/include/c++/v1"
+               cxxabi_incs="${install_prefix}/usr/include/c++/v1"
        else
                local 
gcc_inc="${EPREFIX}/usr/lib/gcc/${CHOST}/$(gcc-fullversion)/include/g++-v$(gcc-major-version)"
                cxxabi=libsupc++
@@ -86,8 +89,8 @@ src_configure() {
 
 multilib_src_configure() {
        if use clang; then
-               local -x CC=${CHOST}-clang
-               local -x CXX=${CHOST}-clang++
+               local -x CC=${CTARGET}-clang
+               local -x CXX=${CTARGET}-clang++
                strip-unsupported-flags
        fi
 
@@ -95,18 +98,25 @@ multilib_src_configure() {
        local use_compiler_rt=OFF
        [[ $(tc-get-c-rtlib) == compiler-rt ]] && use_compiler_rt=ON
 
-       # bootstrap: cmake is unhappy if compiler can't link to stdlib
-       local nolib_flags=( -nodefaultlibs -lc )
-       if ! test_compiler; then
-               if test_compiler "${nolib_flags[@]}"; then
-                       local -x LDFLAGS="${LDFLAGS} ${nolib_flags[*]}"
-                       ewarn "${CXX} seems to lack runtime, trying with 
${nolib_flags[*]}"
+       # Scenarios to consider:
+       #
+       # 1. Compiler test works with the default flags.
+       # 2. There is a runtime library, but no stdlib. In that case, leave the
+       #    LDFLAGS untouched, since there is no self-dependency in libc++.
+       # 3. There is no runtime library nor stdlib. In that case, overwrite the
+       #    LDFLAGS.
+       local nostdlib_flags=( -nostdlib --rtlib=compiler-rt -lc )
+       local nort_flags=( -nodefaultlibs -lc )
+       if ! test_compiler && ! test_compiler "${nostdlib_flags[@]}"; then
+               if test_compiler "${nort_flags[@]}"; then
+                       local -x LDFLAGS="${LDFLAGS} ${nort_flags[*]}"
+                       ewarn "${CXX} seems to lack runtime, trying with 
${nort_flags[*]}"
                fi
        fi
 
        local libdir=$(get_libdir)
        local mycmakeargs=(
-               -DCMAKE_CXX_COMPILER_TARGET="${CHOST}"
+               -DCMAKE_CXX_COMPILER_TARGET="${CTARGET}"
                -DPython3_EXECUTABLE="${PYTHON}"
                -DLLVM_ENABLE_RUNTIMES=libcxx
                -DLLVM_INCLUDE_TESTS=OFF
@@ -126,7 +136,18 @@ multilib_src_configure() {
                # this is broken with standalone builds, and also meaningless
                -DLIBCXXABI_USE_LLVM_UNWINDER=OFF
        )
-
+       if is_crosspkg; then
+               # Needed to target built libc headers
+               local -x CFLAGS="${CFLAGS} -isystem 
${ESYSROOT}/usr/${CTARGET}/usr/include"
+               mycmakeargs+=(
+                       # Without this, the compiler will compile a test program
+                       # and fail due to no builtins.
+                       -DCMAKE_C_COMPILER_WORKS=1
+                       -DCMAKE_CXX_COMPILER_WORKS=1
+                       # Install inside the cross sysroot.
+                       -DCMAKE_INSTALL_PREFIX="${EPREFIX}/usr/${CTARGET}/usr"
+               )
+       fi
        if use test; then
                mycmakeargs+=(
                        -DLLVM_EXTERNAL_LIT="${EPREFIX}/usr/bin/lit"
@@ -160,6 +181,7 @@ multilib_src_install() {
        # since we've replaced libc++.{a,so} with ldscripts, now we have to
        # install the extra symlinks
        if [[ ${CHOST} != *-darwin* ]] ; then
+               is_crosspkg && into /usr/${CTARGET}
                dolib.so lib/libc++_shared.so
                use static-libs && dolib.a lib/libc++_static.a
        fi

diff --git a/llvm-runtimes/libcxx/libcxx-21.1.0.9999.ebuild 
b/llvm-runtimes/libcxx/libcxx-21.1.0.9999.ebuild
index fd4499e9fa26..940a5893f521 100644
--- a/llvm-runtimes/libcxx/libcxx-21.1.0.9999.ebuild
+++ b/llvm-runtimes/libcxx/libcxx-21.1.0.9999.ebuild
@@ -4,8 +4,8 @@
 EAPI=8
 
 PYTHON_COMPAT=( python3_{11..14} )
-inherit cmake-multilib flag-o-matic llvm.org llvm-utils python-any-r1
-inherit toolchain-funcs
+inherit cmake-multilib crossdev flag-o-matic llvm.org llvm-utils
+inherit python-any-r1 toolchain-funcs
 
 DESCRIPTION="New implementation of the C++ standard library, targeting C++11"
 HOMEPAGE="https://libcxx.llvm.org/";
@@ -68,12 +68,15 @@ test_compiler() {
 src_configure() {
        llvm_prepend_path "${LLVM_MAJOR}"
 
+       local install_prefix=${EPREFIX}
+       is_crosspkg && install_prefix+=/usr/${CTARGET}
+
        # note: we need to do this before multilib kicks in since it will
        # alter the CHOST
        local cxxabi cxxabi_incs
        if use libcxxabi; then
                cxxabi=system-libcxxabi
-               cxxabi_incs="${EPREFIX}/usr/include/c++/v1"
+               cxxabi_incs="${install_prefix}/usr/include/c++/v1"
        else
                local 
gcc_inc="${EPREFIX}/usr/lib/gcc/${CHOST}/$(gcc-fullversion)/include/g++-v$(gcc-major-version)"
                cxxabi=libsupc++
@@ -85,8 +88,8 @@ src_configure() {
 
 multilib_src_configure() {
        if use clang; then
-               local -x CC=${CHOST}-clang
-               local -x CXX=${CHOST}-clang++
+               local -x CC=${CTARGET}-clang
+               local -x CXX=${CTARGET}-clang++
                strip-unsupported-flags
        fi
 
@@ -94,18 +97,25 @@ multilib_src_configure() {
        local use_compiler_rt=OFF
        [[ $(tc-get-c-rtlib) == compiler-rt ]] && use_compiler_rt=ON
 
-       # bootstrap: cmake is unhappy if compiler can't link to stdlib
-       local nolib_flags=( -nodefaultlibs -lc )
-       if ! test_compiler; then
-               if test_compiler "${nolib_flags[@]}"; then
-                       local -x LDFLAGS="${LDFLAGS} ${nolib_flags[*]}"
-                       ewarn "${CXX} seems to lack runtime, trying with 
${nolib_flags[*]}"
+       # Scenarios to consider:
+       #
+       # 1. Compiler test works with the default flags.
+       # 2. There is a runtime library, but no stdlib. In that case, leave the
+       #    LDFLAGS untouched, since there is no self-dependency in libc++.
+       # 3. There is no runtime library nor stdlib. In that case, overwrite the
+       #    LDFLAGS.
+       local nostdlib_flags=( -nostdlib --rtlib=compiler-rt -lc )
+       local nort_flags=( -nodefaultlibs -lc )
+       if ! test_compiler && ! test_compiler "${nostdlib_flags[@]}"; then
+               if test_compiler "${nort_flags[@]}"; then
+                       local -x LDFLAGS="${LDFLAGS} ${nort_flags[*]}"
+                       ewarn "${CXX} seems to lack runtime, trying with 
${nort_flags[*]}"
                fi
        fi
 
        local libdir=$(get_libdir)
        local mycmakeargs=(
-               -DCMAKE_CXX_COMPILER_TARGET="${CHOST}"
+               -DCMAKE_CXX_COMPILER_TARGET="${CTARGET}"
                -DPython3_EXECUTABLE="${PYTHON}"
                -DLLVM_ENABLE_RUNTIMES=libcxx
                -DLLVM_INCLUDE_TESTS=OFF
@@ -125,7 +135,18 @@ multilib_src_configure() {
                # this is broken with standalone builds, and also meaningless
                -DLIBCXXABI_USE_LLVM_UNWINDER=OFF
        )
-
+       if is_crosspkg; then
+               # Needed to target built libc headers
+               local -x CFLAGS="${CFLAGS} -isystem 
${ESYSROOT}/usr/${CTARGET}/usr/include"
+               mycmakeargs+=(
+                       # Without this, the compiler will compile a test program
+                       # and fail due to no builtins.
+                       -DCMAKE_C_COMPILER_WORKS=1
+                       -DCMAKE_CXX_COMPILER_WORKS=1
+                       # Install inside the cross sysroot.
+                       -DCMAKE_INSTALL_PREFIX="${EPREFIX}/usr/${CTARGET}/usr"
+               )
+       fi
        if use test; then
                mycmakeargs+=(
                        -DLLVM_EXTERNAL_LIT="${EPREFIX}/usr/bin/lit"
@@ -159,6 +180,7 @@ multilib_src_install() {
        # since we've replaced libc++.{a,so} with ldscripts, now we have to
        # install the extra symlinks
        if [[ ${CHOST} != *-darwin* ]] ; then
+               is_crosspkg && into /usr/${CTARGET}
                dolib.so lib/libc++_shared.so
                use static-libs && dolib.a lib/libc++_static.a
        fi

diff --git a/llvm-runtimes/libcxx/libcxx-22.0.0.9999.ebuild 
b/llvm-runtimes/libcxx/libcxx-22.0.0.9999.ebuild
index fd4499e9fa26..940a5893f521 100644
--- a/llvm-runtimes/libcxx/libcxx-22.0.0.9999.ebuild
+++ b/llvm-runtimes/libcxx/libcxx-22.0.0.9999.ebuild
@@ -4,8 +4,8 @@
 EAPI=8
 
 PYTHON_COMPAT=( python3_{11..14} )
-inherit cmake-multilib flag-o-matic llvm.org llvm-utils python-any-r1
-inherit toolchain-funcs
+inherit cmake-multilib crossdev flag-o-matic llvm.org llvm-utils
+inherit python-any-r1 toolchain-funcs
 
 DESCRIPTION="New implementation of the C++ standard library, targeting C++11"
 HOMEPAGE="https://libcxx.llvm.org/";
@@ -68,12 +68,15 @@ test_compiler() {
 src_configure() {
        llvm_prepend_path "${LLVM_MAJOR}"
 
+       local install_prefix=${EPREFIX}
+       is_crosspkg && install_prefix+=/usr/${CTARGET}
+
        # note: we need to do this before multilib kicks in since it will
        # alter the CHOST
        local cxxabi cxxabi_incs
        if use libcxxabi; then
                cxxabi=system-libcxxabi
-               cxxabi_incs="${EPREFIX}/usr/include/c++/v1"
+               cxxabi_incs="${install_prefix}/usr/include/c++/v1"
        else
                local 
gcc_inc="${EPREFIX}/usr/lib/gcc/${CHOST}/$(gcc-fullversion)/include/g++-v$(gcc-major-version)"
                cxxabi=libsupc++
@@ -85,8 +88,8 @@ src_configure() {
 
 multilib_src_configure() {
        if use clang; then
-               local -x CC=${CHOST}-clang
-               local -x CXX=${CHOST}-clang++
+               local -x CC=${CTARGET}-clang
+               local -x CXX=${CTARGET}-clang++
                strip-unsupported-flags
        fi
 
@@ -94,18 +97,25 @@ multilib_src_configure() {
        local use_compiler_rt=OFF
        [[ $(tc-get-c-rtlib) == compiler-rt ]] && use_compiler_rt=ON
 
-       # bootstrap: cmake is unhappy if compiler can't link to stdlib
-       local nolib_flags=( -nodefaultlibs -lc )
-       if ! test_compiler; then
-               if test_compiler "${nolib_flags[@]}"; then
-                       local -x LDFLAGS="${LDFLAGS} ${nolib_flags[*]}"
-                       ewarn "${CXX} seems to lack runtime, trying with 
${nolib_flags[*]}"
+       # Scenarios to consider:
+       #
+       # 1. Compiler test works with the default flags.
+       # 2. There is a runtime library, but no stdlib. In that case, leave the
+       #    LDFLAGS untouched, since there is no self-dependency in libc++.
+       # 3. There is no runtime library nor stdlib. In that case, overwrite the
+       #    LDFLAGS.
+       local nostdlib_flags=( -nostdlib --rtlib=compiler-rt -lc )
+       local nort_flags=( -nodefaultlibs -lc )
+       if ! test_compiler && ! test_compiler "${nostdlib_flags[@]}"; then
+               if test_compiler "${nort_flags[@]}"; then
+                       local -x LDFLAGS="${LDFLAGS} ${nort_flags[*]}"
+                       ewarn "${CXX} seems to lack runtime, trying with 
${nort_flags[*]}"
                fi
        fi
 
        local libdir=$(get_libdir)
        local mycmakeargs=(
-               -DCMAKE_CXX_COMPILER_TARGET="${CHOST}"
+               -DCMAKE_CXX_COMPILER_TARGET="${CTARGET}"
                -DPython3_EXECUTABLE="${PYTHON}"
                -DLLVM_ENABLE_RUNTIMES=libcxx
                -DLLVM_INCLUDE_TESTS=OFF
@@ -125,7 +135,18 @@ multilib_src_configure() {
                # this is broken with standalone builds, and also meaningless
                -DLIBCXXABI_USE_LLVM_UNWINDER=OFF
        )
-
+       if is_crosspkg; then
+               # Needed to target built libc headers
+               local -x CFLAGS="${CFLAGS} -isystem 
${ESYSROOT}/usr/${CTARGET}/usr/include"
+               mycmakeargs+=(
+                       # Without this, the compiler will compile a test program
+                       # and fail due to no builtins.
+                       -DCMAKE_C_COMPILER_WORKS=1
+                       -DCMAKE_CXX_COMPILER_WORKS=1
+                       # Install inside the cross sysroot.
+                       -DCMAKE_INSTALL_PREFIX="${EPREFIX}/usr/${CTARGET}/usr"
+               )
+       fi
        if use test; then
                mycmakeargs+=(
                        -DLLVM_EXTERNAL_LIT="${EPREFIX}/usr/bin/lit"
@@ -159,6 +180,7 @@ multilib_src_install() {
        # since we've replaced libc++.{a,so} with ldscripts, now we have to
        # install the extra symlinks
        if [[ ${CHOST} != *-darwin* ]] ; then
+               is_crosspkg && into /usr/${CTARGET}
                dolib.so lib/libc++_shared.so
                use static-libs && dolib.a lib/libc++_static.a
        fi

Reply via email to