diff --git a/make.project/clean.sh b/make.project/clean.sh new file mode 100755 index 0000000..cee5d2a --- /dev/null +++ b/make.project/clean.sh @@ -0,0 +1,8 @@ +# clean the slate +echo +echo "Deleting ${dir_stage}" +rm -Rfv ${dir_stage} + +echo +echo "Deleting ${dir_stage}" +rm -Rfv ${dir_logs} diff --git a/make.project/purge_artifacts.sh b/make.project/purge_artifacts.sh new file mode 100755 index 0000000..c3d7d7b --- /dev/null +++ b/make.project/purge_artifacts.sh @@ -0,0 +1,4 @@ +rm -Rfv ${dir_artifacts} +rm -Rfv ${dir_sysroot} +mkdir -p ${dir_artifacts} +mkdir -p ${dir_sysroot} diff --git a/project_config.sh b/project_config.sh index 2060ab6..6784e19 100755 --- a/project_config.sh +++ b/project_config.sh @@ -8,6 +8,8 @@ # set all vars to export automatically set -a +echo "Loading project_config.sh...." + # ## Shared Variables # diff --git a/rex.project/x86_64/components/binutils.bash b/rex.project/x86_64/components/binutils.bash new file mode 100755 index 0000000..9e6b730 --- /dev/null +++ b/rex.project/x86_64/components/binutils.bash @@ -0,0 +1,311 @@ +#!/bin/bash +# desc: +# stages, builds, installs + +# make variables persist in subprocesses for logging function +set -a + +# ---------------------------------------------------------------------- +# Configuration: +# ---------------------------------------------------------------------- +# the name of this application +APPNAME="binutils" + +# the version of this application +#VERSION="2.25" +VERSION="2.40" + +# ---------------------------------------------------------------------- +# Variables and functions sourced from Environment: +# ---------------------------------------------------------------------- +# assert_zero() +# Checks if $1 is 0. If non-0 value, halts the execution of the script. +# +# LOGS_ROOT +# The parent directory where logs from this project will go. +# +# TEMP_STAGE_DIR +# The parent directory of where source archives are extracted to. + +# register mode selections +ARGUMENT_LIST=( + "stage" + "build_pass1" + "install_pass1" + "pass1" + "build_pass2" + "install_pass2" + "pass2" + "help" +) + +# modes to associate with switches +# assumes you want nothing done unless you ask for it. +MODE_STAGE=false +MODE_BUILD_PASS1=false +MODE_INSTALL_PASS1=false +MODE_PASS1=false +MODE_BUILD_PASS2=false +MODE_INSTALL_PASS2=false +MODE_PASS2=false +MODE_HELP=false + +# the file to log to +LOGFILE="${APPNAME}.log" + +# ISO 8601 variation +TIMESTAMP="$(date +%Y-%m-%d_%H:%M:%S)" + +# the path where logs are written to +# note: LOGS_ROOT is sourced from environment +LOG_DIR="${dir_logs}/${APPNAME}-${TIMESTAMP}" + +# the path where the source will be located when complete +# note: TEMP_STAGE_DIR is sourced from environment +T_SOURCE_DIR="${TEMP_STAGE_DIR}/${APPNAME}" + +# read defined arguments +opts=$(getopt \ + --longoptions "$(printf "%s," "${ARGUMENT_LIST[@]}")" \ + --name "$APPNAME" \ + --options "" \ + -- "$@" +) + +# sourced from environment +TEMP_STAGE_DIR=${TEMP_STAGE_DIR} +whoami +ls -l ${TEMP_STAGE_DIR}/../ | grep ${TEMP_STAGE_DIR} +mkdir -p ${TEMP_STAGE_DIR} + +# process supplied arguments into flags that enable execution modes +eval set --$opts +while [[ $# -gt 0 ]]; do + case "$1" in + --stage) + MODE_STAGE=true + shift 1 + ;; + --build_pass1) + MODE_BUILD_PASS1=true + shift 1 + ;; + --install_pass1) + MODE_INSTALL_PASS1=true + shift 1 + ;; + --pass1) + MODE_PASS1=true + shift 1 + ;; + --build_pass2) + MODE_BUILD_PASS2=true + shift 1 + ;; + --install_pass2) + MODE_INSTALL_PASS2=true + shift 1 + ;; + --pass2) + MODE_PASS2=true + shift 1 + ;; + --help) + MODE_HELP=true + shift 1 + ;; + *) + break + ;; + esac +done + +# print to stdout, print to log +logprint() { + mkdir -p "${LOG_DIR}" + echo "[$(date +%Y-%m-%d_%H:%M:%S)] [${APPNAME}] $1" \ + | tee -a "${LOG_DIR}/${LOGFILE}" +} + +# Tell the user we're alive... +logprint "Initializing the ${APPNAME} utility..." + +# when the stage mode is enabled, this will execute +mode_stage() { + logprint "Starting stage of ${APPNAME}..." + + logprint "Removing any pre-existing staging for ${APPNAME}." + rm -Rf "${T_SOURCE_DIR}"* + + logprint "Extracting ${APPNAME}-${VERSION} source archive to ${TEMP_STAGE_DIR}" + tar xf "${SOURCES_DIR}/${APPNAME}-${VERSION}.tar."* -C "${TEMP_STAGE_DIR}" \ + || $( logprint "Couldn't locate source tarball. Did you run \`make download_sources\`?" \ + && assert_zero 127 ) + + logprint "Extraction complete...Renaming directory " + # conditionally rename if it needs it + stat "${T_SOURCE_DIR}-"* && mv "${T_SOURCE_DIR}-"* "${T_SOURCE_DIR}" + assert_zero $? + + logprint "Staging operation complete." +} + +# when the build_pass1 mode is enabled, this will execute +mode_build_pass1() { + logprint "Starting build of ${APPNAME}..." + + logprint "Entering build dir." + pushd "${T_SOURCE_DIR}" + + # sourced from environment: checks $? -- aborts script execution if non-zero + assert_zero $? + + mkdir -p build + pushd build + assert_zero $? + + logprint "Configuring binutils pass1..." + ../configure \ + --prefix=${CROSSTOOLS_DIR} \ + --with-sysroot=${T_SYSROOT} \ + --target=${T_TRIPLET} \ + --disable-nls \ + --disable-werror + assert_zero $? + + logprint "Compiling..." + make + assert_zero $? + + logprint "Build operation complete." +} + +mode_build_pass2() { + logprint "Starting build of ${APPNAME}..." + + logprint "Entering build dir." + pushd "${T_SOURCE_DIR}" + + # sourced from environment: checks $? -- aborts script execution if non-zero + assert_zero $? + + logprint "Entering build subdir" + mkdir -p build + pushd build + assert_zero $? + + # might be wrong, check if --enable-64-bit-bfd is needed on 64-bit targets + logprint "Configuring binutils pass2..." + ../configure \ + --prefix=/usr \ + --build=$(../config.guess) \ + --host=${T_TRIPLET} \ + --disable-nls \ + --enable-shared \ + --disable-werror \ + --enable-64-bit-bfd + assert_zero $? + + logprint "Compiling..." + make -j1 + assert_zero $? + + logprint "Build operation complete." +} + +mode_install_pass1() { + logprint "Starting install of ${APPNAME}..." + pushd "${T_SOURCE_DIR}/build" + assert_zero $? + + make -j1 install + assert_zero $? + + logprint "Install operation complete." +} + +mode_install_pass2() { + logprint "Starting install of ${APPNAME}..." + pushd "${T_SOURCE_DIR}/build" + assert_zero $? + + make -j1 DESTDIR=${T_SYSROOT} install + assert_zero $? + + logprint "Clean up items..." + logprint "Applying hotfix for libctf.so / host zlib bug" + install -vm755 libctf/.libs/libctf.so.0.0.0 ${T_SYSROOT}/usr/lib + assert_zero $? + + logprint "Install operation complete." +} + +mode_help() { + echo "${APPNAME} [ --stage ] [ --build_pass1 ] [ --install_pass1 ] [ --pass1 ] [ --build_pass2 ] [ --install_pass2 ] [ --pass2 ][ --help ]" + exit 0 +} + +# MODE_PASS1 is a meta toggle for all pass1 modes. Modes will always +# run in the correct order. +if [ "$MODE_PASS1" = "true" ]; then + MODE_STAGE=true + MODE_BUILD_PASS1=true + MODE_INSTALL_PASS1=true +fi + +if [ "$MODE_PASS2" = "true" ]; then + MODE_STAGE=true + MODE_BUILD_PASS2=true + MODE_INSTALL_PASS2=true +fi + +# if no options were selected, then show help and exit +if \ + [ "$MODE_HELP" != "true" ] && \ + [ "$MODE_STAGE" != "true" ] && \ + [ "$MODE_BUILD_PASS1" != "true" ] && \ + [ "$MODE_INSTALL_PASS1" != "true" ] && \ + [ "$MODE_BUILD_PASS2" != "true" ] && \ + [ "$MODE_INSTALL_PASS2" != "true" ] +then + logprint "No option selected during execution." + mode_help +fi + +# if help was supplied at all, show help and exit +if [ "$MODE_HELP" = "true" ]; then + logprint "Help option selected. Printing options and exiting." + mode_help +fi + +if [ "$MODE_STAGE" = "true" ]; then + logprint "Staging option selected." + mode_stage + assert_zero $? +fi + +if [ "$MODE_BUILD_PASS1" = "true" ]; then + logprint "Build of PASS1 selected." + mode_build_pass1 + assert_zero $? +fi + +if [ "$MODE_INSTALL_PASS1" = "true" ]; then + logprint "Install of PASS1 selected." + mode_install_pass1 + assert_zero $? +fi + +if [ "$MODE_BUILD_PASS2" = "true" ]; then + logprint "Build of PASS2 selected." + mode_build_pass2 + assert_zero $? +fi + +if [ "$MODE_INSTALL_PASS2" = "true" ]; then + logprint "Install of PASS2 selected." + mode_install_pass2 + assert_zero $? +fi + +logprint "Execution of ${APPNAME} completed." diff --git a/rex.project/x86_64/components/check_dependencies.bash b/rex.project/x86_64/components/check_dependencies.bash new file mode 100755 index 0000000..32ce616 --- /dev/null +++ b/rex.project/x86_64/components/check_dependencies.bash @@ -0,0 +1,135 @@ +#!/bin/bash +# Simple script to list version numbers of critical development tools +export LC_ALL=C + +echo +echo "Checking bash..." +bash --version | head -n1 | cut -d" " -f2-4 + +echo +echo "Checking /bin/sh path" +MYSH=$(readlink -f /bin/sh) +echo "/bin/sh -> $MYSH" +echo $MYSH | grep -q bash || echofail "/bin/sh does not point to bash" +unset MYSH + +echo +echo "Checking binutils..." +echo -n "Binutils: "; ld --version | head -n1 | cut -d" " -f3- +bison --version | head -n1 + +echo +echo "Checking yacc..." +if [ -h /usr/bin/yacc ]; then + echo "/usr/bin/yacc -> `readlink -f /usr/bin/yacc`"; +elif [ -x /usr/bin/yacc ]; then +cat > /usr/bin/yacc << "EOF" +#!/bin/sh +# Begin /usr/bin/yacc + +/usr/bin/bison -y $* + +# End /usr/bin/yacc +EOF +chmod 755 /usr/bin/yacc +else + echofail "yacc not found" +fi + + + +echo +echo -n "Coreutils: "; chown --version | head -n1 | cut -d")" -f2 +diff --version | head -n1 +find --version | head -n1 +gawk --version | head -n1 + +if [ -h /usr/bin/awk ]; then + echo "/usr/bin/awk -> `readlink -f /usr/bin/awk`"; +elif [ -x /usr/bin/awk ]; then + echo awk is `/usr/bin/awk --version | head -n1` +else + echofail "awk not found" +fi + +echo +echo "Checking GCC..." +gcc --version | head -n1 + +echo +echo "Checking G++..." +g++ --version | head -n1 + +echo +echo "Checking grep..." +grep --version | head -n1 + +echo +echo "Checking gzip..." +gzip --version | head -n1 + +echo +echo "Checking /proc/version..." +cat /proc/version + +echo +echo "Checking m4..." +m4 --version | head -n1 + +echo +echo "Checking make..." +make --version | head -n1 + +echo +echo "Checking patch..." +patch --version | head -n1 + +echo +echo "Checking perl..." +echo Perl `perl -V:version` + +echo +echo "Checking python..." +python3 --version + +echo +echo "Checking sed..." +sed --version | head -n1 + +echo +echo "Checking tar..." +tar --version | head -n1 + +echo +echo "Checking makeinfo..." +makeinfo --version | head -n1 +retVal=${PIPESTATUS[0]} + +if [ $retVal -ne 0 ]; then + echofail "Could not check makeinfo version...(yum -y install texinfo)" +fi + +echo +echo "Checking xz..." +xz --version | head -n1 + + +pushd /tmp +rm -fv dummy* +echo +echo "Testing compiler..." +echo 'int main(){}' > dummy.c || echofail "failed to generate /tmp/dummy.c" +g++ -o dummy dummy.c || echofail "failed to compile /tmp/dummy.c" +./dummy || echofail "could not execute test program" + +if [ -x dummy ]; then + rm -fv dummy* + echo "g++ compilation OK" +else + rm -fv dummy* + echofail "g++ compilation failed" +fi + + +echo + diff --git a/rex.project/x86_64/components/create_sysroot_dirs.bash b/rex.project/x86_64/components/create_sysroot_dirs.bash new file mode 100755 index 0000000..0470f2c --- /dev/null +++ b/rex.project/x86_64/components/create_sysroot_dirs.bash @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +mkdir -pv ${dir_sysroot}/{etc,var} ${dir_sysroot}/usr/{bin,lib,sbin} || echofail "Creating sysroot directories..." + +for i in bin lib sbin; do + ln -sv usr/$i ${dir_sysroot}/$i || echofail "Creating sysroot symlinks for bin,lib,sbin" +done + +case $(uname -m) in + x86_64) + mkdir -pv ${dir_sysroot}/lib64 || echofail "Creating /lib64" + ;; +esac + +mkdir -v ${TEMP_STAGE_DIR} || echofail "Creating ${TEMP_STAGE_DIR}" diff --git a/rex.project/x86_64/environments/stage1.env.bash b/rex.project/x86_64/environments/stage1.env.bash index bd44698..3a8eae4 100755 --- a/rex.project/x86_64/environments/stage1.env.bash +++ b/rex.project/x86_64/environments/stage1.env.bash @@ -1,10 +1,10 @@ set -a +source ./project_config.sh + TERM=xterm-256color COLORTERM=truecolor -PATH= -LANG=C -PATH=/usr/lib64/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin +LC_ALL=C function echofail() { echo @@ -12,3 +12,57 @@ function echofail() { echo exit 1 } + +# keeps talking about T_SYSROOT as $LFS +# wants $LFS path to be a mount +# needs to be set for any user including root + +#2.6 +# sourced from project_config +T_SYSROOT=${dir_sysroot} +LFS=${T_SYSROOT} + +# 4.3 we skip user and group creation, it's expected to be done before +# you start if you want a different user than you're running as +# == after that, configure the rex unit for dir creation to use that user + +if [ "$(id -u)" -ne 0 ]; then + echo "Not running as root." +fi + +# 4.4 + +# The set +h command turns off bash's hash function, which affects caching of paths for executables +set +h + +# ensures newly created files and directories are only writable by their owner, but are readable and executable by anyone +umask 022 + +# sets a comptabile machine name description for use when building crosstools that isn't going to be what the host system is using +# $LFS_TGT is what LFS uses for this +T_TRIPLET=x86_64-dhl-linux-gnu + +PATH=${T_SYSROOT}/tools/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin + +# prevents some configure scripts from looking in the wrong place for config.site +CONFIG_SITE=${T_SYSROOT}/usr/share/config.site + +# 4.5 +MAKEFLAGS="-j$(nproc)" + +# where the cross-compiler gets installed ($LFS/tools) +CROSSTOOLS_DIR=${T_SYSROOT}/xtools +TEMP_STAGE_DIR=${T_SYSROOT}/source_stage +# from project_config +SOURCES_DIR=${dir_sources} + +# fail the unit in the event of a non-zero value passed +# used primarily to check exit codes on previous commands +# also a great convenient place to add in a "press any key to continue" +assert_zero() { + if [[ "$1" -eq 0 ]]; then + return + else + exit $1 + fi +} diff --git a/rex.project/x86_64/plans/stage1.plan b/rex.project/x86_64/plans/stage1.plan index b55ad29..7c467c5 100644 --- a/rex.project/x86_64/plans/stage1.plan +++ b/rex.project/x86_64/plans/stage1.plan @@ -10,6 +10,16 @@ "name": "check dependencies", "dependencies": [ null ], "comment": "LFS 11.3-systemd-rc1 Ch. 2.2" + }, + { + "name": "creating T_SYSROOT dirs", + "dependencies": [ null ], + "comment": "LFS 11.3-systemd-rc1 Ch. 4.2" + }, + { + "name": "binutils pass 1", + "dependencies": [ null ], + "comment": "LFS 11.3-systemd-rc1 Ch. 5.2" } ] } diff --git a/rex.project/x86_64/units/stage1.units b/rex.project/x86_64/units/stage1.units index de748b2..8e75a42 100644 --- a/rex.project/x86_64/units/stage1.units +++ b/rex.project/x86_64/units/stage1.units @@ -29,6 +29,42 @@ "rectify": false, "rectifier": "", "active": true, + "required": true, + "set_user_context": true, + "user": "root", + "group": "root", + "supply_environment": true, + "environment": "environments/stage1.env.bash" + }, + { + "name": "creating T_SYSROOT dirs", + "target": "components/create_sysroot_dirs.bash", + "is_shell_command": true, + "shell_definition": "bash", + "force_pty": true, + "set_working_directory": false, + "working_directory": "", + "rectify": false, + "rectifier": "", + "active": true, + "required": true, + "set_user_context": true, + "user": "phanes", + "group": "phanes", + "supply_environment": true, + "environment": "environments/stage1.env.bash" + }, + { + "name": "binutils pass 1", + "target": "components/binutils.bash --pass1", + "is_shell_command": true, + "shell_definition": "bash", + "force_pty": true, + "set_working_directory": false, + "working_directory": "", + "rectify": false, + "rectifier": "", + "active": true, "required": true, "set_user_context": true, "user": "phanes",