overriding config values through environment variables wasn't working because the script call was resetting them before they were saved also, the external config file was getting sourced twice
468 lines
17 KiB
Bash
Executable File
468 lines
17 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Stop the script at any ecountered error
|
|
set -e
|
|
|
|
# save current environment before losing it to the script call
|
|
declare -p -x > current_env
|
|
|
|
# If current run is not using 'script' for logging, do it
|
|
if [ -z "$SCRIPT" ]; then
|
|
export SCRIPT=1
|
|
/usr/bin/script -q -e -c "$0 $@" shell-output.log
|
|
exit_status="$?"
|
|
sed -i 's/\x1b\[[0-9;]*m//g' shell-output.log
|
|
sed -i 's/\x1b(B//g' shell-output.log
|
|
mv -f shell-output.log logs/shell-output.log.txt
|
|
exit $exit_status
|
|
fi
|
|
|
|
###################### Definition of helper variables and functions
|
|
|
|
_where=`pwd`
|
|
srcdir="$_where"
|
|
|
|
# Command used for superuser privileges (`sudo`, `doas`, `su`)
|
|
if [ ! -x "$(command -v sudo)" ]; then
|
|
if [ -x "$(command -v doas)" ]; then
|
|
sudo() { doas "$@"; }
|
|
elif [ -x "$(command -v su)" -a -x "$(command -v xargs)" ]; then
|
|
sudo() { echo "$@" | xargs -I {} su -c '{}'; }
|
|
fi
|
|
fi
|
|
|
|
msg2() {
|
|
echo -e " \033[1;34m->\033[1;0m \033[1;1m$1\033[1;0m" >&2
|
|
}
|
|
|
|
error() {
|
|
echo -e " \033[1;31m==> ERROR: $1\033[1;0m" >&2
|
|
}
|
|
|
|
warning() {
|
|
echo -e " \033[1;33m==> WARNING: $1\033[1;0m" >&2
|
|
}
|
|
|
|
plain() {
|
|
echo -e "$1" >&2
|
|
}
|
|
|
|
####################################################################
|
|
|
|
################### Config sourcing
|
|
|
|
source customization.cfg
|
|
|
|
if [ -e "$_EXT_CONFIG_PATH" ]; then
|
|
msg2 "External configuration file $_EXT_CONFIG_PATH will be used and will override customization.cfg values."
|
|
source "$_EXT_CONFIG_PATH"
|
|
fi
|
|
|
|
. current_env
|
|
|
|
source linux-tkg-config/prepare
|
|
|
|
####################################################################
|
|
|
|
_distro_prompt() {
|
|
echo "Which linux distribution are you running ?"
|
|
echo "if it's not on the list, chose the closest one to it: Fedora/Suse for RPM, Ubuntu/Debian for DEB"
|
|
_prompt_from_array "Debian" "Fedora" "Suse" "Ubuntu" "Gentoo" "Generic"
|
|
_distro="${_selected_value}"
|
|
}
|
|
|
|
_install_dependencies() {
|
|
if [ "$_compiler_name" = "llvm" ]; then
|
|
clang_deps="llvm clang lld"
|
|
fi
|
|
if [ "$_distro" = "Debian" -o "$_distro" = "Ubuntu" ]; then
|
|
msg2 "Installing dependencies"
|
|
sudo apt install bc bison build-essential ccache cpio fakeroot flex git kmod libelf-dev libncurses5-dev libssl-dev lz4 qtbase5-dev rsync schedtool wget zstd debhelper ${clang_deps} -y
|
|
elif [ "$_distro" = "Fedora" ]; then
|
|
msg2 "Installing dependencies"
|
|
sudo dnf install perl bison ccache dwarves elfutils-devel elfutils-libelf-devel fedora-packager fedpkg flex gcc-c++ git grubby libXi-devel lz4 make ncurses-devel openssl openssl-devel perl-devel perl-generators pesign python3-devel qt5-qtbase-devel rpm-build rpmdevtools schedtool zstd bc rsync -y ${clang_deps} -y
|
|
elif [ "$_distro" = "Suse" ]; then
|
|
msg2 "Installing dependencies"
|
|
sudo zypper install -y bc bison ccache dwarves elfutils flex gcc-c++ git libXi-devel libelf-devel libqt5-qtbase-common-devel libqt5-qtbase-devel lz4 make ncurses-devel openssl-devel patch pesign rpm-build rpmdevtools schedtool python3 rsync zstd ${clang_deps}
|
|
fi
|
|
}
|
|
|
|
if [ "$1" != "install" ] && [ "$1" != "config" ] && [ "$1" != "uninstall-help" ]; then
|
|
msg2 "Argument not recognised, options are:
|
|
- config : interactive script that shallow clones the linux 5.x.y git tree into the folder \$_kernel_work_folder, then applies extra patches and prepares the .config file
|
|
by copying the one from the currently running linux system and updates it.
|
|
- install : does the config step, proceeds to compile, then prompts to install
|
|
- 'DEB' distros: it creates .deb packages that will be installed then stored in the DEBS folder.
|
|
- 'RPM' distros: it creates .rpm packages that will be installed then stored in the RPMS folder.
|
|
- 'Generic' distro: it uses 'make modules_install' and 'make install', uses 'dracut' to create an initramfs, then updates grub's boot entry.
|
|
- uninstall-help : [RPM and DEB based distros only], lists the installed kernels in this system, then gives hints on how to uninstall them manually."
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$1" = "install" ] || [ "$1" = "config" ]; then
|
|
|
|
if [ -z "$_distro" ] && [ "$1" = "install" ]; then
|
|
_distro_prompt
|
|
fi
|
|
|
|
if [ "$1" = "config" ]; then
|
|
_distro="Unknown"
|
|
fi
|
|
|
|
# Run init script that is also run in PKGBUILD, it will define some env vars that we will use
|
|
_tkg_initscript
|
|
|
|
if [[ "${_compiler}" = "llvm" && "${_distro}" =~ ^(Generic|Gentoo)$ ]]; then
|
|
read -p "Replace \"libunwind\" with \"llvm-libunwind\" ? Y/[n]:" _libunwind_replace
|
|
if [[ "${_libunwind_replace}" =~ ^(y|yes|Yes|Y)$ ]]; then
|
|
export LDFLAGS_MODULE="-unwindlib=libunwind"
|
|
export HOSTLDFLAGS="-unwindlib=libunwind"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$1" = "install" && ! "$_distro" =~ ^(Ubuntu|Debian|Fedora|Suse|Gentoo|Generic)$ ]]; then
|
|
msg2 "Variable \"_distro\" in \"customization.cfg\" has been set to an unkown value. Prompting..."
|
|
_distro_prompt
|
|
fi
|
|
|
|
# Install the needed dependencies if the user wants to install the kernel
|
|
# Not needed if the user asks for install.sh config
|
|
if [ "$1" == "install" ]; then
|
|
_install_dependencies
|
|
fi
|
|
|
|
# Force prepare script to avoid Arch specific commands if the user is using `config`
|
|
if [ "$1" = "config" ]; then
|
|
_distro=""
|
|
fi
|
|
|
|
_tkg_srcprep
|
|
|
|
_build_dir="$_kernel_work_folder_abs/.."
|
|
|
|
# Uppercase characters are not allowed in source package name for debian based distros
|
|
if [[ "$_distro" =~ ^(Debian|Ubuntu)$ && "$_cpusched" = "MuQSS" ]]; then
|
|
_cpusched="muqss"
|
|
fi
|
|
|
|
msg2 "Configuration done."
|
|
fi
|
|
|
|
if [ "$1" = "install" ]; then
|
|
|
|
if [ -e "${_where}/winesync.rules" ]; then
|
|
msg2 "Installing udev rule for winesync"
|
|
sudo cp "${_where}"/winesync.rules /etc/udev/rules.d/winesync.rules
|
|
sudo chmod 644 /etc/udev/rules.d/winesync.rules
|
|
|
|
msg2 "Adding winesync to '/etc/modules-load.d' for auto-loading by systemd - Password prompt incoming!"
|
|
sudo sh -c 'echo "winesync" >/etc/modules-load.d/winesync.conf'
|
|
fi
|
|
|
|
# Use custom compiler paths if defined
|
|
if [ "$_compiler_name" = "-llvm" ] && [ -n "${CUSTOM_LLVM_PATH}" ]; then
|
|
PATH="${CUSTOM_LLVM_PATH}/bin:${CUSTOM_LLVM_PATH}/lib:${CUSTOM_LLVM_PATH}/include:${PATH}"
|
|
elif [ -n "${CUSTOM_GCC_PATH}" ]; then
|
|
PATH="${CUSTOM_GCC_PATH}/bin:${CUSTOM_GCC_PATH}/lib:${CUSTOM_GCC_PATH}/include:${PATH}"
|
|
fi
|
|
|
|
if [ "$_force_all_threads" = "true" ]; then
|
|
_thread_num=`nproc`
|
|
else
|
|
_thread_num=`expr \`nproc\` / 4`
|
|
if [ "$_thread_num" = "0" ]; then
|
|
_thread_num=1
|
|
fi
|
|
fi
|
|
|
|
# ccache
|
|
if [ "$_noccache" != "true" ]; then
|
|
export PATH="/usr/lib64/ccache/:/usr/lib/ccache/bin/:$PATH"
|
|
|
|
export CCACHE_SLOPPINESS="file_macro,locale,time_macros"
|
|
export CCACHE_NOHASHDIR="true"
|
|
msg2 'Enabled ccache'
|
|
fi
|
|
|
|
if [ -z "$_kernel_localversion" ]; then
|
|
if [ "$_preempt_rt" = "1" ]; then
|
|
_kernel_flavor="tkg-${_cpusched}-rt${_compiler_name}"
|
|
else
|
|
_kernel_flavor="tkg-${_cpusched}${_compiler_name}"
|
|
fi
|
|
else
|
|
_kernel_flavor="tkg-${_kernel_localversion}"
|
|
fi
|
|
|
|
# Setup kernel_subver variable
|
|
if [[ "$_sub" = rc* ]]; then
|
|
# if an RC version, subver will always be 0
|
|
_kernel_subver=0
|
|
else
|
|
_kernel_subver="${_sub}"
|
|
fi
|
|
|
|
#_timed_build() {
|
|
#_runtime=$( time ( schedtool -B -n 1 -e ionice -n 1 "$@" 2>&1 ) 3>&1 1>&2 2>&3 ) || _runtime=$( time ( "$@" 2>&1 ) 3>&1 1>&2 2>&3 ) - Bash 5.2 is broken https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1018727
|
|
#}
|
|
|
|
cd "$_kernel_work_folder_abs"
|
|
|
|
if [[ "$_distro" =~ ^(Ubuntu|Debian)$ ]]; then
|
|
|
|
msg2 "Building kernel DEB packages"
|
|
make ${llvm_opt} -j ${_thread_num} deb-pkg LOCALVERSION=-${_kernel_flavor}
|
|
msg2 "Building successfully finished!"
|
|
|
|
# Create DEBS folder if it doesn't exist
|
|
cd "$_where"
|
|
mkdir -p DEBS
|
|
|
|
# Move deb files to DEBS folder inside the linux-tkg folder
|
|
mv "$_build_dir"/*.deb "$_where"/DEBS/
|
|
|
|
read -p "Do you want to install the new Kernel ? Y/[n]: " _install
|
|
if [[ "$_install" =~ ^(y|Y|yes|Yes)$ ]]; then
|
|
cd "$_where"
|
|
if [[ "$_sub" = rc* ]]; then
|
|
_kernelname=$_basekernel.$_kernel_subver-$_sub-$_kernel_flavor
|
|
else
|
|
_kernelname=$_basekernel.$_kernel_subver-$_kernel_flavor
|
|
fi
|
|
_headers_deb="linux-headers-${_kernelname}*.deb"
|
|
_image_deb="linux-image-${_kernelname}_*.deb"
|
|
|
|
cd DEBS
|
|
sudo dpkg -i $_headers_deb $_image_deb
|
|
fi
|
|
|
|
elif [[ "$_distro" =~ ^(Fedora|Suse)$ ]]; then
|
|
|
|
# Replace dashes with underscores, it seems that it's being done by binrpm-pkg
|
|
# Se we can actually refer properly to the rpm files.
|
|
_kernel_flavor=${_kernel_flavor//-/_}
|
|
|
|
if [[ "$_sub" == rc* ]]; then
|
|
_extra_ver_str="_${_sub}_${_kernel_flavor}"
|
|
else
|
|
_extra_ver_str="_${_kernel_flavor}"
|
|
fi
|
|
|
|
_fedora_work_dir="$_kernel_work_folder_abs/rpmbuild"
|
|
|
|
msg2 "Add patched files to the diff.patch"
|
|
(cd ${_kernel_work_folder_abs} && git add -- . ':!rpmbuild')
|
|
|
|
msg2 "Building kernel RPM packages"
|
|
RPMOPTS="--define '_topdir ${_fedora_work_dir}'" make ${llvm_opt} -j ${_thread_num} rpm-pkg EXTRAVERSION="${_extra_ver_str}"
|
|
msg2 "Building successfully finished!"
|
|
|
|
# Create RPMS folder if it doesn't exist
|
|
cd "$_where"
|
|
mkdir -p RPMS
|
|
|
|
# Move rpm files to RPMS folder inside the linux-tkg folder
|
|
mv ${_fedora_work_dir}/RPMS/x86_64/*tkg* "$_where"/RPMS/
|
|
|
|
read -p "Do you want to install the new Kernel ? Y/[n]: " _install
|
|
if [[ "$_install" =~ ^(Y|y|Yes|yes)$ ]]; then
|
|
|
|
if [[ "$_sub" = rc* ]]; then
|
|
_kernelname=$_basekernel.${_kernel_subver}_${_sub}_$_kernel_flavor
|
|
else
|
|
_kernelname=$_basekernel.${_kernel_subver}_$_kernel_flavor
|
|
fi
|
|
|
|
_kernel_rpm="kernel-${_kernelname}*.rpm"
|
|
# The headers are actually contained in the kernel-devel RPM and not the headers one...
|
|
_kernel_devel_rpm="kernel-devel-${_kernelname}*.rpm"
|
|
_kernel_syms_rpm="kernel-syms-${_kernelname}*.rpm"
|
|
|
|
cd RPMS
|
|
if [ "$_distro" = "Fedora" ]; then
|
|
sudo dnf install $_kernel_rpm $_kernel_devel_rpm
|
|
elif [ "$_distro" = "Suse" ]; then
|
|
# It seems there is some weird behavior with relocking existing locks, so let's unlock first
|
|
sudo zypper removelock kernel-default-devel kernel-default kernel-devel kernel-syms
|
|
|
|
msg2 "Some files from 'linux-glibc-devel' will be replaced by files from the custom kernel-hearders package"
|
|
msg2 "To revert back to the original kernel headers do 'sudo zypper install -f linux-glibc-devel'"
|
|
sudo zypper install --oldpackage --allow-unsigned-rpm $_kernel_rpm $_kernel_devel_rpm $_kernel_syms_rpm
|
|
|
|
# Let's lock post install
|
|
warning "By default, system kernel updates will overwrite your custom kernel."
|
|
warning "Adding a lock will prevent this but skip system kernel updates."
|
|
msg2 "You can remove the lock if needed with 'sudo zypper removelock kernel-default-devel kernel-default kernel-devel kernel-syms'"
|
|
read -p "Would you like to lock system kernel packages ? Y/[n]: " _lock
|
|
if [[ "$_lock" =~ ^(Y|y|Yes|yes)$ ]]; then
|
|
sudo zypper addlock kernel-default-devel kernel-default kernel-devel kernel-syms
|
|
fi
|
|
fi
|
|
|
|
if [ "$_distro" = "Suse" ]; then
|
|
msg2 "Creating initramfs"
|
|
sudo dracut --force --hostonly ${_dracut_options} --kver $_kernelname
|
|
msg2 "Updating GRUB"
|
|
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
|
|
fi
|
|
|
|
msg2 "Install successful"
|
|
fi
|
|
|
|
elif [[ "$_distro" =~ ^(Gentoo|Generic)$ ]]; then
|
|
|
|
./scripts/config --set-str LOCALVERSION "-${_kernel_flavor}"
|
|
|
|
if [[ "$_sub" = rc* ]]; then
|
|
_kernelname=$_basekernel.${_kernel_subver}-${_sub}-$_kernel_flavor
|
|
else
|
|
_kernelname=$_basekernel.${_kernel_subver}-$_kernel_flavor
|
|
fi
|
|
|
|
msg2 "Building kernel"
|
|
make ${llvm_opt} -j ${_thread_num}
|
|
msg2 "Build successful"
|
|
|
|
if [ "$_STRIP" = "true" ]; then
|
|
echo "Stripping vmlinux..."
|
|
strip -v $STRIP_STATIC "vmlinux"
|
|
fi
|
|
|
|
_headers_folder_name="linux-$_kernelname"
|
|
|
|
msg2 "Removing unneeded architectures..."
|
|
for arch in arch/*/; do
|
|
[[ $arch = */x86/ ]] && continue
|
|
echo "Removing $(basename "$arch")"
|
|
rm -r "$arch"
|
|
done
|
|
|
|
msg2 "Removing broken symlinks..."
|
|
find -L . -type l -printf 'Removing %P\n' -delete
|
|
|
|
msg2 "Removing loose objects..."
|
|
find . -type f -name '*.o' -printf 'Removing %P\n' -delete
|
|
|
|
msg2 "Stripping build tools..."
|
|
while read -rd '' file; do
|
|
case "$(file -bi "$file")" in
|
|
application/x-sharedlib\;*) # Libraries (.so)
|
|
strip -v $STRIP_SHARED "$file" ;;
|
|
application/x-archive\;*) # Libraries (.a)
|
|
strip -v $STRIP_STATIC "$file" ;;
|
|
application/x-executable\;*) # Binaries
|
|
strip -v $STRIP_BINARIES "$file" ;;
|
|
application/x-pie-executable\;*) # Relocatable binaries
|
|
strip -v $STRIP_SHARED "$file" ;;
|
|
esac
|
|
done < <(find . -type f -perm -u+x ! -name vmlinux -print0)
|
|
|
|
echo -e "\n\n"
|
|
|
|
msg2 "The installation process will run the following commands:"
|
|
echo " # copy the patched and compiled sources to /usr/src/$_headers_folder_name"
|
|
echo " sudo make modules_install"
|
|
echo " sudo make install"
|
|
echo " sudo dracut --force --hostonly ${_dracut_options} --kver $_kernelname"
|
|
echo " sudo grub-mkconfig -o /boot/grub/grub.cfg"
|
|
|
|
msg2 "Note: Uninstalling requires manual intervention, use './install.sh uninstall-help' for more information."
|
|
read -p "Continue ? Y/[n]: " _continue
|
|
|
|
if ! [[ "$_continue" =~ ^(Y|y|Yes|yes)$ ]];then
|
|
exit 0
|
|
fi
|
|
|
|
msg2 "Copying files over to /usr/src/$_headers_folder_name"
|
|
if [ -d "/usr/src/$_headers_folder_name" ]; then
|
|
msg2 "Removing old folder in /usr/src/$_headers_folder_name"
|
|
sudo rm -rf "/usr/src/$_headers_folder_name"
|
|
fi
|
|
sudo cp -R . "/usr/src/$_headers_folder_name"
|
|
sudo rm -rf "/usr/src/$_headers_folder_name/.git"
|
|
cd "/usr/src/$_headers_folder_name"
|
|
|
|
msg2 "Installing modules"
|
|
if [ "$_STRIP" = "true" ]; then
|
|
sudo make modules_install INSTALL_MOD_STRIP="1"
|
|
else
|
|
sudo make modules_install
|
|
fi
|
|
msg2 "Removing modules from source folder in /usr/src/${_kernel_src_gentoo}"
|
|
sudo find . -type f -name '*.ko' -delete
|
|
sudo find . -type f -name '*.ko.cmd' -delete
|
|
|
|
msg2 "Installing kernel"
|
|
sudo make install
|
|
|
|
if [ "$_distro" = "Gentoo" ]; then
|
|
|
|
msg2 "Selecting the kernel source code as default source folder"
|
|
sudo ln -sfn "/usr/src/$_headers_folder_name" "/usr/src/linux"
|
|
|
|
msg2 "Rebuild kernel modules with \"emerge @module-rebuild\" ?"
|
|
if [ "$_compiler" = "llvm" ];then
|
|
warning "Building modules with LLVM/Clang is mostly unsupported OOTB by \"emerge @module-rebuild\" except for Nvidia 465.31+"
|
|
warning " Manually setting \"CC=clang\" for some modules may work if you haven't used LTO"
|
|
fi
|
|
|
|
read -p "Y/[n]: " _continue
|
|
if [[ "$_continue" =~ ^(Y|y|Yes|yes)$ ]];then
|
|
sudo emerge @module-rebuild --keep-going
|
|
fi
|
|
|
|
else
|
|
|
|
msg2 "Creating initramfs"
|
|
sudo dracut --force --hostonly ${_dracut_options} --kver $_kernelname
|
|
msg2 "Updating GRUB"
|
|
sudo grub-mkconfig -o /boot/grub/grub.cfg
|
|
|
|
fi
|
|
|
|
fi
|
|
fi
|
|
|
|
if [ "$1" = "uninstall-help" ]; then
|
|
|
|
if [ -z $_distro ]; then
|
|
_distro_prompt
|
|
fi
|
|
|
|
cd "$_where"
|
|
|
|
if [[ "$_distro" =~ ^(Ubuntu|Debian)$ ]]; then
|
|
msg2 "List of installed custom tkg kernels: "
|
|
dpkg -l "*tkg*" | grep "linux.*tkg"
|
|
dpkg -l "*linux-libc-dev*" | grep "linux.*tkg"
|
|
msg2 "To uninstall a version, you should remove the linux-image, linux-headers and linux-libc-dev associated to it (if installed), with: "
|
|
msg2 " sudo apt remove linux-image-VERSION linux-headers-VERSION linux-libc-dev-VERSION"
|
|
msg2 " where VERSION is displayed in the lists above, uninstall only versions that have \"tkg\" in its name"
|
|
msg2 "Note: linux-libc-dev packages are no longer created and installed, you can safely remove any remnants."
|
|
elif [ "$_distro" = "Fedora" ]; then
|
|
msg2 "List of installed custom tkg kernels: "
|
|
dnf list --installed | grep -i "tkg"
|
|
msg2 "To uninstall a version, you should remove the kernel, kernel-headers and kernel-devel associated to it (if installed), with: "
|
|
msg2 " sudo dnf remove --noautoremove kernel-VERSION kernel-devel-VERSION kernel-headers-VERSION"
|
|
msg2 " where VERSION is displayed in the second column"
|
|
msg2 "Note: kernel-headers packages are no longer created and installed, you can safely remove any remnants."
|
|
elif [ "$_distro" = "Suse" ]; then
|
|
msg2 "List of installed custom tkg kernels: "
|
|
zypper packages --installed-only | grep "kernel.*tkg"
|
|
msg2 "To uninstall a version, you should remove the kernel, kernel-headers and kernel-devel associated to it (if installed), with: "
|
|
msg2 " sudo zypper remove --no-clean-deps kernel-VERSION kernel-devel-VERSION kernel-headers-VERSION"
|
|
msg2 " where VERSION is displayed in the second to last column"
|
|
msg2 "Note: kernel-headers packages are no longer created and installed, you can safely remove any remnants."
|
|
elif [[ "$_distro" =~ ^(Generic|Gentoo)$ ]]; then
|
|
msg2 "Folders in /lib/modules :"
|
|
ls /lib/modules
|
|
msg2 "Files in /boot :"
|
|
ls /boot
|
|
msg2 "To uninstall a kernel version installed through install.sh with 'Generic' as a distro:"
|
|
msg2 " - Remove manually the corresponding folder in '/lib/modules'"
|
|
msg2 " - Remove manually the corresponding 'System.map', 'vmlinuz', 'config' and 'initramfs' in the folder :/boot"
|
|
msg2 " - Update the boot menu. e.g. 'sudo grub-mkconfig -o /boot/grub/grub.cfg'"
|
|
fi
|
|
|
|
fi
|