#!/bin/sh set -o errexit # The first argument is the shell script that initializes the variables: # sourceDir # outputDir # tmpDir # addBuildCompatibilityLibDir # The following are only for image types: # installDir # isImage # imagePath # imageSize # imageLabel # updateOnly # dontClearImage # isVMwareImage # optionalPackageDescriptions # # addattr # copyattr # rc # rmAttrs # unzip # The following are only for image types: # bfsShell # fsShellCommand # makebootable # resattr # vmdkimage # The following is only for cd types: # generate_attribute_stores # isCD # stripCommand # if [ $# -gt 0 ]; then . $1 shift fi if [ ! $isCD ]; then # If the haiku image path is a symlink resolve it now (makebootable needs the # path of the actual device path under Linux). normalizedImagePath='' if readlink -f "$imagePath" > /dev/null 2>&1 ; then normalizedImagePath=$(readlink -f "$imagePath") elif realpath "$imagePath" > /dev/null 2>&1 ; then normalizedImagePath=$(realpath "$imagePath") elif greadlink -f "$imagePath" > /dev/null 2>&1 ; then normalizedImagePath=$(greadlink -f "$imagePath") fi if [ -n "$normalizedImagePath" ]; then imagePath="$normalizedImagePath" fi fi # this adds the build library dir to LD_LIBRARY_PATH eval "$addBuildCompatibilityLibDir" # map the shell commands if [ $isCD ]; then outputDir=$tmpDir/cdsource sPrefix= tPrefix="$outputDir/" cd=cd scd=: cp="$copyattr -d" copyAttrs="$copyattr" ln=ln mkdir=mkdir rm=rm elif [ $isImage ]; then # If FIFOs are used for the communication with the FS shell, prepare them. if $fsShellCommand --uses-fifos; then fifoBasePath=/tmp/build_haiku_image-$$-fifo toFSShellFifo=${fifoBasePath}-to-shell fromFSShellFifo=${fifoBasePath}-from-shell rm -f $toFSShellFifo $fromFSShellFifo mkfifo $toFSShellFifo $fromFSShellFifo # Open the FIFOs such that they are ready for the fsShellCommand. This # also makes sure that they remain open until this script exits. When we # exit while the FS shell is still running and waiting for commands, # closing of our file descriptors will break the FIFOs and the FS shell # will exit, too. # Note: A bit of trickery is needed since opening one end blocks until # someone opens the other end. sleep 3<$fromFSShellFifo 1 & exec 6>$fromFSShellFifo 3<$fromFSShellFifo sleep 5<$toFSShellFifo 1 & exec 4>$toFSShellFifo 5<$toFSShellFifo # Remove the FIFO files again -- we have the open FDs, so they can # still be used and this makes sure they won't hang around any further. rm -f $toFSShellFifo $fromFSShellFifo # Remap the fsShellCommand and bfsShell such that they don't inherit the # wrong FDs. For both fsShellCommand and bfsShell FD 3 is the input from # the respectively other program, FD 4 is the output to it. actualFSShellCommand="$fsShellCommand" actualBFSShell="$bfsShell" fsShellCommandWrapper() { $actualFSShellCommand 5>&- 6>&- "$@" } bfsShellWrapper() { $actualBFSShell 3>&5 4<&6 "$@" } fsShellCommand=fsShellCommandWrapper bfsShell=bfsShellWrapper fi # set up the other commands sPrefix=: tPrefix=/myfs/ cd="$fsShellCommand cd" scd="$fsShellCommand cd" cp="$fsShellCommand cp -f" copyAttrs="$fsShellCommand cp -a" ln="$fsShellCommand ln" mkdir="$fsShellCommand mkdir" rm="$fsShellCommand rm" mkindex="$fsShellCommand mkindex" else sPrefix= # TODO: This should come from the environment. tPrefix="$installDir/" cd=cd scd=: cp="$copyattr -d" copyAttrs="$copyattr" ln=ln mkdir=mkdir rm=rm mkindex=mkindex fi stripDebugInfo() { file="$1" # Determine whether the file is an ELF file by checking the ELF signature, # or at least the printable characters. elfMarker=`dd "if=$file" bs=1 skip=1 count=3 2> /dev/null` if [ "$elfMarker" = 'ELF' ]; then # make user-writable first -- some files aren't chmod u+w "$file" "$stripCommand" --strip-debug "$file" fi } extractFile() { # extractFile archiveFile=$1 targetExtractedDir=$2 extractedSubDir=$3 stripDebugSymbols=$4 echo "Extracting $archiveFile ..." extractDir=$tmpDir/extract $rmAttrs -rf "$extractDir" mkdir -p "$extractDir" case "$archiveFile" in *.zip) $unzip -q -d "$extractDir" "$archiveFile" ;; *.tgz|*.tar.gz) tar -C "$extractDir" -xf "$archiveFile" ;; *) echo "Unhandled archive extension in build_haiku_image extractFile()" exit 1 ;; esac if [ -f $extractDir/.OptionalPackageDescription ]; then cat $extractDir/.OptionalPackageDescription >> $copyrightsFile echo >> $copyrightsFile rm $extractDir/.OptionalPackageDescription fi if [ "$stripDebugSymbols" = "1" ]; then # strip executables in common/bin if [ -d $extractDir/common/bin ]; then for file in `find $extractDir/common/bin -type f -a -perm +100 \ -a -size +1k`; do stripDebugInfo "$file" done fi # strip libraries in common/lib if [ -d $extractDir/common/lib ]; then for file in `find $extractDir/common/lib -type f -a -size +1k \ -a -name lib\*`; do stripDebugInfo "$file" done fi fi $cp -r "${sPrefix}$extractDir/$extractedSubDir/." "${tPrefix}$targetExtractedDir" $rmAttrs -rf "$extractDir" } mkdir -p $tmpDir copyrightsFile=$tmpDir/copyrights $rmAttrs -f $copyrightsFile if [ "$optionalPackageDescriptions" ]; then cp "$optionalPackageDescriptions" $copyrightsFile fi if [ $isCD ]; then # setup output dir $rmAttrs -rf "$outputDir" mkdir -p "$outputDir" fi # create the image and mount it if [ $isImage ]; then echo imageOffsetFlags= if [ $isVMwareImage ]; then imageOffsetFlags="--start-offset 65536" fi if [ ! $updateOnly ]; then echo "Creating image ..." imageFlags="-i${imageSize}M" if [ ! "$dontClearImage" ]; then imageFlags="$imageFlags -c" fi if [ $isVMwareImage ]; then $vmdkimage -h 64k $imageFlags "$imagePath" else $createImage $imageFlags "$imagePath" fi $bfsShell --initialize $imageOffsetFlags "$imagePath" \ "$imageLabel" "block_size 2048" $makebootable $imageOffsetFlags "$imagePath" fi $bfsShell -n $imageOffsetFlags "$imagePath" > /dev/null & sleep 1 # Close FDs 5 and 6. Those represent the pipe ends that are used by the # FS shell. Closing them in the shell process makes sure an unexpected death # of the FS shell causes writing to/reading from the other ends to fail # immediately. exec 5>&- 6>&- # bail out, if mounting fails $cd . fi echo "Populating image ..." while [ $# -gt 0 ]; do . $1 shift done # install MIME database # TODO: It should be possible to do that in the build system too. if [ ! $updateOnly ]; then mimeDBSource=$sourceDir/src/data/beos_mime mimeDBDest=${tPrefix}home/config/settings/beos_mime echo "Deleting old MIME database ..." $rm -rf $mimeDBDest $mkdir -p $mimeDBDest mimeTmpDir=$tmpDir/mime mimeDBTmpDir=$tmpDir/mime/db mimeTmpIndex=0 mimeTmpFile=$mimeTmpDir/mimedb$$.rsrc # create tmp dir for the MIME conversion stuff mkdir -p $mimeDBTmpDir echo "Installing MIME database ..." for inSuperFile in $mimeDBSource/*.super; do superType=$(basename $inSuperFile .super) tmpSuperDir=$mimeDBTmpDir/$superType # compile rdef to rsrc file and the rsrc file to attributes $rc -o $mimeTmpFile $inSuperFile mkdir -p $tmpSuperDir $resattr -O -o $tmpSuperDir $mimeTmpFile $rmAttrs $mimeTmpFile # iterate through the sub types for inSubFile in $mimeDBSource/$superType/*; do # check, if the type exists if test -f $inSubFile && grep META:TYPE $inSubFile > /dev/null 2>&1 ; then subType=$(basename $inSubFile) tmpSubFile=$mimeDBTmpDir/$superType/$subType # compile rdef to rsrc file and the rsrc file to attributes $rc -o $mimeTmpFile $inSubFile $resattr -O -o $tmpSubFile $mimeTmpFile $rmAttrs $mimeTmpFile fi done done $cp -r ${sPrefix}$mimeDBTmpDir/. $mimeDBDest # cleanup tmp dir $rmAttrs -rf $mimeTmpDir fi # ! updateOnly # add the concatenated copyrights as an attribute to AboutSystem if [ ! $updateOnly ]; then if [ -f $copyrightsFile ]; then copyrightAttrs=$tmpDir/copyrightAttrs $rmAttrs -f $copyrightAttrs touch $copyrightAttrs $addattr -f $copyrightsFile COPYRIGHTS $copyrightAttrs $copyAttrs ${sPrefix}$copyrightAttrs ${tPrefix}system/apps/AboutSystem fi fi if [ $isCD ]; then # generate the attribute stores echo "Generating attribute stores ..." $generate_attribute_stores "$tPrefix" echo "Copying boot image ..." $cp "$cdBootFloppy" "$outputDir" if [ $(which mkisofs) ]; then # build the iso image using mkisofs echo "Building CD image (mkisofs)..." mkisofs -uid 0 -gid 0 -b `basename $cdBootFloppy` -R -V "$cdLabel" -o "$cdImagePath" "$tPrefix" elif [ $(which genisoimage) ]; then # build the iso image using genisoimage echo "Building CD image (genisoimage)..." echo "WARNING: genisoimage fallback has known problems with long filenames!" echo " Please install mkisofs before making production releases!" genisoimage -r -iso-level 4 -b `basename $cdBootFloppy` -V "$cdLabel" -o "$cdImagePath" "$tPrefix" else echo "you need mkisofs (preferred) or genisoimage to create a CD image." exit 1 fi # cleanup output dir $rmAttrs -rf "$outputDir" fi # unmount if [ $isImage ]; then echo "Unmounting ..." $fsShellCommand sync $fsShellCommand quit fi