File PKGBUILD of Package gcc-git-god
# Maintainer: neycrol <330578697@qq.com>
pkgbase=gcc-git-god
pkgname=(
gcc-git-god
gcc-libs-git-god
lib32-gcc-libs-git-god
libgccjit-git-god
)
pkgver=0
pkgrel=3
pkgdesc="GCC Git toolchain and runtime libraries (God Mode, latest upstream)"
arch=('x86_64')
url="https://gcc.gnu.org/git/gcc.git"
license=('GPL3' 'LGPL' 'FDL' 'custom')
makedepends=(
git flex bison texinfo perl autoconf automake libtool make
gmp mpfr libmpc isl zlib zstd python
lib32-glibc-git
)
options=('!strip' '!debug' '!lto')
source=(
"gcc-git.tar.gz"
"gmp.tar.gz"
"mpfr.tar.gz"
"mpc.tar.gz"
"isl.tar.gz"
)
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
pkgver() {
local _date _rev _base _src
_date=$(date -u +%Y%m%d)
if [[ -f "${srcdir}/._servicedata" ]]; then
_rev=$(sed -n 's:.*<revision>\(.*\)</revision>.*:\1:p' "${srcdir}/._servicedata" | head -n1)
if [[ -z "${_rev}" ]]; then
_rev=$(sed -n 's:.*revision="\([0-9a-f]\+\)".*:\1:p' "${srcdir}/._servicedata" | head -n1)
fi
fi
_src=""
for d in "${srcdir}"/gcc*; do
if [[ -d "${d}" && -f "${d}/gcc/BASE-VER" ]]; then
_src="${d}"
break
fi
done
if [[ -n "${_src}" ]]; then
_base=$(cat "${_src}/gcc/BASE-VER")
fi
if [[ -n "${_rev}" ]]; then
echo "${_base:-0}.${_date}.g${_rev:0:8}"
else
echo "${_base:-0}.${_date}"
fi
}
_find_gcc_src() {
local d
for d in "${srcdir}"/gcc*; do
if [[ -d "${d}" && -f "${d}/configure" ]]; then
echo "${d}"
return 0
fi
done
return 1
}
_vendor_dep() {
local _src="$1" _name="$2" _tar="$3"
if [[ ! -d "${_src}/${_name}" && -f "${srcdir}/${_tar}" ]]; then
mkdir -p "${_src}/${_name}"
bsdtar -xf "${srcdir}/${_tar}" -C "${_src}/${_name}" --strip-components=1
fi
}
_copy_so_family() {
local _from="$1" _stem="$2" _to="$3"
local _f _hit=1
for _f in "${_from}/${_stem}.so"*; do
[[ -e "${_f}" ]] || continue
cp -a "${_f}" "${_to}/"
_hit=0
done
return ${_hit}
}
prepare() {
local _src
_src=$(_find_gcc_src) || {
echo "gcc sources not found"
return 1
}
_vendor_dep "${_src}" gmp "gmp.tar.gz"
_vendor_dep "${_src}" mpfr "mpfr.tar.gz"
_vendor_dep "${_src}" mpc "mpc.tar.gz"
_vendor_dep "${_src}" isl "isl.tar.gz"
# LTO can trip on a few runtime libs in trunk; keep selective fallback.
if [[ -f "${_src}/libatomic/Makefile.in" ]] && ! grep -q "fno-lto" "${_src}/libatomic/Makefile.in"; then
echo "LIBATOMIC_CFLAGS += -fno-lto" >> "${_src}/libatomic/Makefile.in"
fi
if [[ -f "${_src}/libgomp/Makefile.in" ]] && ! grep -q "fno-lto" "${_src}/libgomp/Makefile.in"; then
echo "LIBGOMP_CFLAGS += -fno-lto" >> "${_src}/libgomp/Makefile.in"
fi
echo "${_src}" > "${srcdir}/.gcc_srcdir"
rm -rf "${srcdir}/build" "${srcdir}/pkgroot"
mkdir -p "${srcdir}/build" "${srcdir}/pkgroot"
}
build() {
local _src
local _bootstrap_target="profiledbootstrap"
_src=$(cat "${srcdir}/.gcc_srcdir")
export CC=/usr/bin/gcc
export CXX=/usr/bin/g++
# Host build flags: keep conservative for configure/bootstrap reliability.
export CFLAGS="-O2 -pipe -fno-plt -fexceptions -fstack-clash-protection -fcf-protection -fno-semantic-interposition"
export CXXFLAGS="${CFLAGS}"
export LDFLAGS="-Wl,-O2,--sort-common,--as-needed,-z,relro,-z,now"
# Target runtime flags: aggressive but without data collection dependency.
export CFLAGS_FOR_TARGET="-O3 -march=alderlake -mtune=alderlake -pipe -fno-plt -fexceptions -fstack-clash-protection -fcf-protection -fno-semantic-interposition"
export CXXFLAGS_FOR_TARGET="${CFLAGS_FOR_TARGET}"
export LDFLAGS_FOR_TARGET="${LDFLAGS}"
export MAKEFLAGS="-j$(/usr/bin/getconf _NPROCESSORS_ONLN)"
cd "${srcdir}/build"
"${_src}/configure" \
--prefix=/opt/gcc-git-god \
--libdir=/opt/gcc-git-god/lib64 \
--libexecdir=/opt/gcc-git-god/lib \
--enable-languages=c,c++,fortran,jit,lto \
--enable-bootstrap \
--with-build-config=bootstrap-lto-lean \
--enable-multilib \
--enable-host-shared \
--enable-shared \
--enable-threads=posix \
--enable-__cxa_atexit \
--enable-libstdcxx-time \
--enable-lto \
--enable-plugin \
--enable-linker-build-id \
--enable-default-pie \
--enable-default-ssp \
--with-linker-hash-style=gnu \
--with-system-zlib \
--disable-libsanitizer \
--disable-werror
# Pure OBS internal data collection:
# prefer autoprofiledbootstrap when perf+create_gcov exist, else profiledbootstrap.
if command -v perf >/dev/null 2>&1 && command -v create_gcov >/dev/null 2>&1; then
_bootstrap_target="autoprofiledbootstrap"
fi
msg2 "Bootstrap optimization mode: ${_bootstrap_target}"
if ! make -O STAGE1_CFLAGS="-O2" BOOT_CFLAGS="$CFLAGS" BOOT_LDFLAGS="$LDFLAGS" \
LDFLAGS_FOR_TARGET="$LDFLAGS_FOR_TARGET" "${_bootstrap_target}"; then
if [[ "${_bootstrap_target}" == "autoprofiledbootstrap" ]]; then
echo "autoprofiledbootstrap failed, fallback to profiledbootstrap"
make -O STAGE1_CFLAGS="-O2" BOOT_CFLAGS="$CFLAGS" BOOT_LDFLAGS="$LDFLAGS" \
LDFLAGS_FOR_TARGET="$LDFLAGS_FOR_TARGET" profiledbootstrap || \
make -O STAGE1_CFLAGS="-O2" BOOT_CFLAGS="$CFLAGS" BOOT_LDFLAGS="$LDFLAGS" \
LDFLAGS_FOR_TARGET="$LDFLAGS_FOR_TARGET" bootstrap
else
echo "profiledbootstrap failed, fallback to bootstrap"
make -O STAGE1_CFLAGS="-O2" BOOT_CFLAGS="$CFLAGS" BOOT_LDFLAGS="$LDFLAGS" \
LDFLAGS_FOR_TARGET="$LDFLAGS_FOR_TARGET" bootstrap
fi
fi
make DESTDIR="${srcdir}/pkgroot" install
}
package_gcc-git-god() {
pkgdesc="GCC Git compiler suite (installed under /opt)"
depends=("gcc-libs-git-god=${pkgver}-${pkgrel}" binutils gmp mpfr libmpc isl zlib zstd)
provides=('gcc' "gcc=${pkgver}-${pkgrel}")
conflicts=('gcc')
replaces=('gcc')
install -dm755 "${pkgdir}/opt"
cp -a "${srcdir}/pkgroot/opt/gcc-git-god" "${pkgdir}/opt/"
install -dm755 "${pkgdir}/usr/bin"
local _tool
local _target
local _compat_tools=(
gcc g++ c++ cc cpp
gcc-ar gcc-nm gcc-ranlib
gcov gcov-dump gcov-tool
gfortran lto-dump
)
for _tool in "${_compat_tools[@]}"; do
_target="${_tool}"
case "${_tool}" in
cc) _target="gcc" ;;
c++) _target="g++" ;;
esac
cat > "${pkgdir}/usr/bin/${_tool}" <<EOS
#!/bin/sh
exec /opt/gcc-git-god/bin/${_target} "\$@"
EOS
chmod 755 "${pkgdir}/usr/bin/${_tool}"
done
# Keep explicit custom entry points for manual selection.
ln -sf gcc "${pkgdir}/usr/bin/gcc-git-god"
ln -sf g++ "${pkgdir}/usr/bin/g++-git-god"
# Rust and some build systems probe target-prefixed tool names directly.
local _triplet="x86_64-pc-linux-gnu"
local _prefixed_tools=(
"${_triplet}-gcc"
"${_triplet}-g++"
"${_triplet}-cpp"
"${_triplet}-gcc-ar"
"${_triplet}-gcc-nm"
"${_triplet}-gcc-ranlib"
)
for _tool in "${_prefixed_tools[@]}"; do
if [[ -x "${pkgdir}/opt/gcc-git-god/bin/${_tool}" ]]; then
ln -sf "/opt/gcc-git-god/bin/${_tool}" "${pkgdir}/usr/bin/${_tool}"
fi
done
# Keep binutils LTO integration working after replacing the gcc package.
local _lto_plugin
_lto_plugin=$(find "${pkgdir}/opt/gcc-git-god" -type f -name liblto_plugin.so | head -n1 || true)
if [[ -n "${_lto_plugin}" ]]; then
install -dm755 "${pkgdir}/usr/lib/bfd-plugins"
ln -sf "/${_lto_plugin#${pkgdir}/}" "${pkgdir}/usr/lib/bfd-plugins/liblto_plugin.so"
fi
# Do not provide /usr/lib/gcc compatibility symlink here.
# It conflicts with existing directory ownership from toolchains
# such as mingw-w64-gcc and causes pacman file conflicts.
}
package_gcc-libs-git-god() {
pkgdesc="Runtime libraries shipped by GCC Git (system replacement)"
depends=('glibc>=2.27')
provides=(
'gcc-libs' "gcc-libs=${pkgver}-${pkgrel}"
'libasan' 'libatomic' 'libgfortran' 'libgcc' 'libgomp' 'liblsan' 'libobjc' 'libquadmath' 'libstdc++' 'libtsan' 'libubsan'
'libgfortran.so=5-64' 'libgcc_s.so=1-64' 'libstdc++.so=6-64'
'libubsan.so' 'libasan.so' 'libtsan.so' 'liblsan.so'
)
conflicts=(
'gcc-libs'
'libasan' 'libatomic' 'libgfortran' 'libgcc' 'libgomp' 'liblsan' 'libobjc' 'libquadmath' 'libstdc++' 'libtsan' 'libubsan'
)
replaces=(
'gcc-libs'
'libasan' 'libatomic' 'libgfortran' 'libgcc' 'libgomp' 'liblsan' 'libobjc' 'libquadmath' 'libstdc++' 'libtsan' 'libubsan'
)
options=('!emptydirs' '!strip')
local _src _lib64
_src=$(cat "${srcdir}/.gcc_srcdir")
_lib64="${srcdir}/pkgroot/opt/gcc-git-god/lib64"
install -dm755 "${pkgdir}/usr/lib"
local _libs=(
libasan libatomic libgcc_s libgfortran libgomp
libitm liblsan libquadmath libstdc++ libtsan libubsan
)
local _l
for _l in "${_libs[@]}"; do
_copy_so_family "${_lib64}" "${_l}" "${pkgdir}/usr/lib" || true
done
for _l in libstdc++ libgcc_s libgomp libatomic; do
if ! compgen -G "${pkgdir}/usr/lib/${_l}.so*" > /dev/null; then
echo "missing required runtime library family: ${_l}"
return 1
fi
done
# Runtime Library Exception
install -Dm644 "${_src}/COPYING.RUNTIME" \
"${pkgdir}/usr/share/licenses/gcc-libs-git-god/RUNTIME.LIBRARY.EXCEPTION"
# Optional runtime info pages
install -dm755 "${pkgdir}/usr/share/info"
for _info in libgomp.info.gz libitm.info.gz libquadmath.info.gz; do
if [[ -f "${srcdir}/pkgroot/opt/gcc-git-god/share/info/${_info}" ]]; then
cp -a "${srcdir}/pkgroot/opt/gcc-git-god/share/info/${_info}" "${pkgdir}/usr/share/info/"
fi
done
install -dm755 "${pkgdir}/usr/share/locale"
if [[ -d "${srcdir}/pkgroot/opt/gcc-git-god/share/locale" ]]; then
cp -a "${srcdir}/pkgroot/opt/gcc-git-god/share/locale/." "${pkgdir}/usr/share/locale/"
fi
}
package_lib32-gcc-libs-git-god() {
pkgdesc='32-bit runtime libraries shipped by GCC Git (system replacement)'
depends=('lib32-glibc>=2.27')
provides=('lib32-gcc-libs' "lib32-gcc-libs=${pkgver}-${pkgrel}" 'libgfortran.so' 'libubsan.so' 'libasan.so')
conflicts=('lib32-gcc-libs')
replaces=('lib32-gcc-libs')
options=('!emptydirs' '!strip')
local _src _lib32
_src=$(cat "${srcdir}/.gcc_srcdir")
_lib32="${srcdir}/pkgroot/opt/gcc-git-god/lib32"
install -dm755 "${pkgdir}/usr/lib32"
local _libs=(
libasan libatomic libgcc_s libgfortran libgomp
libitm libquadmath libstdc++ libubsan
)
local _l
for _l in "${_libs[@]}"; do
_copy_so_family "${_lib32}" "${_l}" "${pkgdir}/usr/lib32" || true
done
for _l in libstdc++ libgcc_s libgomp libatomic; do
if ! compgen -G "${pkgdir}/usr/lib32/${_l}.so*" > /dev/null; then
echo "missing required 32-bit runtime library family: ${_l}"
return 1
fi
done
install -Dm644 "${_src}/COPYING.RUNTIME" \
"${pkgdir}/usr/share/licenses/lib32-gcc-libs-git-god/RUNTIME.LIBRARY.EXCEPTION"
}
package_libgccjit-git-god() {
pkgdesc="Just-In-Time Compilation library with GCC Git backend"
depends=("gcc-libs-git-god=${pkgver}-${pkgrel}" 'isl')
provides=('libgccjit' "libgccjit=${pkgver}-${pkgrel}")
conflicts=('libgccjit')
replaces=('libgccjit')
local _lib64
_lib64="${srcdir}/pkgroot/opt/gcc-git-god/lib64"
install -dm755 "${pkgdir}/usr/lib" "${pkgdir}/usr/include"
_copy_so_family "${_lib64}" "libgccjit" "${pkgdir}/usr/lib" || {
echo "libgccjit shared library not found"
return 1
}
if [[ -f "${srcdir}/pkgroot/opt/gcc-git-god/include/libgccjit.h" ]]; then
cp -a "${srcdir}/pkgroot/opt/gcc-git-god/include/libgccjit.h" "${pkgdir}/usr/include/"
fi
if [[ -f "${srcdir}/pkgroot/opt/gcc-git-god/include/libgccjit++.h" ]]; then
cp -a "${srcdir}/pkgroot/opt/gcc-git-god/include/libgccjit++.h" "${pkgdir}/usr/include/"
fi
install -dm755 "${pkgdir}/usr/share/info"
if [[ -f "${srcdir}/pkgroot/opt/gcc-git-god/share/info/libgccjit.info.gz" ]]; then
cp -a "${srcdir}/pkgroot/opt/gcc-git-god/share/info/libgccjit.info.gz" "${pkgdir}/usr/share/info/"
fi
local _src
_src=$(cat "${srcdir}/.gcc_srcdir")
install -Dm644 "${_src}/COPYING.RUNTIME" \
"${pkgdir}/usr/share/licenses/libgccjit-git-god/RUNTIME.LIBRARY.EXCEPTION"
}