#!/bin/sh set -e # Enable error trapping set -u # Trap undefined variables.. Forces the programmer # to define a variable before using it # # Load the configuration file # source jhahlfs.conf # VT100 colors declare -r BLACK=$'\e[1;30m' declare -r DK_GRAY=$'\e[0;30m' declare -r RED=$'\e[31m' declare -r GREEN=$'\e[32m' declare -r YELLOW=$'\e[33m' declare -r BLUE=$'\e[34m' declare -r MAGENTA=$'\e[35m' declare -r CYAN=$'\e[36m' declare -r WHITE=$'\e[37m' declare -r OFF=$'\e[0m' declare -r BOLD=$'\e[1m' declare -r REVERSE=$'\e[7m' declare -r HIDDEN=$'\e[8m' declare -r tab_=$'\t' declare -r nl_=$'\n' declare -r DD_BORDER="${BOLD}${WHITE}==============================================================================${OFF}" declare -r SD_BORDER="${BOLD}${WHITE}------------------------------------------------------------------------------${OFF}" declare -r STAR_BORDER="${BOLD}${WHITE}******************************************************************************${OFF}" # bold yellow > < pair declare -r R_arrow=$'\e[1;33m>\e[0m' declare -r L_arrow=$'\e[1;33m<\e[0m' # START predefine some internal vars.. proper programming style # If the var BOOK contains something then, maybe, it points # to a working doc.. set WC=1, else 'null' WC=${BOOK:+1} CLEAN=0 # Clean out build dir? DL= # The download app to use PREV= # name of previous script processed chapter5= chapter6= chapter7= # END predefined vars section _inline_doc=" ${GREEN} This script, jhahlfs, strives to generate an accurate makefile directly from the xml files used to generated the Hardened Linux From Scratch document. The usage of this script assumes you have read and are familiar with the book and therefore the configuration variables found in jhahlfs.conf will have meaning to you. There are a limited number of command line switches which, if used, will override the config file settings. NOTES:: *. The resulting Makefile takes considerable time to run to completion, lay in a supply of caffeine beverages. *. The document, Hardened Linux From Scratch, specifies a Linux kernel >=2.6.2 and GCC >=3.0 for proper compilation. *. It is recommended that you temporarily unpack your linux kernel and run and configure the kernal as per the book and save the resulting .config file. *. Chapter07 contains numerous command files which require customizing before you start 129-console, 131-profile, 133-hosts, 134-network, 135-fstab, 136-kernel. ${OFF}" version=" jhahlfs development \$Date$ Written by George Boudreau Based on the jhalfs code written by Jeremy Huntwork and Manuel Canales Esparcia. This program is published under the ${WHITE}Gnu General Public License, Version 2.${OFF} " usage() { 'clear' cat <<- -EOF- ${DD_BORDER} ${BOLD} ${WHITE} Usage: $0 ${YELLOW}[OPTION] ${CYAN} Options: ${YELLOW} -h, --help ${CYAN} print this help, then exit ${YELLOW} --readme ${CYAN} print a small readme file, then exit ${YELLOW} -V, --version ${CYAN} print version number, then exit ${YELLOW} -d --directory DIR ${CYAN} use DIR directory for building HLFS; all files jhahlfs produces will be in the directory DIR/jhahlfs. Default is \"/mnt/lfs\". ${YELLOW} --rebuild ${CYAN} clean the build directory before to perfom any other task. The directory is cleaned only if it was populated by a previous jhahlfs run. ${YELLOW} -P, --get-packages ${CYAN} download the packages and patches. This assumes that the server declared in the jhahlfs.conf file has the proper packages and patches for the book version being processed. ${YELLOW} -W, --working-copy DIR ${CYAN} use the local working copy placed in DIR as the HLFS book ${YELLOW} -L, --HLFS-version VER ${CYAN} checkout VER version of the HLFS book. Supported versions at this time are: dev* | trunk | SVN aliases for Development HLFS ${YELLOW} --fstab FILE ${CYAN} use FILE as the /etc/fstab file for the HLFS system. If not specified, a default /etc/fstab file with dummy values is created. ${YELLOW} -C, --kernel-config FILE ${CYAN} use the kernel configuration file specified in FILE to build the kernel. if the file is not found, or if not specified, the kernel build is skipped. ${YELLOW} -M, --run-make ${CYAN} run make on the generated Makefile ${DD_BORDER} -EOF- exit } help="\ Try '$0 --help' for more information." no_empty_builddir() { 'clear' cat <<- -EOF- ${DD_BORDER} ${tab_}${tab_}${RED}W A R N I N G${OFF} ${GREEN} Looks like the \$BUILDDIR directory contains subdirectories from a previous HLFS build. Please format the partition mounted on \$BUILDDIR or set a different build directory before running jhahlfs. ${OFF} ${DD_BORDER} -EOF- exit } exit_missing_arg="\ echo \"Option '\$1' requires an argument\" >&2 echo \"\$help\" >&2 exit 1" no_dl_client="\ echo \"Could not find a way to download the HLFS sources.\" >&2 echo \"Attempting to continue.\" >&2" HEADER="# This file is automatically generated by jhahlfs # DO NOT EDIT THIS FILE MANUALLY # # Generated on `date \"+%F %X %Z\"`" #>>>>>>>>>>>>>>>ERROR TRAPPING >>>>>>>>>>>>>>>>>>>> #-----------------------# simple_error() { # Basic error trap.... JUST DIE #-----------------------# # If +e then disable text output if [[ "$-" =~ "e" ]]; then echo -e "\n${RED}ERROR:${GREEN} basic error trapped!${OFF}\n" >&2 fi } see_ya() { echo -e "\n\t${BOLD}${WHITE}Goodbye and thank you for choosing ${YELLOW}JHAHLFS\n${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 ERR trap 'echo -e "\n\n${RED}INTERRUPT${OFF} trapped\n" && exit 2' 1 2 3 15 17 18 23 #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ################################### ### FUNCTIONS ### ################################### #----------------------------# check_requirements() { # Simple routine to validate gcc and kernel versions against requirements #----------------------------# # Minimum values acceptable # bash 3.0> # gcc 3.0> # kernel 2.6.2> [[ $1 = "1" ]] && echo "${nl_}BASH: ${L_arrow}${GREEN}${BASH_VERSION}${R_arrow}" case $BASH_VERSION in [3-9].*) ;; *) 'clear' echo -e " $DD_BORDER \t\t${OFF}${RED}BASH version ${BOLD}${YELLOW}-->${WHITE} $BASH_VERSION ${YELLOW}<--${OFF}${RED} is too old. \t\t This script requires 3.0${OFF}${RED} or greater $DD_BORDER" exit 1 ;; esac [[ $1 = "1" ]] && echo "GCC: ${L_arrow}${GREEN}`gcc -dumpversion`${R_arrow}" case `gcc -dumpversion` in [3-9].[0-9].* ) ;; *) 'clear' echo -e " $DD_BORDER \t\t${OFF}${RED}GCC version ${BOLD}${YELLOW}-->${WHITE} $(gcc -dumpversion) ${YELLOW}<--${OFF}${RED} is too old. \t\t This script requires ${BOLD}${WHITE}3.0${OFF}${RED} or greater $DD_BORDER" exit 1 ;; esac # # >>>> Check kernel version against the minimum acceptable level <<<< # [[ $1 = "1" ]] && echo "LINUX: ${L_arrow}${GREEN}`uname -r`${R_arrow}" local IFS declare -i major minor revision change min_kernel_vers=2.6.2 IFS=".-" # Split up w.x.y.z as well as w.x.y-rc (catch release candidates) set -- $min_kernel_vers # set postional parameters to minimum ver values major=$1; minor=$2; revision=$3 # set -- `uname -r` # Set postional parameters to user kernel version #Compare against minimum acceptable kernel version.. (( $1 > major )) && return (( $1 == major )) && ((( $2 > minor )) || ((( $2 == minor )) && (( $3 >= revision )))) && return # oops.. write error msg and die echo -e " $DD_BORDER \t\t${OFF}${RED}The kernel version ${BOLD}${YELLOW}-->${WHITE} $(uname -r) ${YELLOW}<--${OFF}${RED} is too old. \t\tThis script requires version ${BOLD}${WHITE}$min_kernel_vers${OFF}${RED} or greater $DD_BORDER" exit 1 } #----------------------------# validate_config() { # Are the config values sane (within reason) #----------------------------# local -r PARAM_LIST="BUILDDIR HPKG MODEL TEST TOOLCHAINTEST STRIP VIMLANG PAGE GRSECURITY_HOST RUNMAKE" local -r ERROR_MSG='${OFF}${RED}The variable \"${GREEN}${config_param}${RED}\" value ${BOLD}${YELLOW}--\>${WHITE}${!config_param}${YELLOW}\<--${OFF}${RED} is invalid, check the config file ${GREEN}\${OFF}' local -r PARAM_VALS='${WHITE}${config_param}: ${L_arrow}${GREEN}${!config_param}${R_arrow}' local config_param local validation_str write_error_and_die() { echo -e "\n${DD_BORDER}" echo "`eval echo ${ERROR_MSG}`" >&2 echo -e "${DD_BORDER}\n" exit 1 } set +e for config_param in $PARAM_LIST; do [[ $1 = "1" ]] && echo -e "`eval echo $PARAM_VALS`" case $config_param in BUILDDIR) # We cannot have an or root mount point if [[ "xx x/x" =~ "x${!config_param}x" ]]; then write_error_and_die fi continue ;; HPKG) validation_str="x0x x1x" ;; RUNMAKE) validation_str="x0x x1x" ;; TEST) validation_str="x0x x1x" ;; STRIP) validation_str="x0x x1x" ;; VIMLANG) validation_str="x0x x1x" ;; TOOLCHAINTEST) validation_str="x0x x1x" ;; GRSECURITY_HOST) validation_str="x0x x1x" ;; MODEL) validation_str="xglibcx xuclibcx" ;; PAGE) validation_str="xletterx xA4x" ;; *) echo "WHAT PARAMETER IS THIS.. <<${config_param}>>" exit ;; esac # This is the 'regexp' test available in bash-3.0.. # using it as a poor man's test for substring if [[ ! "${validation_str}" =~ "x${!config_param}x" ]] ; then # parameter value entered is no good write_error_and_die fi done # for loop for config_param in LC_ALL LANG; do [[ $1 = "1" ]] && echo "`eval echo $PARAM_VALS`" [[ -z "${!config_param}" ]] && continue # See it the locale values exist on this machine [[ "`locale -a | grep -c ${!config_param}`" > 0 ]] && continue # If you make it this far then there is a problem write_error_and_die done for config_param in FSTAB CONFIG KEYMAP BOOK; do [[ $1 = "1" ]] && echo "`eval echo $PARAM_VALS`" # If this is not a working copy, ie the default book, then skip [[ -z $WC ]] && continue [[ -z "${!config_param}" ]] && continue [[ -e "${!config_param}" ]] && [[ -s "${!config_param}" ]] && continue # If you make it this far then there is a problem write_error_and_die done set -e echo "$tab_${BOLD}${YELLOW} Config parameters look good${OFF}${nl_}" } #----------------------------# build_patches_file() { # Supply a suitably formated list of patches. #----------------------------# local saveIFS=$IFS LOC_add_patches_entry() { for f in `grep "/$1-" patcheslist_.wget`; do basename $f | sed "s|${2}|\&${1}-version;|" >> patches done } xsltproc --nonet \ --xinclude \ -o patcheslist_.wget \ hlfs-patcheslist_.xsl \ $BOOK/index.xml > /dev/null 2>&1 rm -f patches IFS=$'\x0A' # Modify the 'internal field separator' to break on 'LF' only for f in `cat packages`; do IFS=$saveIFS LOC_add_patches_entry \ `echo $f | sed -e 's/-version//' \ -e 's/-file.*//' \ -e 's/"//g' \ -e 's/uclibc/uClibc/'` done # .... U G L Y .... what to do with the grsecurity patch to the kernel.. for f in `grep "/grsecurity-" patcheslist_.wget`; do basename $f >> patches done IFS=$saveIFS rm -f patcheslist_.wget } #----------------------------# clean_builddir() { # #----------------------------# # Test if the clean must be done. if [ "$CLEAN" = "1" ] ; then # Test to make sure we're running the clean as root if [ "$UID" != "0" ] ; then echo "You must be logged in as root to clean the build directory." exit 1 fi # Test to make sure that the build directory was populated by jhahlfs if [ ! -d $JHAHLFSDIR ] || [ ! -d $BUILDDIR/sources ] ; then echo "Looks like $BUILDDIR was not populated by a previous jhahlfs run." exit 1 else # Clean the build directory echo -ne "Cleaning $BUILDDIR...\n" rm -rf $BUILDDIR/{bin,boot,dev,etc,home,lib,media,mnt,opt,proc,root,sbin,srv,sys,tmp,tools,usr,var} echo -ne "Cleaning $JHAHLFSDIR...\n" rm -rf $JHAHLFSDIR/{0*,1*,envars,sources-dir,commands,logs,Makefile,dump-hlfs-scripts.xsl,hlfs-functions,packages,patches} echo -ne "Cleaning remainig extracted sources in $BUILDDIR/sources...\n" rm -rf `find $BUILDDIR/sources/* -maxdepth 0 -type d` echo -ne "done\n" fi fi } #----------------------------# get_book() { # #----------------------------# cd $JHAHLFSDIR if [ -z $WC ] ; then # Check for Subversion instead of just letting the script hit 'svn' and fail. test `type -p svn` || eval "echo \"This feature requires Subversion.\" exit 1" echo -n "Downloading the HLFS Book, version $HLFSVRS... " # Grab a fresh HLFS book if it's missing, otherwise, update it from the # repo. If we've already extracted the commands, move on to getting the # sources. if [ -d hlfs-$HLFSVRS ] ; then cd hlfs-$HLFSVRS if LC_ALL=C svn up | grep -q At && \ test -d $JHAHLFSDIR/commands && \ test -f $JHAHLFSDIR/packages && \ test -f $JHAHLFSDIR/patches ; then echo -ne "done\n" # Set the canonical book version cd $JHAHLFSDIR VERSION=`grep "ENTITY version " $BOOK/general.ent | sed 's@@@'` get_sources else echo -ne "done\n" extract_commands fi else case $HLFSVRS in development) svn co $SVN/HLFS/trunk/BOOK hlfs-$HLFSVRS >>$LOGDIR/$LOG 2>&1 ;; *) echo -e "${RED}Invalid document version selected${OFF}" ;; esac echo -ne "done\n" extract_commands fi else echo -ne "Using $BOOK as book's sources ...\n" extract_commands fi } #----------------------------# extract_commands() { # #----------------------------# # Check for libxslt instead of just letting the script hit 'xsltproc' and fail. test `type -p xsltproc` || eval "echo \"This feature requires libxslt.\" exit 1" cd $JHAHLFSDIR VERSION=`grep "ENTITY version " $BOOK/general.ent | sed 's@@@'` # Start clean if [ -d commands ]; then rm -rf commands mkdir -v commands fi echo -n "Extracting commands..." # Dump the commands in shell script form from the HLFS book. xsltproc --nonet \ --xinclude \ --stringparam model $MODEL \ --stringparam testsuite $TEST \ --stringparam toolchaintest $TOOLCHAINTEST \ --stringparam vim-lang $VIMLANG \ -o ./commands/ $XSL $BOOK/index.xml >>$LOGDIR/$LOG 2>&1 # Make the scripts executable. chmod -R +x $JHAHLFSDIR/commands # Grab the patches and package names. cd $JHAHLFSDIR for i in patches packages ; do rm -f $i ; done grep "\-version" $BOOK/general.ent | sed -e 's@@"@' \ -e '/generic/d' >> packages # Download the vim-lang package if it must be installed if [ "$VIMLANG" = "1" ] ; then echo `grep "vim" packages | sed 's@vim@&-lang@'` >> packages fi echo `grep "udev-config-file" $BOOK/general.ent | sed -e 's@@"@'` >> packages # There is no HLFS patches.ent file so we will create one. build_patches_file # grep "ENTITY" $BOOK/patches.ent | sed -e 's/.* "//' -e 's/">//' >> patches # Done. Moving on... echo -ne "done\n" get_sources } #----------------------------# download() { # Download file, write name to MISSING_FILES.DMP if an error #----------------------------# cd $BUILDDIR/sources # Hackish fix for the bash-doc, glibc-{linuxthreads,libidn} and # module-init-tools-testsuite packages that don't conform to # norms in the URL scheme. DIR=`echo $1 | sed 's@-doc@@;s@-linuxthreads@@;s@-libidn@@;s@-testsuite@@'` # Find the md5 sum for this package. if [ $2 != MD5SUMS ] ; then set +e MD5=`grep " $2" MD5SUMS` if [ $? -ne 0 ]; then set -e echo "${RED}$2 not found in MD5SUMS${OFF}" echo "$2 not found in MD5SUMS" >> MISSING_FILES.DMP return fi set -e fi if [ ! -f $2 ] ; then case $DL in wget ) wget $HTTP/$DIR/$2 ;; curl ) `curl -# $HTTP/$DIR/$2 -o $2` ;; * ) echo "$DL not supported at this time." ;; esac elif ! echo "$MD5" | md5sum -c - >/dev/null 2>/dev/null ; then case $DL in wget ) wget -c $HTTP/$DIR/$2 ;; curl ) `curl -# -C - $HTTP/$DIR/$2 -o $2` ;; * ) echo "$DL not supported at this time." ;; esac fi if [ $2 != MD5SUMS ] && ! echo "$MD5" | md5sum -c - ; then exit 1 fi if [ $2 != MD5SUMS ] ; then echo `grep "$MD5" MD5SUMS` >> MD5SUMS-$VERSION fi } #----------------------------# get_sources() { # #----------------------------# local IFS # Test if the packages must be downloaded if [ ! "$HPKG" = "1" ] ; then return fi # Modify the 'internal field separator' to break on 'LF' only IFS=$'\x0A' if [ ! -d $BUILDDIR/sources ] ; then mkdir $BUILDDIR/sources ; fi cd $BUILDDIR/sources > MISSING_FILES.DMP # Files not in md5sum end up here if [ -f MD5SUMS ] ; then rm MD5SUMS ; fi if [ -f MD5SUMS-$VERSION ] ; then rm MD5SUMS-$VERSION ; fi # Retrieve the master md5sum file download "" MD5SUMS # Iterate through each package and grab it, along with any patches it needs. for i in `cat $JHAHLFSDIR/packages` ; do PKG=`echo $i | sed -e 's/-version.*//' \ -e 's/-file.*//' \ -e 's/uclibc/uClibc/' ` # Needed for Groff patchlevel patch on UTF-8 branch GROFFLEVEL=`grep "groff-patchlevel" $JHAHLFSDIR/packages | sed -e 's/groff-patchlevel //' -e 's/"//g'` # # How to deal with orphan packages..?? # VRS=`echo $i | sed -e 's/.* //' -e 's/"//g'` case "$PKG" in "expect-lib" ) continue ;; # not valid packages "linux-dl" ) continue ;; "groff-patchlevel" ) continue ;; "uClibc-patch" ) continue ;; "tcl" ) FILE="$PKG$VRS-src.tar.bz2" ; download $PKG $FILE ;; "vim-lang" ) FILE="vim-$VRS-lang.tar.bz2"; PKG="vim" ; download $PKG $FILE ;; "udev-config" ) FILE="$VRS" ; PKG="udev" ; download $PKG $FILE ;; "uClibc-locale" ) FILE="$PKG-$VRS.tar.bz2" ; PKG="uClibc" download $PKG $FILE # There can be no patches for this file continue ;; "gcc" ) download $PKG "gcc-core-$VRS.tar.bz2" download $PKG "gcc-g++-$VRS.tar.bz2" ;; "glibc") download $PKG "$PKG-$VRS.tar.bz2" download $PKG "$PKG-libidn-$VRS.tar.bz2" ;; * ) FILE="$PKG-$VRS.tar.bz2" download $PKG $FILE ;; esac for patch in `grep "$PKG-&$PKG" $JHAHLFSDIR/patches` ; do PATCH=`echo $patch | sed 's@&'$PKG'-version;@'$VRS'@'` download $PKG $PATCH done done # .... U G L Y .... what to do with the grsecurity patch to the kernel.. download grsecurity `grep grsecurity $JHAHLFSDIR/patches` # .... U G L Y .... deal with uClibc-locale-xxxxx.tar.bz2 format issue. bzcat uClibc-locale-030818.tar.bz2 | gzip > uClibc-locale-030818.tgz if [[ -s $BUILDDIR/sources/MISSING_FILES.DMP ]]; then echo -e "\n\n${tab_}${RED} One or more files were not retrieved.\n${tab_} Check for names ${OFF}\n\n" fi } #----------------------------# _IS_() { # Function to test build scripts names #----------------------------# # Returns substr $2 or null str # Must use string testing case $1 in *$2*) echo "$2" ;; *) echo "" ;; esac } #----------------------------# chapter4_Makefiles() { # Initialization of the system #----------------------------# local TARGET LOADER echo "${YELLOW} Processing Chapter-4 scripts ${OFF}" # Define a few model dependant variables if [[ ${MODEL} = "uclibc" ]]; then TARGET="tools-linux-uclibc"; LOADER="ld-uClibc.so.0" else TARGET="tools-linux-gnu"; LOADER="ld-linux.so.2" fi # 022- # If /home/hlfs is already present in the host, we asume that the # hlfs user and group are also presents in the host, and a backup # of their bash init files is made. ( cat << EOF 020-creatingtoolsdir: @\$(call echo_message, Building) @mkdir -v \$(HLFS)/tools && \\ rm -fv /tools && \\ ln -sv \$(HLFS)/tools / @if [ ! -d \$(HLFS)/sources ]; then \\ mkdir \$(HLFS)/sources; \\ fi; @chmod a+wt \$(HLFS)/sources && \\ touch \$@ 021-addinguser: 020-creatingtoolsdir @\$(call echo_message, Building) @if [ ! -d /home/hlfs ]; then \\ groupadd hlfs; \\ useradd -s /bin/bash -g hlfs -m -k /dev/null hlfs; \\ else \\ touch user-hlfs-exist; \\ fi; @chown hlfs \$(HLFS)/tools && \\ chown hlfs \$(HLFS)/sources && \\ touch \$@ 022-settingenvironment: 021-addinguser @\$(call echo_message, Building) @if [ -f /home/hlfs/.bashrc -a ! -f /home/hlfs/.bashrc.XXX ]; then \\ mv -v /home/hlfs/.bashrc /home/hlfs/.bashrc.XXX; \\ fi; @if [ -f /home/hlfs/.bash_profile -a ! -f /home/hlfs/.bash_profile.XXX ]; then \\ mv -v /home/hlfs/.bash_profile /home/hlfs/.bash_profile.XXX; \\ fi; @echo "set +h" > /home/hlfs/.bashrc && \\ echo "umask 022" >> /home/hlfs/.bashrc && \\ echo "HLFS=$(HLFS)" >> /home/hlfs/.bashrc && \\ echo "LC_ALL=POSIX" >> /home/hlfs/.bashrc && \\ echo "PATH=/tools/bin:/bin:/usr/bin" >> /home/hlfs/.bashrc && \\ echo "export HLFS LC_ALL PATH" >> /home/hlfs/.bashrc && \\ echo "" >> /home/hlfs/.bashrc && \\ echo "target=$(uname -m)-${TARGET}" >> /home/hlfs/.bashrc && \\ echo "ldso=/tools/lib/${LOADER}" >> /home/hlfs/.bashrc && \\ echo "export target ldso" >> /home/hlfs/.bashrc && \\ echo "source $JHAHLFSDIR/envars" >> /home/hlfs/.bashrc && \\ chown hlfs:hlfs /home/hlfs/.bashrc && \\ touch envars && \\ touch \$@ EOF ) >> $MKFILE.tmp } #----------------------------# chapter5_Makefiles() { # Bootstrap or temptools phase #----------------------------# echo "${YELLOW} Processing Chapter-5 scripts${OFF}" for file in chapter05/* ; do # Keep the script file name this_script=`basename $file` # Skip this script depending on jhahlfs.conf flags set. case $this_script in # If no testsuites will be run, then TCL, Expect and DejaGNU aren't needed *tcl* ) [[ "$TOOLCHAINTEST" = "0" ]] && continue; ;; *expect* ) [[ "$TOOLCHAINTEST" = "0" ]] && continue; ;; *dejagnu* ) [[ "$TOOLCHAINTEST" = "0" ]] && continue; ;; # Test if the stripping phase must be skipped *stripping* ) [[ "$STRIP" = "0" ]] && continue ;; # Select the appropriate library *glibc*) [[ ${MODEL} = "uclibc" ]] && continue ;; *uclibc*) [[ ${MODEL} = "glibc" ]] && continue ;; *) ;; esac # First append each name of the script files to a list (this will become # the names of the targets in the Makefile chapter5="$chapter5 $this_script" # Grab the name of the target (minus the -headers or -cross in the case of gcc # and binutils in chapter 5) name=`echo $this_script | sed -e 's@[0-9]\{3\}-@@' -e 's@-cross@@' -e 's@-headers@@'` # >>>>>>>>>> U G L Y <<<<<<<<< # Adjust 'name' and patch a few scripts on the fly.. case $name in linux-libc) name=linux-libc-headers ;; uclibc) # this sucks as method to deal with gettext/libint inside uClibc sed 's@^cd gettext-runtime@cd ../gettext-*/gettext-runtime@' -i chapter05/$this_script ;; gcc) # to compensate for the compiler test inside gcc (which fails), disable error trap sed 's@^gcc -o test test.c@set +e; gcc -o test test.c@' -i chapter05/$this_script ;; esac # Set the dependency for the first target. if [ -z $PREV ] ; then PREV=022-settingenvironment ; fi #--------------------------------------------------------------------# # >>>>>>>> START BUILDING A Makefile ENTRY <<<<<<<< # #--------------------------------------------------------------------# # # Drop in the name of the target on a new line, and the previous target # as a dependency. Also call the echo_message function. echo -e "\n$this_script: $PREV @\$(call echo_message, Building)" >> $MKFILE.tmp # Find the version of the command files, if it corresponds with the building of # a specific package vrs=`grep "^$name-version" $JHAHLFSDIR/packages | sed -e 's/.* //' -e 's/"//g'` # If $vrs isn't empty, we've got a package... if [ "$vrs" != "" ] ; then # Deal with non-standard names case $name in tcl) FILE="$name$vrs-src.tar" ;; uclibc) FILE="uClibc-$vrs.tar" ;; gcc) FILE=gcc-core-$vrs.tar ;; *) FILE="$name-$vrs.tar" ;; esac # Insert instructions for unpacking the package and to set the PKGDIR variable. ( cat << EOF @\$(call unpack,$FILE) @ROOT=\`head -n1 /tmp/unpacked | sed 's@^./@@;s@/.*@@'\` && \\ chown -R hlfs \$(HLFS)\$(SRC)/\$\$ROOT && \\ echo "export PKGDIR=\$(HLFS)\$(SRC)/\$\$ROOT" > envars && \\ EOF ) >> $MKFILE.tmp fi case $this_script in *binutils* ) # Dump the path to sources directory for later removal echo -e '\techo "$(HLFS)$(SRC)/$$ROOT" >> sources-dir' >> $MKFILE.tmp ;; *adjusting* ) # For the Adjusting phase we must to cd to the binutils-build directory. echo -e '\t@echo "export PKGDIR=$(HLFS)$(SRC)/binutils-build" > envars' >> $MKFILE.tmp ;; * ) # Everything else, add a true statment so we don't confuse make echo -e '\ttrue' >> $MKFILE.tmp ;; esac # Insert date and disk usage at the top of the log file, the script run # and date and disk usage again at the bottom of the log file. ( cat << EOF @echo -e "\n\`date\`\n\nKB: \`du -sk --exclude={0,1}??-* \$(HLFS)\`\n" >logs/$this_script && \\ su - hlfs -c "source /home/hlfs/.bashrc && $JHAHLFSDIR/commands/$file" >>logs/$this_script 2>&1 && \\ echo -e "\n\`date\`\n\nKB: \`du -sk --exclude={0,1}??-* \$(HLFS)\`\n" >>logs/$this_script EOF ) >> $MKFILE.tmp # Remove the build directory(ies) except if the package build fails # (so we can review config.cache, config.log, etc.) # For Binutils the sources must be retained for some time. if [ "$vrs" != "" ] ; then if [[ ! `_IS_ $this_script binutils` ]]; then ( cat << EOF @ROOT=\`head -n1 /tmp/unpacked | sed 's@^./@@;s@/.*@@'\` && \\ rm -r \$(HLFS)\$(SRC)/\$\$ROOT && \\ if [ -e \$(HLFS)\$(SRC)/$name-build ]; then \\ rm -r \$(HLFS)\$(SRC)/$name-build; \\ fi; EOF ) >> $MKFILE.tmp fi fi # Remove the Binutils pass 1 sources after a successful Adjusting phase. if [[ `_IS_ $this_script adjusting` ]] ; then ( cat << EOF @rm -r \`cat sources-dir\` && \\ rm -r \$(HLFS)\$(SRC)/binutils-build && \\ rm sources-dir EOF ) >> $MKFILE.tmp fi # Include a touch of the target name so make can check if it's already been made. echo -e '\t@touch $@' >> $MKFILE.tmp # #--------------------------------------------------------------------# # >>>>>>>> END OF Makefile ENTRY <<<<<<<< # #--------------------------------------------------------------------# # Keep the script file name for Makefile dependencies. PREV=$this_script done # end for file in chapter05/* } #----------------------------# chapter6_Makefiles() { # sysroot or chroot build phase #----------------------------# local TARGET LOADER # # Set these definitions early and only once # if [[ ${MODEL} = "uclibc" ]]; then TARGET="pc-linux-uclibc"; LOADER="ld-uClibc.so.0" else TARGET="pc-linux-gnu"; LOADER="ld-linux.so.2" fi echo -e "${YELLOW} Processing Chapter-6 scripts ${OFF}" for file in chapter06/* ; do # Keep the script file name this_script=`basename $file` # Skip this script depending on jhahlfs.conf flags set. case $this_script in # We'll run the chroot commands differently than the others, so skip them in the # dependencies and target creation. *chroot* ) continue ;; # Test if the stripping phase must be skipped *-stripping* ) [[ "$STRIP" = "0" ]] && continue ;; # Select the appropriate library *glibc*) [[ ${MODEL} = "uclibc" ]] && continue ;; *uclibc*) [[ ${MODEL} = "glibc" ]] && continue ;; *) ;; esac # First append each name of the script files to a list (this will become # the names of the targets in the Makefile chapter6="$chapter6 $this_script" # Grab the name of the target name=`echo $this_script | sed -e 's@[0-9]\{3\}-@@'` # # Sed replacement for 'nodump' tag in xml scripts until Manuel has a chance to fix them # case $name in kernfs) # Remove sysctl code if host does not have grsecurity enabled if [[ "$GRSECURITY_HOST" = "0" ]]; then sed '/sysctl/d' -i chapter06/$this_script fi ;; module-init-tools) if [[ "$TEST" = "0" ]]; then # This needs rework.... sed '/make distclean/d' -i chapter06/$this_script fi ;; glibc) # PATCH.. Turn off error trapping for the remainder of the script. sed 's|^make install|make install; set +e|' -i chapter06/$this_script ;; uclibc) # PATCH.. sed 's/EST5EDT/${TIMEZONE}/' -i chapter06/$this_script # PATCH.. Cannot use interactive programs/scripts. sed 's/make menuconfig/make oldconfig/' -i chapter06/$this_script sed 's@^cd gettext-runtime@cd ../gettext-*/gettext-runtime@' -i chapter06/$this_script ;; gcc) # PATCH.. sed 's/rm /rm -f /' -i chapter06/$this_script ;; esac #--------------------------------------------------------------------# # >>>>>>>> START BUILDING A Makefile ENTRY <<<<<<<< # #--------------------------------------------------------------------# # # Drop in the name of the target on a new line, and the previous target # as a dependency. Also call the echo_message function. echo -e "\n$this_script: $PREV @\$(call echo_message, Building)" >> $MKFILE.tmp # Find the version of the command files, if it corresponds with the building of # a specific package vrs=`grep "^$name-version" $JHAHLFSDIR/packages | sed -e 's/.* //' -e 's/"//g'` # If $vrs isn't empty, we've got a package... # Insert instructions for unpacking the package and changing directories if [ "$vrs" != "" ] ; then # Deal with non-standard names case $name in tcl) FILE="$name$vrs-src.tar.*" ;; uclibc) FILE="uClibc-$vrs.tar.*" ;; gcc) FILE="gcc-core-$vrs.tar.*" ;; *) FILE="$name-$vrs.tar.*" ;; esac ( cat << EOF @\$(call unpack2,$FILE) @ROOT=\`head -n1 /tmp/unpacked | sed 's@^./@@;s@/.*@@'\` && \\ echo "export PKGDIR=\$(SRC)/\$\$ROOT" > envars && \\ echo "export target=$(uname -m)-${TARGET}" >> envars && \\ echo "export ldso=/lib/${LOADER}" >> envars EOF ) >> $MKFILE.tmp fi case $this_script in *readjusting*) # For the Re-Adjusting phase we must to cd to the binutils-build directory. echo -e '\t@echo "export PKGDIR=$(SRC)/binutils-build" > envars' >> $MKFILE.tmp ;; *glibc* | *uclibc* ) # For glibc and uClibc we need to set TIMEZONE envar. echo -e '\t@echo "export TIMEZONE=$(TIMEZONE)" >> envars' >> $MKFILE.tmp ;; *groff* ) # For Groff we need to set PAGE envar. echo -e '\t@echo "export PAGE=$(PAGE)" >> envars' >> $MKFILE.tmp ;; esac # In the mount of kernel filesystems we need to set HLFS and not to use chroot. if [[ `_IS_ $this_script kernfs` ]] ; then ( cat << EOF @echo -e "\n\`date\`\n\nKB: \`du -sk --exclude={0,1}??-* \$(HLFS)\`\n" >logs/$this_script && \\ export HLFS=\$(HLFS) && commands/$file >>logs/$this_script 2>&1 && \\ echo -e "\n\`date\`\n\nKB: \`du -sk --exclude={0,1}??-* \$(HLFS)\`\n" >>logs/$this_script EOF ) >> $MKFILE.tmp # The rest of Chapter06 else ( cat << EOF @echo -e "\n\`date\`\n\nKB: \`du -skx --exclude={0,1}??-* \$(HLFS)\`\n" >logs/$this_script && \\ \$(CHROOT1) 'cd /jhahlfs && source envars && /jhahlfs/commands/$file >>/jhahlfs/logs/$this_script 2>&1' && \\ echo -e "\n\`date\`\n\nKB: \`du -skx --exclude={0,1}??-* \$(HLFS)\`\n" >>logs/$this_script EOF ) >> $MKFILE.tmp fi # Remove the build directory(ies) except if the package build fails. if [ "$vrs" != "" ] ; then ( cat << EOF @ROOT=\`head -n1 /tmp/unpacked | sed 's@^./@@;s@/.*@@'\` && \\ rm -r \$(HLFS)\$(SRC)/\$\$ROOT && \\ if [ -e \$(HLFS)\$(SRC)/$name-build ]; then \\ rm -r \$(HLFS)\$(SRC)/$name-build; \\ fi; EOF ) >> $MKFILE.tmp fi # Remove the Binutils pass 2 sources after a successful Re-Adjusting phase. if [[ `_IS_ $this_script readjusting` ]] ; then ( cat << EOF @rm -r \`cat sources-dir\` && \\ rm -r \$(HLFS)\$(SRC)/binutils-build && \\ rm sources-dir EOF ) >> $MKFILE.tmp fi # Include a touch of the target name so make can check if it's already been made. echo -e '\t@touch $@' >> $MKFILE.tmp # #--------------------------------------------------------------------# # >>>>>>>> END OF Makefile ENTRY <<<<<<<< # #--------------------------------------------------------------------# # Keep the script file name for Makefile dependencies. PREV=$this_script done # end for file in chapter06/* } #----------------------------# chapter7_Makefiles() { # Create a bootable system.. kernel, bootscripts..etc #----------------------------# echo "${YELLOW} Processing Chapter-7 scripts ${OFF}" for file in chapter07/*; do # Keep the script file name this_script=`basename $file` # Grub must be configured manually. # The filesystems can't be unmounted via Makefile and the user # should enter the chroot environment to create the root # password, edit several files and setup Grub. case $this_script in *grub) continue ;; *reboot) continue ;; *console) continue ;; # Use the file generated by lfs-bootscripts *kernel) # How does Manuel add this string to the file.. sed 's|cd \$PKGDIR.*||' -i chapter07/$this_script # You cannot run menuconfig from within the makefile sed 's|make menuconfig|make oldconfig|' -i chapter07/$this_script # The files in the conglomeration dir are xxx.bz2 sed 's|.patch.gz|.patch.bz2|' -i chapter07/$this_script sed 's|gunzip|bunzip2|' -i chapter07/$this_script # If defined include the keymap in the kernel if [[ -n "$KEYMAP" ]]; then sed "s|^loadkeys -m.*>|loadkeys -m $KEYMAP >|" -i chapter07/$this_script else sed '/loadkeys -m/d' -i chapter07/$this_script sed '/drivers\/char/d' -i chapter07/$this_script fi # If no .config file is supplied, the kernel build is skipped [[ -z $CONFIG ]] && continue ;; *usage) # The script bombs, disable error trapping sed 's|set -e|set +e|' -i chapter07/$this_script ;; *profile) # Add the config values to the script sed "s|LC_ALL=\*\*EDITME.*EDITME\*\*|LC_ALL=$LC_ALL|" -i chapter07/$this_script sed "s|LANG=\*\*EDITME.*EDITME\*\*|LANG=$LANG|" -i chapter07/$this_script ;; esac # First append then name of the script file to a list (this will become # the names of the targets in the Makefile chapter7="$chapter7 $this_script" #--------------------------------------------------------------------# # >>>>>>>> START BUILDING A Makefile ENTRY <<<<<<<< # #--------------------------------------------------------------------# # # Drop in the name of the target on a new line, and the previous target # as a dependency. Also call the echo_message function. echo -e "\n$this_script: $PREV @\$(call echo_message, Building)" >> $MKFILE.tmp if [[ `_IS_ $this_script bootscripts` ]] ; then vrs=`grep "^lfs-bootscripts-version" $JHAHLFSDIR/packages | sed -e 's/.* //' -e 's/"//g'` FILE="lfs-bootscripts-$vrs.tar.*" # The bootscript pkg references both lfs AND blfs bootscripts... # see XML script for other additions to bootscripts file # PATCH vrs=`grep "^blfs-bootscripts-version" $JHAHLFSDIR/packages | sed -e 's/.* //' -e 's/"//g'` sed "s|make install$|make install; cd ../blfs-bootscripts-$vrs|" -i chapter07/$this_script ( cat << EOF @\$(call unpack2,$FILE) @ROOT=\`head -n1 /tmp/unpacked | sed 's@^./@@;s@/.*@@'\` && \\ echo "export PKGDIR=\$(SRC)/\$\$ROOT" > envars && \\ echo "\$(HLFS)\$(SRC)/blfs-bootscripts-$vrs" > sources-dir EOF ) >> $MKFILE.tmp fi if [[ `_IS_ $this_script kernel` ]] ; then # not much really, script does everything.. echo -e "\t@cp -f $CONFIG \$(HLFS)/sources/kernel-config" >> $MKFILE.tmp fi # Check if we have a real /etc/fstab file if [[ `_IS_ $this_script fstab` ]] && [[ -n "$FSTAB" ]] ; then ( cat << EOF @echo -e "\n\`date\`\n\nKB: \`du -skx --exclude={0,1}??-* \$(HLFS)\`\n" >logs/$this_script && \\ cp -v $FSTAB \$(HLFS)/etc/fstab >>logs/$this_script 2>&1 && \\ echo -e "\n\`date\`\n\nKB: \`du -skx --exclude={0,1}??-* \$(HLFS)\`\n" >>logs/$this_script EOF ) >> $MKFILE.tmp else # Initialize the log and run the script ( cat << EOF @echo -e "\n\`date\`\n\nKB: \`du -skx --exclude={0,1}??-* \$(HLFS)\`\n" >logs/$this_script && \\ \$(CHROOT2) 'cd /jhahlfs && source envars && /jhahlfs/commands/$file >>/jhahlfs/logs/$this_script 2>&1' && \\ echo -e "\n\`date\`\n\nKB: \`du -skx --exclude={0,1}??-* \$(HLFS)\`\n" >>logs/$this_script EOF ) >> $MKFILE.tmp fi # Remove the build directory except if the package build fails. if [[ `_IS_ $this_script bootscripts` ]]; then ( cat << EOF @ROOT=\`head -n1 /tmp/unpacked | sed 's@^./@@;s@/.*@@'\` && \\ rm -r \$(HLFS)\$(SRC)/\$\$ROOT @rm -r \`cat sources-dir\` && \\ rm sources-dir EOF ) >> $MKFILE.tmp fi # Include a touch of the target name so make can check if it's already been made. echo -e '\t@touch $@' >> $MKFILE.tmp # #--------------------------------------------------------------------# # >>>>>>>> END OF Makefile ENTRY <<<<<<<< # #--------------------------------------------------------------------# # Keep the script file name for Makefile dependencies. PREV=$this_script done # for file in chapter07/* } #----------------------------# build_Makefile() { # Construct a Makefile from the book scripts #----------------------------# echo -e "${GREEN}Creating Makefile... ${OFF}" cd $JHAHLFSDIR/commands # Start with a clean Makefile.tmp file >$MKFILE.tmp chapter4_Makefiles chapter5_Makefiles chapter6_Makefiles chapter7_Makefiles # Add a header, some variables and include the function file # to the top of the real Makefile. ( cat << EOF $HEADER SRC= /sources HLFS= $BUILDDIR PAGE= $PAGE TIMEZONE= $TIMEZONE include hlfs-functions EOF ) > $MKFILE # Add chroot commands i=1 for file in chapter06/*chroot* ; do chroot=`cat $file | sed -e '/#!\/bin\/sh/d' \ -e '/^export/d' \ -e '/^logout/d' \ -e 's@ \\\@ @g' | tr -d '\n' | sed -e 's/ */ /g' \ -e 's|\\$|&&|g' \ -e 's|exit||g' \ -e 's|$| -c|' \ -e 's|"$$HLFS"|$(HLFS)|'\ -e 's|set -e||'` echo -e "CHROOT$i= $chroot\n" >> $MKFILE i=`expr $i + 1` done # Drop in the main target 'all:' and the chapter targets with each sub-target # as a dependency. ( cat << EOF all: chapter4 chapter5 chapter6 chapter7 @\$(call echo_finished,$VERSION) chapter4: 020-creatingtoolsdir 021-addinguser 022-settingenvironment chapter5: chapter4 $chapter5 restore-hlfs-env chapter6: chapter5 $chapter6 chapter7: chapter6 $chapter7 clean-all: clean rm -rf ./{commands,logs,Makefile,dump-hlfs-scripts.xsl,functions,packages,patches} clean: clean-chapter7 clean-chapter6 clean-chapter5 clean-chapter4 clean-chapter4: -if [ ! -f user-hlfs-exist ]; then \\ userdel hlfs; \\ rm -rf /home/hlfs; \\ fi; rm -rf \$(HLFS)/tools rm -f /tools rm -f envars user-hlfs-exist rm -f 02* logs/02*.log clean-chapter5: rm -rf \$(HLFS)/tools/* rm -f $chapter5 restore-hlfs-env sources-dir cd logs && rm -f $chapter5 && cd .. clean-chapter6: -umount \$(HLFS)/sys -umount \$(HLFS)/proc -umount \$(HLFS)/dev/shm -umount \$(HLFS)/dev/pts -umount \$(HLFS)/dev rm -rf \$(HLFS)/{bin,boot,dev,etc,home,lib,media,mnt,opt,proc,root,sbin,srv,sys,tmp,usr,var} rm -f $chapter6 cd logs && rm -f $chapter6 && cd .. clean-chapter7: rm -f $chapter7 cd logs && rm -f $chapter7 && cd .. restore-hlfs-env: @\$(call echo_message, Building) @if [ -f /home/hlfs/.bashrc.XXX ]; then \\ mv -fv /home/hlfs/.bashrc.XXX /home/hlfs/.bashrc; \\ fi; @if [ -f /home/hlfs/.bash_profile.XXX ]; then \\ mv -v /home/hlfs/.bash_profile.XXX /home/hlfs/.bash_profile; \\ fi; @chown hlfs:hlfs /home/hlfs/.bash* && \\ touch \$@ EOF ) >> $MKFILE # Bring over the items from the Makefile.tmp cat $MKFILE.tmp >> $MKFILE rm $MKFILE.tmp echo -ne "${GREEN}done\n${OFF}" } #----------------------------# run_make() { # Execute the newly constructed Makefile #----------------------------# # Test if make must be run. if [ "$RUNMAKE" = "1" ] ; then # Test to make sure we're running the build as root if [ "$UID" != "0" ] ; then echo "You must be logged in as root to successfully build HLFS." exit 1 fi # Build the system if [ -e $MKFILE ] ; then echo -ne "Building the HLFS system...\n" cd $JHAHLFSDIR && make echo -ne "done\n" fi fi } ################################### ### MAIN ### ################################### # Evaluate any command line switches while test $# -gt 0 ; do case $1 in --version | -V ) 'clear'; echo "$version" ; exit 0; ;; --help | -h ) usage | less 'clear' ; exit 0 ;; --HLFS-version | -L ) test $# = 1 && eval "$exit_missing_arg" shift case $1 in dev* | SVN | trunk ) BOOK="" # necessary to overide any value set inside jhahlfs.conf WC= HLFSVRS=development ;; * ) echo "$1 is an unsupported version at this time." exit 1 ;; esac ;; --directory | -d ) test $# = 1 && eval "$exit_missing_arg" shift BUILDDIR=$1 JHAHLFSDIR=$BUILDDIR/jhahlfs LOGDIR=$JHAHLFSDIR/logs MKFILE=$JHAHLFSDIR/Makefile ;; --working-copy | -W ) test $# = 1 && eval "$exit_missing_arg" shift if [ -f $1/patches.ent ] ; then WC=1 BOOK=$1 else echo -e "\nLook like $1 isn't a supported working copy." echo -e "Verify your selection and the command line.\n" exit 1 fi ;; --get-packages | -P ) HPKG=1 ;; --run-make | -M ) RUNMAKE=1 ;; --rebuild ) CLEAN=1 ;; --readme ) 'clear' echo "$_inline_doc" | less 'clear'; exit ;; --fstab ) test $# = 1 && eval "$exit_missing_arg" shift if [ -f $1 ] ; then FSTAB=$1 else echo -e "\nFile $1 not found. Verify your command line.\n" exit 1 fi ;; --kernel-config | -C ) test $# = 1 && eval "$exit_missing_arg" shift if [ -f $1 ] ; then CONFIG=$1 else echo -e "\nFile $1 not found. Verify your command line.\n" exit 1 fi ;; * ) echo "$usage" exit 1 ;; esac shift done # Prevents setting "-d /" by mistake. if [ $BUILDDIR = / ] ; then echo -ne "\nThe root directory can't be used to build HLFS.\n\n" exit 1 fi # If $BUILDDIR has subdirectories like tools/ or bin/, stop the run # and notify the user about that. if [ -d $BUILDDIR/tools -o -d $BUILDDIR/bin ] && [ -z $CLEAN ] ; then no_empty_builddir fi # If requested, clean the build directory clean_builddir # Find the download client to use, if not already specified. if [ -z $DL ] ; then if [ `type -p wget` ] ; then DL=wget elif [ `type -p curl` ] ; then DL=curl else eval "$no_dl_client" fi fi # Set the document location.. # if set by conf file leave it alone otherwise load the specified version BOOK=${BOOK:=hlfs-$HLFSVRS} [[ ! -d $JHAHLFSDIR ]] && mkdir -pv $JHAHLFSDIR [[ ! -d $LOGDIR ]] && mkdir -v $LOGDIR if [[ "$PWD" != "$JHAHLFSDIR" ]]; then cp -v $FILES $JHAHLFSDIR/ sed 's,FAKEDIR,'$BOOK',' $XSL > $JHAHLFSDIR/dump-hlfs-scripts.xsl export XSL=$JHAHLFSDIR/dump-hlfs-scripts.xsl fi >$LOGDIR/$LOG # Check for minumum gcc and kernel versions check_requirements 1 # 0/1 0-do not display values. validate_config 1 # 0/1 0-do not display values get_book build_Makefile run_make