template (6526B)
1 # Template file for 'libstdc++' 2 pkgname=libstdc++ 3 version=14.2.0 4 revision=0 5 short_desc="GNU Standard C++ library and GCC unwinder runtime" 6 maintainer="finwo <finwo@pm.me>" 7 license="GPL-3.0-or-later WITH GCC-exception-3.1" 8 homepage="https://gcc.gnu.org/" 9 # GCC plus its pinned in-tree prerequisites. Only the first distfile is 10 # extracted by the driver; do_configure places the rest (see below). 11 # Prerequisite versions are GCC 14.2.0's own pins, taken verbatim from 12 # contrib/download_prerequisites -- not chosen by us. 13 distfiles="https://ftp.gnu.org/gnu/gcc/gcc-${version}/gcc-${version}.tar.xz 14 https://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.2.1.tar.bz2 15 https://gcc.gnu.org/pub/gcc/infrastructure/mpfr-4.1.0.tar.bz2 16 https://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.2.1.tar.gz" 17 checksum="a7b39bc69cbf9e25826c5a60ab26477001f7c08d85cec04bc0e29cabed6f3cc9 18 eae9326beb4158c386e39a356818031bd28f3124cf915f8c5b1dc4c7a36b4d7c 19 feced2d430dd5a97805fa289fed3fc8ff2b094c02d05287fd6133e7f1f0ec926 20 17503d2c395dfcf106b622dc142683c1199431d095367c6aacba6eec30340459" 21 depends="glibc busybox" 22 23 # Notes: 24 # - Why: sgdisk (gptfdisk) and smartctl (smartmontools) are C++, and UNOS 25 # shipped no C++ runtime at all. Static-linking the runtime into each binary 26 # was the alternative; packaging it keeps packages/README.md's shared-only 27 # rule intact and amortises across any future C++ package. 28 # - We build GCC, but we ship only libstdc++.so and libgcc_s.so. No compiler, 29 # no headers, no libsupc++.a. GCC is a means to the runtime here, nothing 30 # more; do_install takes exactly two .so trees out of the tree. 31 # - ABI: host g++ 14.2.1 emits at most GLIBCXX_3.4.33, which GCC 14.2.0's 32 # libstdc++ provides. Bumping this package below the host compiler version 33 # would break C++ packages at link time -- the assert in do_install guards it. 34 # - --disable-bootstrap: a 3-stage bootstrap builds the compiler three times to 35 # prove it can rebuild itself. We are not shipping the compiler, so stage1 is 36 # sufficient and roughly a third of the build time. 37 # - gmp/mpfr/mpc are build-time only and never packaged. GCC builds them 38 # in-tree when their source dirs are present, which is the upstream-supported 39 # way and avoids three packages we would otherwise never install. 40 41 do_configure() { 42 cd "${WRKSRC}" 43 44 # In-tree prerequisites: GCC's build system picks these up automatically 45 # when unpacked under the source root with their version suffix stripped. 46 for dep in gmp-6.2.1 mpfr-4.1.0 mpc-1.2.1; do 47 name=${dep%%-*} 48 [ -d "${name}" ] && continue 49 case "${dep}" in 50 *.gz|mpc-*) tar -xf "${SRCDEST}/${dep}.tar.gz" -C . ;; 51 *) tar -xf "${SRCDEST}/${dep}.tar.bz2" -C . ;; 52 esac 53 mv "${dep}" "${name}" || die "libstdc++: could not stage ${name}" 54 done 55 for name in gmp mpfr mpc; do 56 [ -d "${name}" ] || die "libstdc++: missing in-tree ${name}" 57 done 58 59 # Target libraries ignore --libdir: their location comes from the multilib 60 # osdir, which on x86_64 defaults to ../lib64 even with --disable-multilib. 61 # UNOS is /usr/lib throughout (glibc is built --libdir=/usr/lib), so 62 # retarget m64 the way distros do rather than shipping a stray /usr/lib64. 63 sed -i 's|m64=../lib64|m64=../lib|' gcc/config/i386/t-linux64 \ 64 || die "libstdc++: could not retarget MULTILIB_OSDIRNAMES" 65 grep -q 'm64=../lib$' gcc/config/i386/t-linux64 \ 66 || grep -q 'm64=../lib[^6]' gcc/config/i386/t-linux64 \ 67 || die "libstdc++: MULTILIB_OSDIRNAMES retarget did not apply" 68 69 # GCC refuses to configure in its own source directory. 70 mkdir -p "${WORK}/gccbuild" 71 cd "${WORK}/gccbuild" 72 "${WRKSRC}/configure" \ 73 --prefix=/usr \ 74 --libdir=/usr/lib \ 75 --disable-bootstrap \ 76 --enable-languages=c++ \ 77 --enable-shared \ 78 --enable-threads=posix \ 79 --enable-__cxa_atexit \ 80 --enable-clocale=gnu \ 81 --disable-multilib \ 82 --disable-nls \ 83 --disable-libstdcxx-pch \ 84 --disable-werror \ 85 --disable-libsanitizer \ 86 --disable-libssp \ 87 --disable-libquadmath \ 88 --disable-libvtv 89 } 90 91 do_build() { 92 cd "${WORK}/gccbuild" 93 # Only the two target runtimes. Building `all` would produce a full 94 # compiler we then throw away. 95 make -j"$(nproc)" all-target-libgcc 96 make -j"$(nproc)" all-target-libstdc++-v3 97 } 98 99 do_install() { 100 cd "${WORK}/gccbuild" 101 make install-target-libgcc DESTDIR="${DESTDIR}" 102 make install-target-libstdc++-v3 DESTDIR="${DESTDIR}" 103 104 # Sysroot seed so gptfdisk/smartmontools link against our runtime. 105 make install-target-libgcc DESTDIR="${SYSROOT}" 106 make install-target-libstdc++-v3 DESTDIR="${SYSROOT}" 107 108 # Ship the runtime only. Everything below is compiler-side: static 109 # archives, linker scripts, headers and GCC's private lib tree. 110 rm -rf "${DESTDIR}/usr/lib/gcc" "${DESTDIR}/usr/include" 111 rm -rf "${DESTDIR}/usr/share" 112 rm -f "${DESTDIR}"/usr/lib/*.a "${DESTDIR}"/usr/lib/*.la 113 rm -f "${DESTDIR}"/usr/lib/*.py 114 # libstdc++ ships GDB pretty-printers as .py; Python is banned in the 115 # rootfs and they are debugger-side anyway. 116 find "${DESTDIR}" -name '*-gdb.py' -delete 2>/dev/null || true 117 118 # GCC builds target libs with -g; unstripped libstdc++.so is ~20MB against 119 # ~2.5MB stripped, which is not a reasonable thing to put on a switch. 120 # --strip-debug (not --strip-unneeded) is deliberate: it drops debug info 121 # only and cannot touch the dynamic symbol table the loader resolves. 122 for so in "${DESTDIR}"/usr/lib/*.so.*; do 123 [ -f "${so}" ] || continue 124 strip --strip-debug "${so}" || die "libstdc++: strip failed on ${so}" 125 done 126 127 [ -e "${DESTDIR}/usr/lib/libstdc++.so.6" ] || die "libstdc++: no libstdc++.so.6" 128 [ -e "${DESTDIR}/usr/lib/libgcc_s.so.1" ] || die "libstdc++: no libgcc_s.so.1" 129 # Catch a silent regression of the MULTILIB_OSDIRNAMES retarget above. 130 [ ! -d "${DESTDIR}/usr/lib64" ] || die "libstdc++: stray /usr/lib64 (multilib osdir not retargeted)" 131 132 # ABI floor: our runtime must be at least what the host compiler emits, 133 # or every C++ binary we build will fail to resolve symbols on the switch. 134 have=$(strings "${DESTDIR}/usr/lib/libstdc++.so.6"* 2>/dev/null \ 135 | grep -oE 'GLIBCXX_3\.4\.[0-9]+' | sort -V | tail -1) 136 need=$(strings /usr/lib/libstdc++.so.6 2>/dev/null \ 137 | grep -oE 'GLIBCXX_3\.4\.[0-9]+' | sort -V | tail -1) 138 [ -n "${have}" ] || die "libstdc++: could not read our GLIBCXX versions" 139 if [ -n "${need}" ] && [ "$(printf '%s\n%s\n' "${need}" "${have}" | sort -V | tail -1)" != "${have}" ]; then 140 die "libstdc++: ours (${have}) is older than the host compiler needs (${need})" 141 fi 142 msg "libstdc++: ABI ${have} (host compiler needs ${need:-unknown})" 143 }