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
64 if [ "$RETVAL" -eq "0" ]; then
73 sleep 0.3 # Wait one second for finish of processes
74 for fs
in $
(mount |
grep $BASEDIR/build_
${TARGET} |
awk '{print $3}'); do
75 umount
$fs 2>/dev
/null
;
77 } # End of stdumount()
83 [ -n "$LOGFILE" ] && \
84 build_spy log $
(tail -n16 $LOGFILE |
$BASEDIR/tools
/base64
)
86 rm -f $RUNNING 2>/dev
/null
88 } # End of exiterror()
90 ################################################################################
91 # This is the function that sets the environment of a chroot and enters it #
92 ################################################################################
94 PATH
=${TOOLS_DIR}/usr/bin:/bin:/usr/bin:/sbin:/usr/sbin:${TOOLS_DIR}/bin:/usr/${MACHINE_REAL}-linux/bin
96 if [ ! -e $LFS/usr
/src
/lfs
/ ]; then
97 exiterror
"No such file or directory: $LFS/usr/src/lfs/"
100 echo -ne "Entering ${BOLD}$MACHINE${NORMAL} LFS chroot, type exit to return to host environment\n"
102 chroot
$LFS $TOOLS_DIR/bin
/env
-i \
105 PS1
="${BOLD}[chroot-${TARGET}(${MACHINE})]${NORMAL} \u:\w\$ " \
107 CONFIG_ROOT
=${CONFIG_ROOT} \
112 CCACHE_DIR
=/usr
/src
/ccache \
113 CCACHE_PREFIX
=${CCACHE_PREFIX} \
114 CCACHE_HASHDIR
=${CCACHE_HASHDIR} \
115 DISTCC_DIR
=/usr
/src
/distcc \
116 PARALLELISMFLAGS
=$PARALLELISMFLAGS \
118 TOOLS_DIR
=$TOOLS_DIR \
119 INSTALLER_DIR
=$INSTALLER_DIR \
121 MACHINE_REAL
="$MACHINE_REAL" \
123 CXXFLAGS
="$CXXFLAGS" \
124 IFS_HOST
="$IFS_HOST" \
125 IFS_TARGET
="$IFS_TARGET" \
128 STAGE_ORDER
=$STAGE_ORDER \
129 LOGFILE
=$
(echo $LOGFILE |
sed "s,$BASEDIR,/usr/src,g") \
132 if [ $?
-ne 0 ]; then
133 exiterror
"chroot error"
137 } # End of entershell()
141 ################################################################################
142 # Common checking before entering the chroot and compilling #
143 # Return:0 caller can continue #
144 # :1 skip (nothing to do) #
145 # or fail if no script file found #
146 ################################################################################
150 if [ ! -f $BASEDIR/lfs
/$1 ]; then
151 exiterror
"No such file or directory: $BASEDIR/lfs/$1"
154 local PKG_VER
=$
(get_pkg_ver
$BASEDIR/lfs
/$1)
155 beautify make_pkg
"$PKG_VER $*"
159 for i
in $SKIP_PACKAGE_LIST; do
160 if [ "$i" == "$1" ]; then
166 # On debug build, we don't strip
167 if [ "$1" == "strip" -a "$BUILD_DEBUG" == "1" ]; then
172 # Don't create addons?
173 local EXTRA
=$
(grep ^EXTRA
$BASEDIR/lfs
/$1 |
awk '{print $3}')
174 if [ "$EXTRA" == "yes" -a "$BUILD_EXTRAS" == "0" ]; then
179 # Don't create debugging tools?
180 local DEBUG
=$
(grep ^DEBUG
$BASEDIR/lfs
/$1 |
awk '{print $3}')
181 if [ "$DEBUG" == "yes" -a "$BUILD_DEBUG" == "1" ]; then
186 echo -e "$(date -u '+%b %e %T'): Building $* " >> $LOGFILE
188 cd $BASEDIR/lfs
&& make -s -f $
* MACHINE
=$MACHINE LFS_BASEDIR
=$BASEDIR MESSAGE
="$1\t " download
>> $LOGFILE 2>&1
189 if [ $?
-ne 0 ]; then
190 exiterror
"Download error in $1"
196 } # End of lfsmakecommoncheck()
198 ################################################################################
199 # This is the function that builds every package in stage "toolchain" #
200 ################################################################################
202 lfsmakecommoncheck $
*
203 [ $?
== 1 ] && return 0
205 local PKG_VER
=$
(get_pkg_ver
$BASEDIR/lfs
/$1)
207 local EXTRA_MAKE
=$EXTRA_MAKE
209 local PKG_TIME_START
=$
(date +%s
)
210 cd $BASEDIR/lfs
&& $EXTRA_MAKE make -f $
* \
211 CONFIG_ROOT
=$CONFIG_ROOT \
213 TOOLS_DIR
=$TOOLS_DIR \
215 MACHINE_REAL
="$MACHINE_REAL" \
216 IFS_HOST
="$IFS_HOST" \
217 IFS_TARGET
="$IFS_TARGET" \
219 LFS_BASEDIR
=$BASEDIR \
221 INSTALLER_DIR
=$INSTALLER_DIR \
222 PARALLELISMFLAGS
=$PARALLELISMFLAGS \
225 STAGE_ORDER
=$STAGE_ORDER \
226 install >> $LOGFILE 2>&1
228 local COMPILE_SUCCESS
=$?
229 local PKG_TIME_END
=$
(date +%s
)
231 if [ $COMPILE_SUCCESS -ne 0 ]; then
232 beautify result FAIL $
[ $PKG_TIME_END - $PKG_TIME_START ] $1 $PKG_VER $STAGE_ORDER $STAGE
233 exiterror
"Building $*"
235 beautify result DONE $
[ $PKG_TIME_END - $PKG_TIME_START ] $1 $PKG_VER $STAGE_ORDER $STAGE
239 } # End of toolchain_make()
241 ################################################################################
242 # This is the function that builds every package in stage "base" and "ipfire" #
243 ################################################################################
245 lfsmakecommoncheck $
*
246 [ $?
== 1 ] && return 0
248 local PKG_VER
=$
(get_pkg_ver
$BASEDIR/lfs
/$1)
250 local EXTRA_MAKE
=$EXTRA_MAKE
251 # When cross-compiling, make sure the kernel is compiled for the target
252 [ "$MACHINE" != "$MACHINE_REAL" -a "$1" == "linux" ] && unset EXTRA_MAKE
254 # Also, make sure external kernel modules are compiled 64bit
255 if grep -qEi 'KERNEL_MOD = yes' $1 ; then
259 local PKG_TIME_START
=$
(date +%s
)
260 chroot
$LFS $TOOLS_DIR/bin
/env
-i \
265 CONFIG_ROOT
=${CONFIG_ROOT} \
270 CCACHE_DIR
=/usr
/src
/ccache \
271 CCACHE_PREFIX
=${CCACHE_PREFIX} \
272 CCACHE_HASHDIR
=${CCACHE_HASHDIR} \
273 DISTCC_DIR
=/usr
/src
/distcc \
274 PARALLELISMFLAGS
=$PARALLELISMFLAGS \
276 TOOLS_DIR
=$TOOLS_DIR \
277 INSTALLER_DIR
=$INSTALLER_DIR \
278 CDROM_DIR
=$CDROM_DIR \
279 IMAGES_DIR
=$IMAGES_DIR \
281 MACHINE_REAL
="$MACHINE_REAL" \
283 CXXFLAGS
="$CXXFLAGS" \
284 IFS_HOST
="$IFS_HOST" \
285 IFS_TARGET
="$IFS_TARGET" \
287 BUILD_DEBUG
=$BUILD_DEBUG \
288 BUILD_EXTRAS
=$BUILD_EXTRAS \
291 STAGE_ORDER
=$STAGE_ORDER \
293 IMAGENAME
=$IMAGENAME \
294 LOGFILE
=$
(echo $LOGFILE |
sed "s,$BASEDIR,/usr/src,g") \
295 bash
-x -c "cd /usr/src/lfs && \
296 $EXTRA_MAKE make -f $* LFS_BASEDIR=/usr/src install" >>$LOGFILE 2>&1
298 local COMPILE_SUCCESS
=$?
299 local PKG_TIME_END
=$
(date +%s
)
301 if [ $COMPILE_SUCCESS -ne 0 ]; then
302 beautify result FAIL $
[ $PKG_TIME_END - $PKG_TIME_START ] $1 $PKG_VER $STAGE_ORDER $STAGE
303 exiterror
"Building $*"
305 beautify result DONE $
[ $PKG_TIME_END - $PKG_TIME_START ] $1 $PKG_VER $STAGE_ORDER $STAGE
309 } # End of ipfire_make()
311 ################################################################################
312 # This prepares the build environment #
313 ################################################################################
315 LOGFILE
=$BASEDIR/log_
${TARGET}/_build
.00-preparation.log
317 mkdir
-p $BASEDIR/log_
${TARGET}/01_toolchain
2>/dev
/null
318 mkdir
-p $BASEDIR/log_
${TARGET}/02_base
2>/dev
/null
319 mkdir
-p $BASEDIR/log_
${TARGET}/03_
${SNAME} 2>/dev
/null
320 mkdir
-p $BASEDIR/log_
${TARGET}/04_misc
2>/dev
/null
321 mkdir
-p $BASEDIR/log_
${TARGET}/05_installer
2>/dev
/null
322 mkdir
-p $BASEDIR/log_
${TARGET}/06_packages
2>/dev
/null
324 #############################################################################
325 # Are we running the right shell? #
326 #############################################################################
328 if [ ! "$BASH" ]; then
329 exiterror
"BASH environment variable is not set. You're probably running the wrong shell."
332 if [ -z "${BASH_VERSION}" ]; then
333 exiterror
"Not running BASH shell."
336 #############################################################################
337 # Trap on emergency exit #
338 #############################################################################
339 trap "exiterror 'Build process interrupted'" SIGINT SIGTERM SIGKILL SIGSTOP SIGQUIT
342 #############################################################################
343 # Resetting our nice level #
344 #############################################################################
345 echo -ne "Resetting our nice level to $NICE"
346 renice
$NICE $$
> /dev
/null
347 if [ $
(nice
) != "$NICE" ]; then
348 beautify message FAIL
349 exiterror
"Failed to set correct nice level"
351 beautify message DONE
355 if [ -x /usr
/bin
/schedtool
]; then
356 /usr
/bin
/schedtool
-B $$
357 if [ $?
-ne 0 ]; then
358 echo -ne "Setting kernel schedular to SCHED_BATCH"
359 beautify message FAIL
363 ##############################################################################
364 # Checking if running as root user #
365 ##############################################################################
366 if [ $
(id
-u) != 0 ]; then
367 echo -ne "Checking if we're running as root user"
368 beautify message FAIL
369 exiterror
"Not building as root"
373 ##############################################################################
374 # Checking for necessary temporary space #
375 ##############################################################################
376 BASE_DEV
=$
(df
-P -k $BASEDIR |
tail -n 1 |
awk '{ print $1 }')
377 BASE_ASPACE
=$
(df
-P -k $BASEDIR |
tail -n 1 |
awk '{ print $4 }')
378 if (( 2048000 > $BASE_ASPACE )); then
379 BASE_USPACE
=$
(du
-skx $BASEDIR |
awk '{print $1}')
380 if (( 2048000 - $BASE_USPACE > $BASE_ASPACE )); then
381 echo -ne "Checking for necessary space on disk $BASE_DEV"
382 beautify message FAIL
383 exiterror
"Not enough temporary space available, need at least 2GB on $BASE_DEV"
387 ##############################################################################
389 ##############################################################################
391 echo -ne "Embedded build"
392 if [ $EMB -eq 1 ]; then
394 check_loop || exiterror
"Can't build flash images on this machine."
401 ##############################################################################
402 # Checking CPU features #
403 ##############################################################################
405 check_supported_target
$TARGET || \
406 exiterror
"Your host doesn't have all needed cpu features for building \"$TARGET\""
408 ##############################################################################
409 # Building Linux From Scratch system configuration #
410 ##############################################################################
416 LFS
=$BASEDIR/build_
${TARGET}/${SNAME}
418 # Check /tools symlink
419 if [ -h $TOOLS_DIR ]; then
422 if [ ! -a $TOOLS_DIR ]; then
423 ln -s $BASEDIR/build_
${TARGET}/$TOOLS_DIR /
425 if [ ! -h $TOOLS_DIR ]; then
426 exiterror
"Could not create $TOOLS_DIR symbolic link."
433 unset CC CXX CPP LD_LIBRARY_PATH LD_PRELOAD
435 # Make some extra directories
436 mkdir
-p $BASEDIR/build_
${TARGET}/{$TOOLS_DIR,cdrom
,$INSTALLER_DIR,$IMAGES_DIR} 2>/dev
/null
437 mkdir
-p $BASEDIR/{cache
,ccache
,distcc
} 2>/dev
/null
438 mkdir
-p $BASEDIR/cache
/{toolchains
,patches
,tarballs
} 2>/dev
/null
439 mkdir
-p $LFS/{$TOOLS_DIR,usr
/src
} 2>/dev
/null
440 mkdir
-p $LFS/{dev
,etc
,proc
,sys
} 2>/dev
/null
441 mkdir
-p $LFS/dev
/pts
2>/dev
/null
442 mkdir
-p $LFS/usr
/src
/{cache
,config
,doc
,lfs
,log_
${TARGET},src
,ccache
,distcc
} 2>/dev
/null
443 mkdir
-p $LFS/{$INSTALLER_DIR,cdrom
,images
} 2>/dev
/null
445 mknod
-m 600 $BASEDIR/build
/dev
/console c
5 1 2>/dev
/null
446 mknod
-m 666 $BASEDIR/build
/dev
/null c
1 3 2>/dev
/null
448 # Make all sources and proc available under lfs build
449 mount
--bind /dev
$LFS/dev
450 mount
--bind /proc
$LFS/proc
451 mount
--bind /sys
$LFS/sys
452 mount
--bind $BASEDIR/cache
$LFS/usr
/src
/cache
453 mount
--bind $BASEDIR/ccache
$LFS/usr
/src
/ccache
454 mount
--bind $BASEDIR/distcc
$LFS/usr
/src
/distcc
455 mount
--bind $BASEDIR/config
$LFS/usr
/src
/config
456 mount
--bind $BASEDIR/doc
$LFS/usr
/src
/doc
457 mount
--bind $BASEDIR/lfs
$LFS/usr
/src
/lfs
458 mount
--bind $BASEDIR/log_
${TARGET} $LFS/usr
/src
/log_
${TARGET}
459 mount
--bind $BASEDIR/src
$LFS/usr
/src
/src
460 mount
--bind $BASEDIR/build_
${TARGET}/$TOOLS_DIR $LFS/$TOOLS_DIR
461 mount
--bind $BASEDIR/build_
${TARGET}/$CDROM_DIR $LFS/$CDROM_DIR
462 mount
--bind $BASEDIR/build_
${TARGET}/$INSTALLER_DIR $LFS/$INSTALLER_DIR
463 mount
--bind $BASEDIR/build_
${TARGET}/$IMAGES_DIR $LFS/$IMAGES_DIR
465 # Run LFS static binary creation scripts one by one
466 export CCACHE_DIR
=$BASEDIR/ccache
467 export CCACHE_HASHDIR
=1
468 if [ ! -z "$DISTCC_HOSTS" ]; then
469 export CCACHE_PREFIX
="distcc"
470 export DISTCC_DIR
=$BASEDIR/distcc
473 [ -z "$DISTCC_HOSTS" ] ||
echo "$DISTCC_HOSTS" > $DISTCC_DIR/hosts
475 # Remove pre-install list of installed files in case user erase some files before rebuild
476 rm -f $LFS/usr
/src
/lsalr
2>/dev
/null
480 #a prebuilt toolchain package is only used if found in cache
481 if [ ! -d $BASEDIR/cache
]; then
482 exiterror
"Use make.sh source get first!"
484 cd $BASEDIR/cache
/toolchains
485 PACKAGE
=$
(ls -v -r $TOOLCHAINNAME.
tar.bz2
2>/dev
/null |
head -n 1)
486 #only restore on a clean disk
488 local BLD_TIME_START
=$
(date +%s
)
489 touch $RUNNING; rm -f $FAILED $BUILD_SPY_FILENAME 2>/dev
/null
491 echo -ne "Building for ${BOLD}${TARGET} (${MACHINE}) on ${MACHINE_REAL}${NORMAL}\n"
493 build_spy_send_profile
494 build_spy state compiling
495 BASEDIR
=$BASEDIR UUID
=$UUID NAME
=$NAME VERSION
=$VERSION \
496 LOGFILE
="$BASEDIR/log_${TARGET}/_build.00-buildspy.log" \
497 $BASEDIR/tools
/make-buildspy
&
499 if [ -f $BASEDIR/log_
${TARGET}/02_base
/stage2-LFS
]; then
501 echo "Using installed toolchain" >> $LOGFILE
502 beautify message DONE
"Stage toolchain already built or extracted"
504 if [ -z "$PACKAGE" ]; then
505 echo "Full toolchain compilation"
510 beautify build_stage
"Building toolchain"
513 echo "Restore from $PACKAGE"
514 cd $BASEDIR && tar jxf
$BASEDIR/cache
/toolchains
/$PACKAGE
522 beautify build_stage
"Building base"
525 beautify build_stage
"Building $SNAME"
528 beautify build_stage
"Building miscellaneous"
531 if [ "${EMB}" -eq "0" ]; then
532 beautify build_stage
"Building installer"
536 beautify build_stage
"Building packages"
540 echo "... and all this hard work for this:"
541 ls -sh $BASEDIR/${IMAGENAME}.iso
543 local BLD_TIME_END
=$
(date +%s
)
544 build_spy duration $
[ $BLD_TIME_END - $BLD_TIME_START ]
551 DIR_TOOLCHAIN
="$BASEDIR/cache/toolchains"
552 [ -d "${DIR_TOOLCHAIN}" ] || mkdir
-p ${DIR_TOOLCHAIN}
553 if [ ! -f $BASEDIR/cache
/toolchains
/$TOOLCHAINNAME.
tar.bz2
]; then
554 URL_TOOLCHAIN
=$
(grep URL_TOOLCHAIN lfs
/Config |
awk '{ print $3 }')
555 DIR_TOOLCHAIN
="$BASEDIR/cache/toolchains"
557 echo "Loading toolchain for $TARGET"
558 scp
-2 ${IPFIRE_USER}@
${URL_TOOLCHAIN}/$TOOLCHAINNAME.
tar.bz2 \
561 echo -n "Toolchain \"$TOOLCHAINNAME\" is already existing"
562 beautify message SKIP
568 if [ -f $BASEDIR/cache
/toolchains
/$TOOLCHAINNAME.
tar.bz2
]; then
569 URL_TOOLCHAIN
=$
(grep URL_TOOLCHAIN lfs
/Config |
awk '{ print $3 }')
570 DIR_TOOLCHAIN
="$BASEDIR/cache/toolchains"
572 echo "Pushing toolchain for $TARGET"
573 scp
-2 ${DIR_TOOLCHAIN}/$TOOLCHAINNAME.
tar.bz2 \
574 ${IPFIRE_USER}@
${URL_TOOLCHAIN}
576 echo -n "Toolchain \"$TOOLCHAINNAME\" is not existing. "
577 echo -n "Run \"./make.sh build\", first"
578 beautify message SKIP
583 if [ ! -d $BASEDIR/cache
]; then
584 mkdir
-p $BASEDIR/cache
/{tarballs
,patches
}
586 mkdir
-p $BASEDIR/log_
${TARGET}
587 echo -e "${BOLD}Preload all source files${NORMAL}"
590 if [ -f "$i" -a "$i" != "Config" ]; then
592 LFS_BASEDIR
=$BASEDIR \
594 download
2>> $LOGFILE
595 [ $?
-ne 0 ] && beautify message FAIL
603 URL_SOURCE
=$
(grep URL_SOURCE lfs
/Config |
awk '{ print $3 }')
604 REMOTE_FILES
=$
(echo "ls -1" | sftp
-C ${IPFIRE_USER}@
${URL_SOURCE})
606 cd $BASEDIR/cache
/tarballs
/
607 for file in $
(ls -1); do
608 grep -q "$file" <<<$REMOTE_FILES && continue
609 NEW_FILES
="$NEW_FILES $file"
611 [ -n "$NEW_FILES" ] && scp
-2 $NEW_FILES ${IPFIRE_USER}@
${URL_SOURCE}
617 URL_TARGET
=$
(grep URL_TARGET lfs
/Config |
awk '{ print $3 }')
618 DIR
="${BASEDIR}/${HOSTNAME}/$(date '+%Y%m%d-%0k')/"
620 # If there is no iso, we do nothing.
621 ls ${BASEDIR}/${IMAGENAME}.
* &>/dev
/null ||
return 0
623 rm -rf ${BASEDIR}/${HOSTNAME} 2>/dev
/null
626 [ -e "${BASEDIR}/packages" ] && cp -al ${BASEDIR}/packages ${DIR}
627 [ -e "${BATCHLOG}" ] && \
628 python ${BASEDIR}/tools/alog2html < ${BATCHLOG} > ${DIR}/build_log.html
629 software_list > ${DIR}/packages-list.txt
630 git_export; cp -l ${BASEDIR}/${SNAME}-${VERSION}.source.tar.gz ${DIR}
631 git_diff >/dev/null && cp -l ${DIFF_NAME} ${DIR}
632 cp -l ${BASEDIR}/${IMAGENAME}.* ${DIR}
635 scp -2 -r ${HOSTNAME} ${IPFIRE_USER}@${URL_TARGET} || :
637 rm -rf ${BASEDIR}/${HOSTNAME} 2>/dev/null