2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2008 Michael Tremer & Christian Schmidt #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
21 ###############################################################################
25 ###############################################################################
28 BASENAME
=$
(basename $0)
30 # Debian specific settings
31 if [ ! -e /etc
/debian_version
]; then
34 if [ -x /usr
/bin
/realpath
]; then
35 FULLPATH
=$
(/usr
/bin
/realpath
$0)
37 echo "ERROR: Need to do apt-get install realpath"
42 BASEDIR
=$
(echo $FULLPATH |
sed "s/\/$BASENAME//g")
45 .
$BASEDIR/tools
/make-constants
# Load this very early
46 .
$BASEDIR/tools
/make-beautify
48 mkdir
$BASEDIR/log_
${TARGET}/ 2>/dev
/null
50 ################################################################################
52 # Necessary shell functions #
54 ################################################################################
56 .
$BASEDIR/tools
/make-buildspy
57 .
$BASEDIR/tools
/make-check
58 .
$BASEDIR/tools
/make-batch
59 .
$BASEDIR/tools
/make-compilers
60 .
$BASEDIR/tools
/make-git
61 .
$BASEDIR/tools
/make-packages
62 .
$BASEDIR/tools
/make-rootfiles
63 .
$BASEDIR/tools
/make-vm
64 .
$BASEDIR/tools
/make-cron
68 if [ "$RETVAL" -eq "0" ]; then
77 sleep 0.3 # Wait one second for finish of processes
78 for fs
in $
(mount |
grep $BASEDIR/build_
${TARGET} |
awk '{print $3}'); do
79 umount
$fs 2>/dev
/null
;
81 } # End of stdumount()
87 if [ -n "$LOGFILE" ]; then
88 echo "$(date -u '+%b %e %T') ERROR: $*" >> $LOGFILE
89 build_spy log $
(tail -n16 $LOGFILE |
$BASEDIR/tools
/base64
)
93 rm -f $RUNNING 2>/dev
/null
95 } # End of exiterror()
98 local logfile
=$LOGFILE
101 logfile
=$BASEDIR/log_
$TARGET/_build
.00-distcc.log
105 echo "$(date -u '+%b %e %T') $*" >> $logfile
108 ################################################################################
109 # This is the function that sets the environment of a chroot and enters it #
110 ################################################################################
112 PATH
=${TOOLS_DIR}/usr/bin:/bin:/usr/bin:/sbin:/usr/sbin:${TOOLS_DIR}/bin:/usr/${MACHINE_REAL}-linux/bin
114 if [ ! -e $LFS/usr
/src
/lfs
/ ]; then
115 exiterror
"No such file or directory: $LFS/usr/src/lfs/"
118 COMMAND
=${@-bash} # Run command, given as parameters.
120 echo -ne "Entering ${BOLD}$MACHINE${NORMAL} LFS chroot, type exit to return to host environment\n"
122 chroot
$LFS $TOOLS_DIR/bin
/env
-i \
125 PS1
="${BOLD}[chroot-${TARGET}(${MACHINE})]${NORMAL} \u:\w\$ " \
127 CONFIG_ROOT
=${CONFIG_ROOT} \
132 CCACHE_DIR
=/usr
/src
/ccache \
133 CCACHE_PREFIX
=${CCACHE_PREFIX} \
134 CCACHE_HASHDIR
=${CCACHE_HASHDIR} \
135 DISTCC_DIR
=/usr
/src
/distcc \
136 PARALLELISMFLAGS
=$PARALLELISMFLAGS \
138 TOOLS_DIR
=$TOOLS_DIR \
139 INSTALLER_DIR
=$INSTALLER_DIR \
141 MACHINE_REAL
="$MACHINE_REAL" \
143 CXXFLAGS
="$CXXFLAGS" \
144 IFS_HOST
="$IFS_HOST" \
145 IFS_TARGET
="$IFS_TARGET" \
148 STAGE_ORDER
=$STAGE_ORDER \
149 LOGFILE
=$
(echo $LOGFILE |
sed "s,$BASEDIR,/usr/src,g") \
152 if [ $?
-ne 0 ]; then
153 exiterror
"chroot error"
157 } # End of entershell()
161 ################################################################################
162 # Common checking before entering the chroot and compilling #
163 # Return:0 caller can continue #
164 # :1 skip (nothing to do) #
165 # or fail if no script file found #
166 ################################################################################
173 if [ ! -f $BASEDIR/lfs
/$1 ]; then
174 exiterror
"No such file or directory: $BASEDIR/lfs/$1"
177 local PKG_VER
=$
(get_pkg_ver
$BASEDIR/lfs
/$1)
178 beautify make_pkg
"$PKG_VER $*"
182 for i
in $SKIP_PACKAGE_LIST; do
183 if [ "$i" == "$1" ]; then
189 # On debug build, we don't strip
190 if [ "$STAGE" != "toolchain" -a \
191 "$1" == "strip" -a "$BUILD_DEBUG" == "1" ]; then
196 # Don't create addons?
197 local EXTRA
=$
(grep ^EXTRA
$BASEDIR/lfs
/$1 |
awk '{print $3}')
198 if [ "$EXTRA" == "yes" ] && [ "$BUILD_EXTRAS" == "0" ]; then
203 # Don't create debugging tools?
204 local DEBUG
=$
(grep ^DEBUG
$BASEDIR/lfs
/$1 |
awk '{print $3}')
205 if [ "$DEBUG" == "yes" ] && [ "$BUILD_DEBUG" == "0" ]; then
210 # Searching for dependencies
212 for dep
in $
(pkg_deps
$1); do
214 for package
in $PACKAGES_DONE; do
215 if [ "$dep" = "$package" ]; then
220 [ "$found" = "0" ] && message
="$message $dep"
222 if [ "$message" != "" ]; then
223 message
="Deps are missing: $message"
224 if [ "$EXTRA" = "yes" ]; then
225 echo -ne "${WARN}${message}${NORMAL}"
226 beautify message SKIP
233 cd $BASEDIR/lfs
&& make -s -f $
* MACHINE
=$MACHINE LFS_BASEDIR
=$BASEDIR MESSAGE
="$1\t " download
>> $LOGFILE 2>&1
234 if [ $?
-ne 0 ]; then
235 exiterror
"Download error in $1"
241 } # End of lfsmakecommoncheck()
243 ################################################################################
244 # This is the function that builds every package in stage "toolchain" #
245 ################################################################################
247 lfsmakecommoncheck $
*
248 [ $?
== 1 ] && return 0
250 local PKG_VER
=$
(get_pkg_ver
$BASEDIR/lfs
/$1)
252 local EXTRA_MAKE
=$EXTRA_MAKE
254 local PKG_TIME_START
=$
(date +%s
)
255 cd $BASEDIR/lfs
&& $EXTRA_MAKE make -f $
* \
256 CONFIG_ROOT
=$CONFIG_ROOT \
258 TOOLS_DIR
=$TOOLS_DIR \
260 MACHINE_REAL
="$MACHINE_REAL" \
261 IFS_HOST
="$IFS_HOST" \
262 IFS_TARGET
="$IFS_TARGET" \
264 LFS_BASEDIR
=$BASEDIR \
266 INSTALLER_DIR
=$INSTALLER_DIR \
267 PARALLELISMFLAGS
=$PARALLELISMFLAGS \
270 STAGE_ORDER
=$STAGE_ORDER \
271 install >> $LOGFILE 2>&1
273 local COMPILE_SUCCESS
=$?
274 local PKG_TIME_END
=$
(date +%s
)
276 if [ $COMPILE_SUCCESS -ne 0 ]; then
277 beautify result FAIL $
[ $PKG_TIME_END - $PKG_TIME_START ] $1 $PKG_VER $STAGE_ORDER $STAGE
278 exiterror
"Building $*"
280 beautify result DONE $
[ $PKG_TIME_END - $PKG_TIME_START ] $1 $PKG_VER $STAGE_ORDER $STAGE
281 PACKAGES_DONE
="$PACKAGES_DONE $1"
285 } # End of toolchain_make()
287 ################################################################################
288 # This is the function that builds every package in stage "base" and "ipfire" #
289 ################################################################################
291 lfsmakecommoncheck $
*
292 [ $?
== 1 ] && return 0
294 local PKG_VER
=$
(get_pkg_ver
$BASEDIR/lfs
/$1)
296 local EXTRA_MAKE
=$EXTRA_MAKE
297 # When cross-compiling, make sure the kernel is compiled for the target
298 [ "$MACHINE" != "$MACHINE_REAL" -a "$1" == "linux" ] && unset EXTRA_MAKE
300 # Also, make sure external kernel modules are compiled 64bit
301 if grep -qEi 'KERNEL_MOD = yes' $1 ; then
305 local PKG_TIME_START
=$
(date +%s
)
306 chroot
$LFS $TOOLS_DIR/bin
/env
-i \
311 CONFIG_ROOT
=${CONFIG_ROOT} \
316 CCACHE_DIR
=/usr
/src
/ccache \
317 CCACHE_PREFIX
=${CCACHE_PREFIX} \
318 CCACHE_HASHDIR
=${CCACHE_HASHDIR} \
319 DISTCC_DIR
=/usr
/src
/distcc \
320 PARALLELISMFLAGS
=$PARALLELISMFLAGS \
322 TOOLS_DIR
=$TOOLS_DIR \
323 INSTALLER_DIR
=$INSTALLER_DIR \
324 CDROM_DIR
=$CDROM_DIR \
325 IMAGES_DIR
=$IMAGES_DIR \
327 MACHINE_REAL
="$MACHINE_REAL" \
329 CXXFLAGS
="$CXXFLAGS" \
330 IFS_HOST
="$IFS_HOST" \
331 IFS_TARGET
="$IFS_TARGET" \
333 BUILD_DEBUG
=$BUILD_DEBUG \
334 BUILD_EXTRAS
=$BUILD_EXTRAS \
337 STAGE_ORDER
=$STAGE_ORDER \
339 IMAGENAME
=$IMAGENAME \
340 LOGFILE
=$
(echo $LOGFILE |
sed "s,$BASEDIR,/usr/src,g") \
341 bash
-x -c "cd /usr/src/lfs && \
342 $EXTRA_MAKE make -f $* LFS_BASEDIR=/usr/src install" >>$LOGFILE 2>&1
344 local COMPILE_SUCCESS
=$?
345 local PKG_TIME_END
=$
(date +%s
)
347 if [ $COMPILE_SUCCESS -ne 0 ]; then
348 beautify result FAIL $
[ $PKG_TIME_END - $PKG_TIME_START ] $1 $PKG_VER $STAGE_ORDER $STAGE
349 exiterror
"Building $*"
351 beautify result DONE $
[ $PKG_TIME_END - $PKG_TIME_START ] $1 $PKG_VER $STAGE_ORDER $STAGE
352 PACKAGES_DONE
="$PACKAGES_DONE $1"
356 } # End of ipfire_make()
358 ################################################################################
359 # This prepares the build environment #
360 ################################################################################
362 LOGFILE
=$BASEDIR/log_
${TARGET}/_build
.00-preparation.log
364 mkdir
-p $BASEDIR/log_
${TARGET}/01_toolchain
2>/dev
/null
365 mkdir
-p $BASEDIR/log_
${TARGET}/02_base
2>/dev
/null
366 mkdir
-p $BASEDIR/log_
${TARGET}/03_
${SNAME} 2>/dev
/null
367 mkdir
-p $BASEDIR/log_
${TARGET}/04_misc
2>/dev
/null
368 mkdir
-p $BASEDIR/log_
${TARGET}/05_installer
2>/dev
/null
369 mkdir
-p $BASEDIR/log_
${TARGET}/06_packages
2>/dev
/null
371 #############################################################################
372 # Are we running the right shell? #
373 #############################################################################
375 if [ ! "$BASH" ]; then
376 exiterror
"BASH environment variable is not set. You're probably running the wrong shell."
379 if [ -z "${BASH_VERSION}" ]; then
380 exiterror
"Not running BASH shell."
383 #############################################################################
384 # Trap on emergency exit #
385 #############################################################################
386 trap "exiterror 'Build process interrupted'" SIGINT SIGTERM SIGKILL SIGSTOP SIGQUIT
389 #############################################################################
390 # Resetting our nice level #
391 #############################################################################
392 echo -ne "Resetting our nice level to $NICE"
393 renice
$NICE $$
> /dev
/null
394 if [ $
(nice
) != "$NICE" ]; then
395 beautify message FAIL
396 exiterror
"Failed to set correct nice level"
398 beautify message DONE
402 if [ -x /usr
/bin
/schedtool
]; then
403 /usr
/bin
/schedtool
-B $$
404 if [ $?
-ne 0 ]; then
405 echo -ne "Setting kernel schedular to SCHED_BATCH"
406 beautify message FAIL
410 ##############################################################################
411 # Checking if running as root user #
412 ##############################################################################
413 if [ $
(id
-u) != 0 ]; then
414 echo -ne "Checking if we're running as root user"
415 beautify message FAIL
416 exiterror
"Not building as root"
420 ##############################################################################
421 # Checking for necessary temporary space #
422 ##############################################################################
423 BASE_DEV
=$
(df
-P -k $BASEDIR |
tail -n 1 |
awk '{ print $1 }')
424 BASE_ASPACE
=$
(df
-P -k $BASEDIR |
tail -n 1 |
awk '{ print $4 }')
425 if (( 2048000 > $BASE_ASPACE )); then
426 BASE_USPACE
=$
(du
-skx $BASEDIR |
awk '{print $1}')
427 if (( 2048000 - $BASE_USPACE > $BASE_ASPACE )); then
428 echo -ne "Checking for necessary space on disk $BASE_DEV"
429 beautify message FAIL
430 exiterror
"Not enough temporary space available, need at least 2GB on $BASE_DEV"
434 ##############################################################################
436 ##############################################################################
438 echo -ne "Embedded build"
439 if [ $EMB -eq 1 ]; then
441 check_loop || exiterror
"Can't build flash images on this machine."
448 ##############################################################################
449 # Checking CPU features #
450 ##############################################################################
452 check_supported_target
$TARGET || \
453 exiterror
"Your host doesn't have all needed cpu features for building \"$TARGET\""
455 ##############################################################################
456 # Building Linux From Scratch system configuration #
457 ##############################################################################
463 LFS
=$BASEDIR/build_
${TARGET}/${SNAME}
465 # Check /tools symlink
466 if [ -h $TOOLS_DIR ]; then
469 if [ ! -a $TOOLS_DIR ]; then
470 ln -s $BASEDIR/build_
${TARGET}/$TOOLS_DIR /
472 if [ ! -h $TOOLS_DIR ]; then
473 exiterror
"Could not create $TOOLS_DIR symbolic link."
480 unset CC CXX CPP LD_LIBRARY_PATH LD_PRELOAD
482 # Make some extra directories
483 mkdir
-p $BASEDIR/build_
${TARGET}/{$TOOLS_DIR,cdrom
,$INSTALLER_DIR,$IMAGES_DIR} 2>/dev
/null
484 mkdir
-p $BASEDIR/{cache
,ccache
,distcc
} 2>/dev
/null
485 mkdir
-p $BASEDIR/cache
/{toolchains
,patches
,tarballs
} 2>/dev
/null
486 mkdir
-p $LFS/{$TOOLS_DIR,usr
/src
} 2>/dev
/null
487 mkdir
-p $LFS/{dev
,etc
,proc
,sys
} 2>/dev
/null
488 mkdir
-p $LFS/dev
/pts
2>/dev
/null
489 mkdir
-p $LFS/usr
/src
/{cache
,config
,doc
,lfs
,log_
${TARGET},src
,ccache
,distcc
} 2>/dev
/null
490 mkdir
-p $LFS/{$INSTALLER_DIR,cdrom
,images
} 2>/dev
/null
492 mknod
-m 600 $BASEDIR/build
/dev
/console c
5 1 2>/dev
/null
493 mknod
-m 666 $BASEDIR/build
/dev
/null c
1 3 2>/dev
/null
495 # Make all sources and proc available under lfs build
496 mount
--bind /dev
$LFS/dev
497 mount
--bind /proc
$LFS/proc
498 mount
--bind /sys
$LFS/sys
499 mount
--bind $BASEDIR/cache
$LFS/usr
/src
/cache
500 mount
--bind $BASEDIR/ccache
$LFS/usr
/src
/ccache
501 mount
--bind $BASEDIR/distcc
$LFS/usr
/src
/distcc
502 mount
--bind $BASEDIR/config
$LFS/usr
/src
/config
503 mount
--bind $BASEDIR/doc
$LFS/usr
/src
/doc
504 mount
--bind $BASEDIR/lfs
$LFS/usr
/src
/lfs
505 mount
--bind $BASEDIR/log_
${TARGET} $LFS/usr
/src
/log_
${TARGET}
506 mount
--bind $BASEDIR/src
$LFS/usr
/src
/src
507 mount
--bind $BASEDIR/build_
${TARGET}/$TOOLS_DIR $LFS/$TOOLS_DIR
508 mount
--bind $BASEDIR/build_
${TARGET}/$CDROM_DIR $LFS/$CDROM_DIR
509 mount
--bind $BASEDIR/build_
${TARGET}/$INSTALLER_DIR $LFS/$INSTALLER_DIR
510 mount
--bind $BASEDIR/build_
${TARGET}/$IMAGES_DIR $LFS/$IMAGES_DIR
512 # Run LFS static binary creation scripts one by one
513 export CCACHE_DIR
=$BASEDIR/ccache
514 export CCACHE_HASHDIR
=1
515 export CCACHE_PREFIX
="distcc"
516 export DISTCC_DIR
=$BASEDIR/distcc
518 # Remove pre-install list of installed files in case user erase some files before rebuild
519 rm -f $LFS/usr
/src
/lsalr
2>/dev
/null
523 #a prebuilt toolchain package is only used if found in cache
524 if [ ! -d $BASEDIR/cache
]; then
525 exiterror
"Use make.sh source get first!"
527 cd $BASEDIR/cache
/toolchains
528 PACKAGE
=$
(ls -v -r $TOOLCHAINNAME.
tar.bz2
2>/dev
/null |
head -n 1)
529 #only restore on a clean disk
531 local BLD_TIME_START
=$
(date +%s
)
532 touch $RUNNING; rm -f $FAILED $BUILD_SPY_FILENAME 2>/dev
/null
534 echo -ne "Building for ${BOLD}${TARGET} (${MACHINE}) on ${MACHINE_REAL}${NORMAL}\n"
536 build_spy_send_profile
537 build_spy state compiling
541 if [ -f $BASEDIR/log_
${TARGET}/02_base
/stage2-LFS
]; then
543 echo "Using installed toolchain" >> $LOGFILE
544 beautify message DONE
"Stage toolchain already built or extracted"
546 if [ -z "$PACKAGE" ]; then
547 echo "Full toolchain compilation"
552 beautify build_stage
"Building toolchain"
555 echo "Restore from $PACKAGE"
556 cd $BASEDIR && tar jxf
$BASEDIR/cache
/toolchains
/$PACKAGE
564 beautify build_stage
"Building base"
567 beautify build_stage
"Building $SNAME"
570 beautify build_stage
"Building miscellaneous"
573 if [ "${EMB}" -eq "0" ]; then
574 beautify build_stage
"Building installer"
578 beautify build_stage
"Building packages"
582 echo "... and all this hard work for this:"
583 ls -sh $BASEDIR/${IMAGENAME}.iso
585 local BLD_TIME_END
=$
(date +%s
)
586 build_spy duration $
[ $BLD_TIME_END - $BLD_TIME_START ]
594 DIR_TOOLCHAIN
="$BASEDIR/cache/toolchains"
595 [ -d "${DIR_TOOLCHAIN}" ] || mkdir
-p ${DIR_TOOLCHAIN}
596 if [ ! -f $BASEDIR/cache
/toolchains
/$TOOLCHAINNAME.
tar.bz2
]; then
597 URL_TOOLCHAIN
=$
(grep URL_TOOLCHAIN lfs
/Config |
awk '{ print $3 }')
598 DIR_TOOLCHAIN
="$BASEDIR/cache/toolchains"
600 echo "Loading toolchain for $TARGET"
601 scp
-2 ${IPFIRE_USER}@
${URL_TOOLCHAIN}/$TOOLCHAINNAME.
tar.bz2 \
604 echo -n "Toolchain \"$TOOLCHAINNAME\" is already existing"
605 beautify message SKIP
611 if [ -f $BASEDIR/cache
/toolchains
/$TOOLCHAINNAME.
tar.bz2
]; then
612 URL_TOOLCHAIN
=$
(grep URL_TOOLCHAIN lfs
/Config |
awk '{ print $3 }')
613 DIR_TOOLCHAIN
="$BASEDIR/cache/toolchains"
615 echo "Pushing toolchain for $TARGET"
616 scp
-2 ${DIR_TOOLCHAIN}/$TOOLCHAINNAME.
tar.bz2 \
617 ${IPFIRE_USER}@
${URL_TOOLCHAIN}
619 echo -n "Toolchain \"$TOOLCHAINNAME\" is not existing. "
620 echo -n "Run \"./make.sh build\", first"
621 beautify message SKIP
626 if [ ! -d $BASEDIR/cache
]; then
627 mkdir
-p $BASEDIR/cache
/{tarballs
,patches
}
629 mkdir
-p $BASEDIR/log_
${TARGET}
630 echo -e "${BOLD}Preload all source files${NORMAL}"
633 if [ -f "$i" -a "$i" != "Config" ]; then
635 LFS_BASEDIR
=$BASEDIR \
637 download
2>> $LOGFILE
638 [ $?
-ne 0 ] && beautify message FAIL
646 URL_SOURCE
=$
(grep URL_SOURCE lfs
/Config |
awk '{ print $3 }')
647 REMOTE_FILES
=$
(echo "ls -1" | sftp
-C ${IPFIRE_USER}@
${URL_SOURCE})
649 cd $BASEDIR/cache
/tarballs
/
650 for file in $
(ls -1); do
651 grep -q "$file" <<<$REMOTE_FILES && continue
652 NEW_FILES
="$NEW_FILES $file"
654 [ -n "$NEW_FILES" ] && scp
-2 $NEW_FILES ${IPFIRE_USER}@
${URL_SOURCE}
660 URL_TARGET
=$
(grep URL_TARGET lfs
/Config |
awk '{ print $3 }')
661 DIR
="${BASEDIR}/${HOSTNAME}/$(date '+%Y%m%d-%0k')-${TARGET}/"
663 # If there is no iso, we do nothing.
664 ls ${BASEDIR}/${IMAGENAME}.
* &>/dev
/null ||
return 0
666 rm -rf ${BASEDIR}/${HOSTNAME} 2>/dev
/null
669 [ -e "${BASEDIR}/packages" ] && cp -al ${BASEDIR}/packages ${DIR}
670 [ -e "${BATCHLOG}" ] && \
671 python ${BASEDIR}/tools/alog2html < ${BATCHLOG} > ${DIR}/build_log.html
672 pkg_list_packages > ${DIR}/packages-list.txt
673 git_log >/dev/null; cp -l ${BASEDIR}/doc/ChangeLog ${DIR}
674 git_export; cp -l ${BASEDIR}/${SNAME}-${VERSION}.source.tar.gz ${DIR}
675 git_diff >/dev/null && cp -l ${DIFF_NAME} ${DIR}
676 cp -l ${BASEDIR}/${IMAGENAME}.* ${DIR}
679 scp -2 -r ${HOSTNAME} ${IPFIRE_USER}@${URL_TARGET} || :
681 rm -rf ${BASEDIR}/${HOSTNAME} 2>/dev/null