cacc6c5433
If using a new book, MAKEFLAGS is set to -j$(nproc), so that if we want to easure timings with 4 processors and our computer has more than that, we need to restrict the number of processors. Jhalfs allows to do that using th cpuset cgroup controller, so that it only restrits the make job and not the whole machine. For that use a small scripts written by Xi Ruoyao that restarts make this the cpuset set.
415 lines
12 KiB
Bash
Executable file
415 lines
12 KiB
Bash
Executable file
#!/bin/bash
|
|
set -e
|
|
# Pass trap handlers to functions
|
|
set -E
|
|
|
|
# VT100 colors
|
|
declare -r RED=$'\e[31m'
|
|
declare -r GREEN=$'\e[32m'
|
|
declare -r YELLOW=$'\e[33m'
|
|
|
|
# shellcheck disable=SC2034
|
|
declare -r BLUE=$'\e[34m'
|
|
declare -r OFF=$'\e[0m'
|
|
declare -r BOLD=$'\e[1m'
|
|
declare -r tab_=$'\t'
|
|
declare -r nl_=$'\n'
|
|
|
|
# shellcheck disable=SC2034
|
|
declare -r DD_BORDER="${BOLD}==============================================================================${OFF}"
|
|
# shellcheck disable=SC2034
|
|
declare -r SD_BORDER="${BOLD}------------------------------------------------------------------------------${OFF}"
|
|
# shellcheck disable=SC2034
|
|
declare -r STAR_BORDER="${BOLD}******************************************************************************${OFF}"
|
|
|
|
# bold yellow > < pair
|
|
declare -r R_arrow=$'\e[1;33m>\e[0m'
|
|
declare -r L_arrow=$'\e[1;33m<\e[0m'
|
|
|
|
|
|
#>>>>>>>>>>>>>>>ERROR TRAPPING >>>>>>>>>>>>>>>>>>>>
|
|
#-----------------------#
|
|
simple_error() { # Basic error trap.... JUST DIE
|
|
#-----------------------#
|
|
LASTLINE="$1"
|
|
LASTERR="$2"
|
|
LASTSOURCE="$4"
|
|
error_message "${GREEN} Error $LASTERR at $LASTSOURCE line ${LASTLINE}!"
|
|
}
|
|
|
|
see_ya() {
|
|
printf '\n%b%bjhalfs%b exit%b\n' "$L_arrow" "$BOLD" "$R_arrow" "$OFF"
|
|
}
|
|
##### Simple error TRAPS
|
|
# ctrl-c SIGINT
|
|
# ctrl-y
|
|
# ctrl-z SIGTSTP
|
|
# SIGHUP 1 HANGUP
|
|
# SIGINT 2 INTRERRUPT FROM KEYBOARD Ctrl-C
|
|
# SIGQUIT 3
|
|
# SIGKILL 9 KILL
|
|
# SIGTERM 15 TERMINATION
|
|
# SIGSTOP 17,18,23 STOP THE PROCESS
|
|
#####
|
|
set -e
|
|
trap see_ya 0
|
|
trap 'simple_error "${LINENO}" "$?" "${FUNCNAME}" "${BASH_SOURCE}"' ERR
|
|
trap 'echo -e "\n\n${RED}INTERRUPT${OFF} trapped\n" && exit 2' \
|
|
HUP INT QUIT TERM # STOP stops tterminal output and does not seem to
|
|
# execute the handler
|
|
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
|
|
simple_message() {
|
|
# Prevents having to check $VERBOSITY everywhere
|
|
if [ "$VERBOSITY" -ne 0 ] ; then
|
|
# shellcheck disable=SC2059
|
|
printf "$*"
|
|
fi
|
|
}
|
|
|
|
warning_message() {
|
|
simple_message "${YELLOW}\\nWARNING:${OFF} $*\\n\\n"
|
|
}
|
|
|
|
error_message() {
|
|
# Prints an error message and exits with LASTERR or 1
|
|
if [ -n "$LASTERR" ] ; then
|
|
LASTERR=$(printf '%d' "$LASTERR")
|
|
else
|
|
LASTERR=1
|
|
fi
|
|
# If +e then disable text output
|
|
if [[ "$-" =~ e ]]; then
|
|
printf '\n\n%bERROR:%b %s\n' "$RED" "$OFF" "$*" >&2
|
|
fi
|
|
exit "$LASTERR"
|
|
}
|
|
|
|
load_file() {
|
|
# source files in a consistent way with an optional message
|
|
file="$1"
|
|
shift
|
|
msg="Loading file ${file}..."
|
|
[ -z "$*" ] || msg="$*..."
|
|
simple_message "$msg"
|
|
|
|
# shellcheck disable=SC1090
|
|
source "$file" 2>/dev/null || error_message "$file did not load"
|
|
simple_message "OK\\n"
|
|
}
|
|
|
|
git_commit=$(git log -1 --format=format:"%h %ad")
|
|
version="
|
|
${BOLD} \"jhalfs\"${OFF} builder tool (development) $git_commit
|
|
|
|
Copyright (C) 2005-2023, the jhalfs team:
|
|
Jeremy Huntwork
|
|
George Boudreau
|
|
Manuel Canales Esparcia
|
|
Thomas Pegg
|
|
Matthew Burgess
|
|
Pierre Labastie
|
|
|
|
Unless specified, all the files in this directory and its sub-directories
|
|
are subjected to the ${BOLD}MIT license${OFF}. See the ${BOLD}LICENSE${OFF} file.
|
|
|
|
The files in the ${BOLD}menu${OFF} directory are subjected to the ${BOLD}ISC License${OFF}.
|
|
See ${BOLD}LICENSE.txt${OFF} and ${BOLD}README${OFF} in that directory.
|
|
"
|
|
|
|
usage="${nl_}${tab_}${BOLD}${RED}This script cannot be called directly${OFF}
|
|
${tab_}Type ${BOLD}make${OFF} to run the tool, or
|
|
${tab_}Type ${BOLD}./jhalfs -v${OFF} to display version information."
|
|
|
|
case $1 in
|
|
-v ) echo "$version" && exit ;;
|
|
run ) : ;;
|
|
* ) echo "$usage" && exit 1 ;;
|
|
esac
|
|
|
|
# If the user has not saved his configuration file, let's ask
|
|
# if he or she really wants to run this stuff
|
|
time_current=$(stat -c '%Y' configuration 2>/dev/null || date +%s)
|
|
time_old=$(stat -c '%Y' configuration.old 2>/dev/null || printf '%s' "$time_current")
|
|
if [ "$(printf '%d' "$time_old")" -ge "$(printf '%d' "$time_current")" ] ; then
|
|
printf 'Do you want to run jhalfs? yes/no (yes): '
|
|
read -r ANSWER
|
|
case ${ANSWER:0:1} in
|
|
n|N) printf "\nExiting gracefully.\n"; exit ;;
|
|
esac
|
|
fi
|
|
|
|
# Change this to 0 to suppress almost all messages
|
|
VERBOSITY=1
|
|
|
|
load_file configuration "Loading config params from <configuration>"
|
|
|
|
# These are boolean vars generated from Config.in.
|
|
# ISSUE: If a boolean parameter is not set to y(es) there
|
|
# is no variable defined by the menu app. This can
|
|
# cause a headache if you are not aware.
|
|
# The following variables MUST exist. If they don't, the
|
|
# default value is n(o).
|
|
RUNMAKE=${RUNMAKE:-n}
|
|
GETPKG=${GETPKG:-n}
|
|
COMPARE=${COMPARE:-n}
|
|
RUN_ICA=${RUN_ICA:-n}
|
|
PKGMNGT=${PKGMNGT:-n}
|
|
WRAP_INSTALL=${WRAP_INSTALL:-n}
|
|
STRIP=${STRIP:=n}
|
|
REPORT=${REPORT:=n}
|
|
NCURSES5=${NCURSES5:-n}
|
|
DEL_LA_FILES=${DEL_LA_FILES:-n}
|
|
FULL_LOCALE=${FULL_LOCALE:-n}
|
|
GRSECURITY_HOST=${GRSECURITY_HOST:-n}
|
|
CUSTOM_TOOLS=${CUSTOM_TOOLS:-n}
|
|
REBUILD_MAKEFILE=${REBUILD_MAKEFILE:-n}
|
|
INSTALL_LOG=${INSTALL_LOG:-n}
|
|
CLEAN=${CLEAN:=n}
|
|
SET_SSP=${SET_SSP:=n}
|
|
SET_ASLR=${SET_ASLR:=n}
|
|
SET_PAX=${SET_PAX:=n}
|
|
SET_HARDENED_TMP=${SET_HARDENED_TMP:=n}
|
|
SET_WARNINGS=${SET_WARNINGS:=n}
|
|
SET_MISC=${SET_MISC:=n}
|
|
SET_BLOWFISH=${SET_BLOWFISH:=n}
|
|
UNICODE=${UNICODE:=n}
|
|
LOCAL=${LOCAL:=n}
|
|
ALL_CORES=${ALL_CORES:=n}
|
|
REALSBU=${REALSBU:=n}
|
|
SAVE_CH5=${SAVE_CH5:=n}
|
|
|
|
if [[ "${NO_PROGRESS_BAR}" = "y" ]] ; then
|
|
# shellcheck disable=SC2034
|
|
NO_PROGRESS="#"
|
|
fi
|
|
|
|
# Sanity check on the location of $BUILDDIR / $JHALFSDIR
|
|
CWD="$(cd "$(dirname "$0")" && pwd)"
|
|
if [[ $JHALFSDIR == "$CWD" ]]; then
|
|
echo " The jhalfs source directory conflicts with the jhalfs build directory."
|
|
echo " Please move the source directory or change the build directory."
|
|
exit 2
|
|
fi
|
|
|
|
# Set the document location...
|
|
BOOK=${BOOK:=$JHALFSDIR/book-source}
|
|
|
|
|
|
#--- Envars not sourced from configuration
|
|
# shellcheck disable=SC2034
|
|
declare -r REPO=https://git.linuxfromscratch.org/lfs.git
|
|
declare -r LOG=000-masterscript.log
|
|
declare -r COMMANDS=lfs-commands
|
|
|
|
# Set true internal variables
|
|
COMMON_DIR="common"
|
|
PACKAGE_DIR=LFS
|
|
MODULE=$PACKAGE_DIR/master.sh
|
|
PKGMNGTDIR="pkgmngt"
|
|
# The name packageManager.xml is hardcoded in *.xsl, so no variable.
|
|
|
|
for file in \
|
|
"$COMMON_DIR/common-functions" \
|
|
"$COMMON_DIR/libs/func_book_parser" \
|
|
"$COMMON_DIR/libs/func_download_pkgs" \
|
|
"$COMMON_DIR/libs/func_wrt_Makefile" \
|
|
"$MODULE" ; do
|
|
load_file "$file"
|
|
done
|
|
|
|
simple_message "${SD_BORDER}${nl_}"
|
|
|
|
|
|
#*******************************************************************#
|
|
LASTERR=2
|
|
for file in \
|
|
"$COMMON_DIR/libs/func_check_version.sh" \
|
|
"$COMMON_DIR/libs/func_validate_configs.sh" \
|
|
"$COMMON_DIR/libs/func_custom_pkgs" ; do
|
|
load_file "$file"
|
|
done
|
|
unset LASTERR
|
|
|
|
simple_message "${SD_BORDER}${nl_}"
|
|
simple_message "Checking tools required for jhalfs${nl_}"
|
|
check_alfs_tools
|
|
simple_message "${SD_BORDER}${nl_}"
|
|
|
|
# blfs-tool envars
|
|
BLFS_TOOL=${BLFS_TOOL:-n}
|
|
if [[ "${BLFS_TOOL}" = "y" ]] ; then
|
|
#not needed now that the check is in alfs_tools
|
|
# simple_message 'Checking supplementary tools for installing BLFS'
|
|
# check_blfs_tools
|
|
simple_message "${SD_BORDER}${nl_}"
|
|
BLFS_BRANCH=${BLFS_BRANCH:-n}
|
|
BLFS_WORKING_COPY=${BLFS_WORKING_COPY:-n}
|
|
if [[ "${BLFS_WORKING_COPY}" = "y" ]] &&
|
|
[[ ! -d "$BLFS_WC_LOCATION/postlfs" ]] ; then
|
|
echo " BLFS tools: This is not a working copy: $BLFS_WC_LOCATION."
|
|
echo " Please rerun make and fix the configuration."
|
|
exit 2
|
|
fi
|
|
load_file "${COMMON_DIR}/libs/func_install_blfs"
|
|
fi
|
|
|
|
###################################
|
|
### MAIN ###
|
|
###################################
|
|
|
|
|
|
validate_config
|
|
echo "${SD_BORDER}${nl_}"
|
|
echo -n "Are you happy with these settings? yes/no (no): "
|
|
read -r ANSWER
|
|
if [ "x$ANSWER" != "xyes" ] ; then
|
|
echo "${nl_}Rerun make to fix the configuration options.${nl_}"
|
|
exit
|
|
fi
|
|
echo "${nl_}${SD_BORDER}${nl_}"
|
|
|
|
# Load additional modules or configuration files based on global settings
|
|
# compare module
|
|
if [[ "$COMPARE" = "y" ]]; then
|
|
load_file "${COMMON_DIR}/libs/func_compare.sh" 'Loading compare module'
|
|
fi
|
|
#
|
|
# save module
|
|
if [[ "$SAVE_CH5" = "y" ]]; then
|
|
load_file "${COMMON_DIR}/libs/func_save.sh" 'Loading save module'
|
|
fi
|
|
#
|
|
# optimize module
|
|
# the optimize_functions file is needed for wrt_makeflags even
|
|
# if optimize=0, because we need to pass NINJAJOBS=1
|
|
load_file optimize/optimize_functions 'Loading optimization module'
|
|
if [[ "$OPTIMIZE" != "0" ]]; then
|
|
#
|
|
# optimize configurations
|
|
load_file optimize/opt_config 'Loading optimization config'
|
|
# Validate optimize settings, if required
|
|
validate_opt_settings
|
|
fi
|
|
# Parallelization is outside optimization, because it is now in the book
|
|
if [[ "$ALL_CORES" = "n" ]]; then
|
|
# shellcheck disable=SC2034
|
|
JH_MAKEFLAGS="-j${N_PARALLEL}"
|
|
fi
|
|
#
|
|
|
|
if [[ "$REBUILD_MAKEFILE" = "n" ]] ; then
|
|
|
|
# If requested, clean the build directory
|
|
clean_builddir
|
|
|
|
if [[ ! -d $JHALFSDIR ]]; then
|
|
sudo mkdir -p "$JHALFSDIR"
|
|
# Do not assume there is a group named as $USER, do not use
|
|
# $USER:$USER...
|
|
sudo chown "$USER" "$JHALFSDIR"
|
|
fi
|
|
|
|
# Create $BUILDDIR/sources even though it could be created by get_sources()
|
|
if [[ ! -d $BUILDDIR/sources ]]; then
|
|
sudo mkdir -p "$BUILDDIR/sources"
|
|
sudo chmod a+wt "$BUILDDIR/sources"
|
|
fi
|
|
|
|
# Create the log directory
|
|
if [[ ! -d $LOGDIR ]]; then
|
|
mkdir "$LOGDIR"
|
|
fi
|
|
true >"$LOGDIR/$LOG"
|
|
|
|
# Copy common helper files
|
|
cp "$COMMON_DIR"/{makefile-functions,progress_bar.sh,run-in-cgroup.sh} "$JHALFSDIR/"
|
|
|
|
# Copy needed stylesheets
|
|
cp "$COMMON_DIR"/{packages.xsl,chroot.xsl,kernfs.xsl} "$JHALFSDIR/"
|
|
cp "$PACKAGE_DIR/$XSL" "$JHALFSDIR/"
|
|
|
|
export XSL=$JHALFSDIR/${XSL}
|
|
|
|
# Copy packageManager.xml, if needed
|
|
[[ "$PKGMNGT" = "y" ]] && {
|
|
sed s@BOOK@"$BOOK"@ "$PKGMNGTDIR/packageManager.xml" > \
|
|
"$JHALFSDIR/"packageManager.xml
|
|
cp "$PKGMNGTDIR/packInstall.sh" "$JHALFSDIR/"
|
|
}
|
|
|
|
# Copy urls.xsl, if needed
|
|
[[ "$GETPKG" = "y" ]] && cp "$COMMON_DIR/urls.xsl" "$JHALFSDIR/"
|
|
|
|
# Always create the test-log directory to allow user to "uncomment" test
|
|
# instructions
|
|
install -d -m 1777 "$TESTLOGDIR"
|
|
|
|
# Create the installed-files directory, if needed
|
|
[[ "$INSTALL_LOG" = "y" ]] && [[ ! -d $FILELOGDIR ]] && install -d -m 1777 "$FILELOGDIR"
|
|
|
|
# Prepare report creation, if needed
|
|
if [[ "$REPORT" = "y" ]]; then
|
|
cp $COMMON_DIR/create-sbu_du-report.sh "$JHALFSDIR/"
|
|
# After making sure that all looks sane, dump the settings to a file
|
|
# This file will be used to create the REPORT header
|
|
validate_config >"$JHALFSDIR/jhalfs.config"
|
|
fi
|
|
|
|
# Copy optimize files, if needed
|
|
[[ "$OPTIMIZE" != "0" ]] && cp optimize/opt_override "$JHALFSDIR/"
|
|
|
|
# Copy compare files, if needed
|
|
if [[ "$COMPARE" = "y" ]]; then
|
|
mkdir -p "$JHALFSDIR/extras"
|
|
cp extras/* "$JHALFSDIR/extras"
|
|
fi
|
|
|
|
# Copy custom tools config files, if requested
|
|
if [[ "${CUSTOM_TOOLS}" = "y" ]]; then
|
|
echo "Copying custom tool scripts to $JHALFSDIR"
|
|
mkdir -p "$JHALFSDIR/custom-commands"
|
|
cp -f custom/config/* "$JHALFSDIR/custom-commands"
|
|
fi
|
|
|
|
# Download or updates the book source
|
|
# Note that all customization to $JHALFSDIR have to be done before this.
|
|
# But the LFS book is needed for BLFS tools.
|
|
get_book
|
|
extract_commands
|
|
echo "${SD_BORDER}${nl_}"
|
|
cd "$CWD" # the functions above change directory
|
|
|
|
# Install blfs-tool, if requested.
|
|
if [[ "${BLFS_TOOL}" = "y" ]] ; then
|
|
echo Installing BLFS book and tools
|
|
install_blfs_tools 2>&1 | tee -a "$LOGDIR/$LOG"
|
|
[[ ${PIPESTATUS[0]} != 0 ]] && exit 1
|
|
fi
|
|
|
|
fi
|
|
|
|
# shellcheck disable=SC2034
|
|
if [[ "$REBUILD_MAKEFILE" = "y" ]] ; then
|
|
# Sanity check: users tend to tick "rebuild Makefile"
|
|
# without generating one first. Check we have one:
|
|
if [ ! -f $MKFILE ]; then
|
|
set -e
|
|
error_message "You cannot \"rebuild Makefile\" without first building one"
|
|
fi
|
|
# When regenerating the Makefile, we need to know also the
|
|
# canonical book version
|
|
VERSION=$(grep 'echo.*lfs-release' "$JHALFSDIR/prbook.xml" | sed 's/.*echo[ ]*\([^ ]*\).*/\1/')
|
|
fi
|
|
|
|
build_Makefile
|
|
|
|
echo "${SD_BORDER}${nl_}"
|
|
|
|
# Check for build prerequisites.
|
|
echo
|
|
cd "$CWD"
|
|
check_prerequisites
|
|
echo "${SD_BORDER}${nl_}"
|
|
# All is well, run the build (if requested)
|
|
run_make
|