Skip to content

Instantly share code, notes, and snippets.

@phush0
Forked from lazerl0rd/20-makepkg.hook
Created July 21, 2022 13:50
Show Gist options
  • Save phush0/3a22b1ed9086b127b36ec0f26dfdbda8 to your computer and use it in GitHub Desktop.
Save phush0/3a22b1ed9086b127b36ec0f26dfdbda8 to your computer and use it in GitHub Desktop.
A Makepkg configuration for Arch Linux that utilises LLVM and takes optimisation up to eleven.
[Trigger]
Operation = Install
Operation = Upgrade
Type = Path
Target = etc/makepkg.conf
Target = usr/share/makepkg/buildenv/lto.sh
Target = usr/share/makepkg/executable/strip.sh
[Action]
Description = Modifying the Makepkg configuration...
When = PostTransaction
Exec = /usr/bin/bash -c 'curl "https://gist.githubusercontent.com/lazerl0rd/60ba5b662d3d7afe1e279d6c599f28f2/raw/makepkg.conf" -o "/etc/makepkg.conf"; curl "https://gist.githubusercontent.com/lazerl0rd/60ba5b662d3d7afe1e279d6c599f28f2/raw/lto.sh" -o "/usr/share/makepkg/buildenv/lto.sh"; curl "https://gist.githubusercontent.com/lazerl0rd/60ba5b662d3d7afe1e279d6c599f28f2/raw/strip.sh" -o "/usr/share/makepkg/executable/strip.sh"'
Depends = bash
Depends = curl
Depends = pacman
#! /usr/bin/bash
#
# lto.sh - Specify flags for building a package with link-time
# optimisation.
#
# Copyright (c) 2021 Pacman Development Team <pacman-dev@archlinux.org>
# Copyright (c) 2021 Diab Neiroukh <lazerl0rd@thezest.dev>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses>.
#
[[ -n "$LIBMAKEPKG_BUILDENV_LTO_SH" ]] && return
LIBMAKEPKG_BUILDENV_LTO_SH="1"
LIBRARY=${LIBRARY:-'/usr/share/makepkg'}
source "$LIBRARY/util/option.sh"
build_options+=('lto')
buildenv_functions+=('buildenv_lto')
buildenv_lto()
{
if check_option "lto" "y"; then
if [[ $CC == clang ]] && [[ $CXX == clang++ ]]; then
CFLAGS="$CFLAGS -flto=thin"
CXXFLAGS="$CXXFLAGS -flto=thin"
RUSTFLAGS="$RUSTFLAGS -C link-arg=-flto=thin -C linker-plugin-lto"
else
CFLAGS="$CFLAGS -flto"
CXXFLAGS="$CXXFLAGS -flto"
# linker-plugin-lto only works if all the object files being linked
# were created by LLVM. As such, we rely on rustc performing LTO
# when using GCC.
RUSTFLAGS="$RUSTFLAGS -C lto"
fi
fi
}
#! /hint/bash
DLAGENTS=(
"file::/usr/bin/curl -gqC - -o %o %u"
"ftp::/usr/bin/aria2c -UWget -s4 %u -o %o"
"http::/usr/bin/aria2c -UWget -s4 %u -o %o"
"https::/usr/bin/aria2c -UWget -s4 %u -o %o"
"rsync::/usr/bin/rsync --no-motd -z %u %o"
"scp::/usr/bin/scp -C %u %o"
)
VCSCLIENTS=(
"bzr::bzr"
"git::git"
"hg::mercurial"
"svn::subversion"
)
CARCH="x86_64"
CHOST="x86_64-pc-linux-gnu"
CFLAGS="-fcf-protection -fdata-sections -fexceptions -ffunction-sections -fno-plt -fstack-clash-protection -O3 -pipe -Werror=format-security -Wformat -Wp,-D_FORTIFY_SOURCE=2,-D_GLIBCXX_ASSERTIONS"
CXXFLAGS="-fcf-protection -fdata-sections -fexceptions -ffunction-sections -fno-plt -fstack-clash-protection -O3 -pipe -Werror=format-security -Wformat -Wp,-D_FORTIFY_SOURCE=2,-D_GLIBCXX_ASSERTIONS"
LDFLAGS="-Wl,--as-needed,--gc-sections,-O3,--sort-common,-z,now,-z,relro"
RUSTFLAGS="-C link-arg=$LDFLAGS -C link-dead-code=off -C opt-level=3"
DEBUG_CFLAGS="-fasynchronous-unwind-tables -g"
DEBUG_CXXFLAGS="-fasynchronous-unwind-tables -g"
DEBUG_RUSTFLAGS="-C debuginfo=2"
if [[ $MAKEPKG_GCC != true ]]; then
export AR="llvm-ar"
export CC="clang"
export CXX="clang++"
export NM="llvm-nm"
export OBJCOPY="llvm-objcopy"
export OBJDUMP="llvm-objdump"
export READELF="llvm-readelf"
export STRIP="llvm-strip"
RUSTFLAGS="$RUSTFLAGS -C linker=clang"
else
export CC="gcc"
export CXX="g++"
RUSTFLAGS="$RUSTFLAGS -C linker=gcc"
fi
if [[ $CC == clang ]] && [[ $CXX == clang++ ]]; then
CFLAGS="$CFLAGS -fuse-ld=lld -ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang -Wno-unused-command-line-argument -Wno-error=unused-command-line-argument"
CXXFLAGS="$CXXFLAGS -fuse-ld=lld -ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang -Wno-unused-command-line-argument -Wno-error=unused-command-line-argument"
RUSTFLAGS="$RUSTFLAGS -C link-arg=-fuse-ld=lld"
if [[ $MAKEPKG_LLVM_IAS != false ]]; then
CFLAGS="$CFLAGS -fintegrated-as"
CXXFLAGS="$CXXFLAGS -fintegrated-as"
else
CFLAGS="$CFLAGS -fno-integrated-as"
CXXFLAGS="$CXXFLAGS -fno-integrated-as"
fi
if [[ $MAKEPKG_LLVM_POLLY != false ]]; then
# Check if using Arch's build of Polly and load it
# manually. It doesn't load automatically.
if pacman -Q "polly" 2> "/dev/null" | grep -q "polly "; then
CFLAGS="$CFLAGS -Xclang -load -Xclang LLVMPolly.so"
CXXFLAGS="$CXXFLAGS -Xclang -load -Xclang LLVMPolly.so"
fi
CFLAGS="$CFLAGS -mllvm -polly -mllvm -polly-position=early -mllvm -polly-vectorizer=stripmine -mllvm -polly-detect-profitability-min-per-loop-insts=40"
CXXFLAGS="$CXXFLAGS -mllvm -polly -mllvm -polly-position=before-vectorizer -mllvm -polly-vectorizer=stripmine -mllvm -polly-detect-profitability-min-per-loop-insts=40"
fi
if [[ $MAKEPKG_LLVM_CFI == true ]]; then
CFLAGS="$CFLAGS -fsanitize=cfi"
CXXFLAGS="$CXXFLAGS -fsanitize=cfi"
fi
else
if [[ $MAKEPKG_GCC_GOLD != false ]]; then
CFLAGS="$CFLAGS -fuse-ld=gold"
CXXFLAGS="$CXXFLAGS -fuse-ld=gold"
RUSTFLAGS="$RUSTFLAGS -C link-arg=-fuse-ld=gold"
else
CFLAGS="$CFLAGS -fuse-ld=bfd"
CXXFLAGS="$CXXFLAGS -fuse-ld=bfd"
RUSTFLAGS="$RUSTFLAGS -C link-arg=-fuse-ld=bfd"
fi
if [[ $MAKEPKG_GCC_GRAPHITE != false ]]; then
CFLAGS="$CFLAGS -fgraphite-identity -ftree-loop-distribution -floop-block -floop-interchange -floop-strip-mine"
CXXFLAGS="$CXXFLAGS -fgraphite-identity -ftree-loop-distribution -floop-block -floop-interchange -floop-strip-mine"
fi
DEBUG_CFLAGS="$DEBUG_CFLAGS -fvar-tracking-assignments"
DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -fvar-tracking-assignments"
fi
if [[ $MAKEPKG_TUNE_NATIVE != false ]]; then
# LLVM doesn't understand -march=native so let's limit to a sane
# alternative (x86-64-v3) which would allow us to share packages if need be.
CFLAGS="$CFLAGS -march=x86-64-v3 -mcpu=native -mtune=native"
CXXFLAGS="$CXXFLAGS -march=x86-64-v3 -mcpu=native -mtune=native"
RUSTFLAGS="$RUSTFLAGS -C target-cpu=native"
else
CFLAGS="$CFLAGS -march=x86-64 -mcpu=generic -mtune=generic"
CXXFLAGS="$CXXFLAGS -march=x86-64 -mcpu=generic -mtune=generic"
RUSTFLAGS="$RUSTFLAGS -C target-cpu=generic"
fi
MAKEFLAGS="-j$(($(nproc) -1))"
NINJAFLAGS="-j$(($(nproc) -1))"
BUILDENV=(
"color"
"ccache"
"check"
"!distcc"
"!sign"
)
OPTIONS=(
"!debug"
"docs"
"emptydirs"
"!libtool"
"purge"
"!staticlibs"
"strip"
"zipman"
# Our LTO definitions have moved to /usr/share/makepkg/buildenv/lto.sh.
"lto"
)
if [[ $MAKEPKG_LTO != false ]]; then
OPTIONS+=(
# Our LTO definitions have moved to /usr/share/makepkg/buildenv/lto.sh.
"lto"
)
else
OPTIONS+=(
# Our LTO definitions have moved to /usr/share/makepkg/buildenv/lto.sh.
"!lto"
)
fi
INTEGRITY_CHECK=("b2")
STRIP_BINARIES="--strip-all"
STRIP_SHARED="--strip-unneeded"
STRIP_STATIC="--strip-debug"
MAN_DIRS=(
"opt/"*"/"{"man","info"}
"usr/"{,"local/"}{,"share/"}{"man","info"}
)
DOC_DIRS=(
"opt/"*"/"{"doc","gtk-doc"}
"usr/"{,"local/"}{,"share/"}{"doc","gtk-doc"}
)
PURGE_TARGETS=(
"*.pod"
".packlist"
"usr/{,share}/info/dir"
)
DBGSRCDIR="/usr/src/debug"
if [[ -z $MAKEPKG_PACKAGER ]]; then
PACKAGER="Xxxx Xxxx <xxxx@xxxx.xxx>"
else
PACKAGER="$MAKEPKG_PACKAGER"
fi
COMPRESSGZ=(pigz -c -f -n)
COMPRESSBZ2=(lbzip2 -c -f)
COMPRESSXZ=(xz -c -z -T$(($(nproc)-1)) -)
COMPRESSZST=(zstd -c -z -q -T$(($(nproc)-1)) -)
COMPRESSLRZ=(lrzip -q)
COMPRESSLZO=(lrzip -q)
COMPRESSZ=(compress -c -f)
COMPRESSLZ4=(lz4 -q)
COMPRESSLZ=(lrzip -q)
PKGEXT=".pkg.tar.zst"
SRCEXT=".src.tar.gz"
#! /usr/bin/bash
#
# lto.sh - Specify flags for building a package with link-time
# optimisation.
#
# Copyright (c) 2011 Pacman Development Team <pacman-dev@archlinux.org>
# Copyright (c) 2021 Diab Neiroukh <lazerl0rd@thezest.dev>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses>.
#
[[ -n "$LIBMAKEPKG_EXECUTABLE_STRIP_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_STRIP_SH="1"
LIBRARY=${LIBRARY:-'/usr/share/makepkg'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/option.sh"
executable_functions+=('executable_strip')
executable_strip()
{
if check_option "strip" "y"; then
if [[ $CC == clang ]] && [[ $CXX == clang++ ]]; then
if ! type -p llvm-strip >/dev/null; then
error "$(gettext "Cannot find the %s binary required for object file stripping.")" "strip"
return 1
fi
else
if ! type -p strip >/dev/null; then
error "$(gettext "Cannot find the %s binary required for object file stripping.")" "strip"
return 1
fi
fi
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment