From 6319cbe1d15c3831bd4a2e5b52c4367abc68747d Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Fri, 18 Oct 2024 01:04:19 +0100 Subject: [PATCH] Support clang on macos prefix Bug: https://bugs.gentoo.org/758167 Signed-off-by: Alexey Sokolov --- scripts/bootstrap-prefix.sh | 163 ++++++++++++++++++++++++++++-------- 1 file changed, 128 insertions(+), 35 deletions(-) diff --git a/scripts/bootstrap-prefix.sh b/scripts/bootstrap-prefix.sh index ac38ff7b9f..551184822b 100755 --- a/scripts/bootstrap-prefix.sh +++ b/scripts/bootstrap-prefix.sh @@ -220,18 +220,15 @@ configure_toolchain() { # this is Clang, recent enough to compile recent clang compiler_stage1+=" ${llvm_deps} - sys-libs/libcxxabi - sys-libs/libcxx + sys-libs/compiler-rt sys-devel/llvm + sys-devel/lld + sys-devel/clang-common sys-devel/clang " CC=clang CXX=clang++ - # avoid going through hoops and deps for - # binutils-apple, rely on the host-installed ld to - # build a compiler, we'll pull in binutils-apple - # from system set - linker=sys-devel/native-cctools + linker=sys-devel/lld ;; *) eerror "unknown/unsupported compiler" @@ -242,10 +239,15 @@ configure_toolchain() { compiler=" dev-libs/libffi ${llvm_deps} + sys-libs/compiler-rt sys-libs/libcxxabi sys-libs/libcxx sys-devel/llvm - sys-devel/clang" + sys-devel/lld + sys-libs/llvm-libunwind + sys-devel/clang-common + sys-devel/clang + " ;; *-linux*) is-rap && einfo "Triggering Linux RAP bootstrap" @@ -454,9 +456,13 @@ bootstrap_profile() { ;; esac - if [[ ${DARWIN_USE_GCC} == 1 ]] ; then - # amend profile, to use gcc one - profile="${profile}/gcc" + if [[ ${CHOST} == *-darwin* ]] ; then + if [[ ${DARWIN_USE_GCC} == 1 ]] ; then + # amend profile, to use gcc one + profile="${profile}/gcc" + elif [[ "${STAGE}" != stage2 ]]; then + profile="${profile}/clang" + fi fi [[ -n ${PROFILE_BASE}${PROFILE_VARIANT} ]] && @@ -1176,18 +1182,17 @@ bootstrap_cmake_core() { # we need sysroot crap to build cmake itself, but it makes trouble # later on, so kill it in the installed version - ver=${A%-*} ; ver=${ver%.*} sed -i -e '/cmake_gnu_set_sysroot_flag/d' \ - "${ROOT}/tmp/usr/share/${ver}/Modules/Platform"/Apple-GNU-*.cmake || die + "${ROOT}"/tmp/usr/share/cmake*/Modules/Platform/Apple-GNU-*.cmake || die # disable isysroot usage with clang as well sed -i -e '/_SYSROOT_FLAG/d' \ - "${ROOT}/tmp/usr/share/${ver}/Modules/Platform"/Apple-Clang.cmake || die + "${ROOT}"/tmp/usr/share/cmake*/Modules/Platform/Apple-Clang.cmake || die einfo "${A%.tar.*} bootstrapped" } bootstrap_cmake() { - bootstrap_cmake_core 3.16.5 || bootstrap_cmake_core 3.0.2 + bootstrap_cmake_core 3.20.6 || bootstrap_cmake_core 3.16.5 || bootstrap_cmake_core 3.0.2 } bootstrap_zlib_core() { @@ -1465,7 +1470,7 @@ bootstrap_stage1() { [[ -e ${ROOT}/tmp/${x} ]] || ( cd "${ROOT}"/tmp && ln -s usr/${x} ) done - configure_toolchain + STAGE=stage1 configure_toolchain || return 1 export CC CXX # default: empty = NO @@ -1753,7 +1758,7 @@ bootstrap_stage1() { [[ -e ${ROOT}/tmp/etc/portage/make.profile ]] || \ ( "${CP}" -dpR "${ROOT}"/etc/portage "${ROOT}"/tmp/etc && \ rm -f "${ROOT}"/tmp/etc/portage/make.profile && \ - (ROOT="${ROOT}"/tmp PREFIX_DISABLE_RAP=yes bootstrap_profile) ) || return 1 + (ROOT="${ROOT}"/tmp PREFIX_DISABLE_RAP=yes STAGE=stage2 bootstrap_profile) ) || return 1 # setup portage [[ -e ${ROOT}/tmp/usr/bin/emerge ]] || (bootstrap_portage) || return 1 @@ -1818,7 +1823,6 @@ do_emerge_pkgs() { "-berkdb" "-fortran" # gcc "-gdbm" - "-libcxx" "-nls" "-pcre" "-python" @@ -1830,6 +1834,22 @@ do_emerge_pkgs() { "clang" "internal-glib" ) + if [[ ${CHOST}:${DARWIN_USE_GCC} == *-darwin*:0 ]] ; then + # darwin+clang + myuse+=( + "-binutils-plugin" + "default-compiler-rt" + "default-libcxx" + "default-lld" + ) + else + myuse+=( "-libcxx" ) + fi + local skip_llvm_pkg_setup="" + if [[ ${STAGE} == stage2 ]] ; then + myuse+=( "bootstrap-prefix" ) + skip_llvm_pkg_setup="yes" + fi local override_make_conf_dir="${PORTAGE_OVERRIDE_EPREFIX}${MAKE_CONF_DIR#"${ROOT}"}" if [[ " ${USE} " == *" prefix-stack "* ]] && @@ -1891,6 +1911,7 @@ do_emerge_pkgs() { PORTAGE_SYNC_STALE=0 \ FEATURES="-news ${FEATURES}" \ USE="${myuse[*]}" \ + LLVM_ECLASS_SKIP_PKG_SETUP="${skip_llvm_pkg_setup}" \ "${ROOT}"/tmp/bin/python \ "${ROOT}"/tmp/usr/bin/emerge "${eopts[@]}" "${pkg}" ) || return 1 @@ -1907,11 +1928,29 @@ bootstrap_stage2() { # Find out what toolchain packages we need, and configure LDFLAGS # and friends. - configure_toolchain || return 1 + STAGE=stage2 configure_toolchain || return 1 configure_cflags || return 1 export CONFIG_SHELL="${ROOT}"/tmp/bin/bash export CC CXX + # provide active SDK link on Darwin + if [[ ${CHOST} == *-darwin* ]] ; then + rm -f "${ROOT}"/tmp/MacOSX.sdk + ( cd "${ROOT}"/tmp && ln -s ../MacOSX.sdk MacOSX.sdk ) + if [[ ${DARWIN_USE_GCC} == 0 ]] ; then + # Until proper clang is installed, just redirect calls to it to the + # system's one. Libtool is here because its path is passed to the + # compiler-rt and llvm's ebuilds. + for bin in libtool clang clang++ ; do + { + echo "#!${ROOT}/tmp/bin/sh" + echo "exec ${bin}"' "$@"' + } > "${ROOT}/tmp/usr/bin/${CHOST}-${bin}" + chmod +x "${ROOT}/tmp/usr/bin/${CHOST}-${bin}" + done + fi + fi + emerge_pkgs() { EPREFIX="${ROOT}"/tmp \ STAGE=stage2 \ @@ -2012,12 +2051,6 @@ bootstrap_stage2() { sys-devel/binutils-config ) - # provide active SDK link on Darwin - if [[ ${CHOST} == *-darwin* ]] ; then - rm -f "${ROOT}"/tmp/MacOSX.sdk - ( cd "${ROOT}"/tmp && ln -s ../MacOSX.sdk MacOSX.sdk ) - fi - # cmake has some external dependencies which require autoconf, etc. # unless we only build the buildtool, bug #603012 echo "dev-build/cmake -server" >> "${ROOT}"/tmp/etc/portage/package.use @@ -2036,11 +2069,13 @@ bootstrap_stage2() { emerge_pkgs --nodeps "${pkgs[@]}" || return 1 - # Debian multiarch supported by RAP needs ld to support sysroot. - for pkg in ${linker} ; do - EXTRA_ECONF=$(rapx --with-sysroot=/) \ - emerge_pkgs --nodeps "${pkg}" || return 1 - done + if [[ ${CHOST}:${DARWIN_USE_GCC} != *-darwin*:0 ]] ; then + # Debian multiarch supported by RAP needs ld to support sysroot. + for pkg in ${linker} ; do + EXTRA_ECONF=$(rapx --with-sysroot=/) \ + emerge_pkgs --nodeps "${pkg}" || return 1 + done + fi # GCC doesn't respect CPPFLAGS because of its own meddling as well # as toolchain.eclass, so provide a wrapper here to force just @@ -2080,6 +2115,12 @@ bootstrap_stage2() { [[ -x ${ROOT}/tmp/usr/bin/clang++ ]] && CXX=clang++ fi done + if [[ ${CHOST}:${DARWIN_USE_GCC} == *-darwin*:0 ]] ; then + # Stop using host's compilers, but still need 'libtool' in PATH. + rm ${ROOT}/tmp/usr/bin/${CHOST}-{libtool,clang,clang++} + mkdir -p ${ROOT}/usr/bin + ln -s ${ROOT}/tmp/usr/lib/llvm/*/bin/llvm-libtool-darwin ${ROOT}/usr/bin/libtool + fi if [[ ${compiler_type} == clang ]] ; then # We use Clang as our toolchain compiler, so we need to make @@ -2088,6 +2129,8 @@ bootstrap_stage2() { { echo echo "# System compiler on $(uname) Prefix is Clang, do not remove this" + echo "AS=\"${CHOST}-clang -c\"" + echo "CPP=${CHOST}-clang-cpp" echo "CC=${CHOST}-clang" echo "CXX=${CHOST}-clang++" echo "OBJC=${CHOST}-clang" @@ -2151,7 +2194,7 @@ bootstrap_stage3() { # they stop mucking up builds. rm -f "${ROOT}"/tmp/usr/local/bin/{,my,${CHOST}-}{gcc,g++} - configure_toolchain || return 1 + STAGE=stage3 configure_toolchain || return 1 if [[ ${compiler_type} == clang ]] ; then if ! type -P clang > /dev/null ; then @@ -2204,7 +2247,6 @@ bootstrap_stage3() { # (CBUILD, BDEPEND) and with the system being built # (CHOST, RDEPEND). To correctly bootstrap stage3, # PORTAGE_OVERRIDE_EPREFIX as BROOT is needed. - PREROOTPATH="${ROOT}"$(echo /{,tmp/}{usr/,}{,lib/llvm/{12,11,10}/}{s,}bin | sed "s, ,:${ROOT},g") \ EPREFIX="${ROOT}" PORTAGE_TMPDIR="${PORTAGE_TMPDIR}" \ EMERGE_LOG_DIR="${ROOT}"/var/log \ STAGE=stage3 \ @@ -2356,8 +2398,10 @@ bootstrap_stage3() { sys-devel/flex sys-devel/binutils-config sys-libs/zlib - "${linker_pkgs[@]}" ) + if [[ ${CHOST}:${DARWIN_USE_GCC} != *-darwin*:0 ]] ; then + pkgs+=( "${linker_pkgs[@]}" ) + fi pre_emerge_pkgs --nodeps "${pkgs[@]}" || return 1 fi @@ -2387,6 +2431,30 @@ bootstrap_stage3() { PYTHON_COMPAT_OVERRIDE="python$(python_ver)" \ pre_emerge_pkgs --nodeps "${compiler_pkgs[@]}" || return 1 + if [[ ${CHOST}:${DARWIN_USE_GCC} == *-darwin*:0 ]] ; then + # At this point our libc++abi.dylib is dynamically linked to + # /usr/lib/libc++abi.dylib. That causes issues with perl later. Force + # rebuild of sys-libs/libcxxabi to break this link. + rm -Rf "${ROOT}/var/db/pkg/sys-libs/libcxxabi"* + PYTHON_COMPAT_OVERRIDE=python$(python_ver) \ + pre_emerge_pkgs --nodeps "sys-libs/libcxxabi" || return 1 + + # Make ${CHOST}-libtool (used by compiler-rt's and llvm's ebuild) to + # point at the correct libtool in stage3. Resolve it in runtime, to + # support llvm version upgrades. + rm -f ${ROOT}/usr/bin/${CHOST}-libtool + { + echo "#!${ROOT}/bin/sh" + echo 'exec llvm-libtool-darwin "$@"' + } > "${ROOT}"/usr/bin/${CHOST}-${bin} + + # Now clang is ready, can use it instead of /usr/bin/gcc + # TODO: perhaps symlink the whole etc/portage instead? + ln -s -f "${ROOT}/etc/portage/make.profile" "${ROOT}/tmp/etc/portage/make.profile" + cp "${ROOT}/etc/portage/make.conf/0100_bootstrap_prefix_clang.conf" \ + "${ROOT}/tmp/etc/portage/make.conf/" + fi + # Undo libgcc_s.so path of stage2 # Now we have the compiler right there unset CC CXX CPPFLAGS LDFLAGS @@ -2403,8 +2471,33 @@ bootstrap_stage3() { ln -s bash "${ROOT}"/bin/sh fi - # Start using apps from the final destination Prefix - export PREROOTPATH="${ROOT}/usr/bin:${ROOT}/bin" + # Start using apps from new target + cat > "${ROOT}"/tmp/etc/env.d/10stage3 <<-EOF + PATH="${ROOT}/usr/bin:${ROOT}/bin" + EOF + if [[ ${compiler_type} == clang ]] ; then + if [[ ! -e "${ROOT}"/tmp/etc/env.d/11stage3-llvm ]]; then + ln -s "${ROOT}"/etc/env.d/60llvm-* "${ROOT}"/tmp/etc/env.d/11stage3-llvm + fi + # Prevent usage of AppleClang aka gcc for bad packages which ignore $CC + if [[ ! -e "${ROOT}"/usr/bin/gcc ]]; then + echo "#!${ROOT}/bin/bash" > "${ROOT}"/usr/bin/gcc + echo "false ${CHOST}-clang \"\$@\"" >> "${ROOT}"/usr/bin/gcc + fi + if [[ ! -e "${ROOT}"/usr/bin/g++ ]]; then + echo "#!${ROOT}/bin/bash" > "${ROOT}"/usr/bin/g++ + echo "false ${CHOST}-clang++ \"\$@\"" >> "${ROOT}"/usr/bin/g++ + fi + chmod +x "${ROOT}"/usr/bin/{gcc,g++} + if [[ ${CHOST} == *-darwin* ]]; then + if [[ ! -e "${ROOT}"/usr/bin/ld ]]; then + echo "#!${ROOT}/bin/bash" > "${ROOT}"/usr/bin/ld + echo "false ld64.lld \"\$@\"" >> "${ROOT}"/usr/bin/ld + fi + chmod +x "${ROOT}"/usr/bin/ld + fi + fi + "${ROOT}"/tmp/usr/sbin/env-update # Get a sane bash, overwriting tmp symlinks pre_emerge_pkgs "" "app-shells/bash" || return 1