1#!/bin/sh 2set -o errexit 3 4# The first argument is the shell script that initializes the variables: 5# sourceDir 6# outputDir 7# tmpDir 8# addBuildCompatibilityLibDir 9# The following are only for image types: 10# installDir 11# isImage 12# imagePath 13# imageSize 14# imageLabel 15# updateOnly 16# dontClearImage 17# isVMwareImage 18# optionalPackageDescriptions 19# 20# addattr 21# copyattr 22# rc 23# rmAttrs 24# unzip 25# The following are only for image types: 26# bfsShell 27# fsShellCommand 28# makebootable 29# resattr 30# vmdkimage 31# The following is only for cd types: 32# generate_attribute_stores 33# isCD 34# 35if [ $# -gt 0 ]; then 36 . $1 37 shift 38fi 39 40if [ ! $isCD ]; then 41 # If the haiku image path is a symlink resolve it now (makebootable needs the 42 # path of the actual device path under Linux). 43 normalizedImagePath='' 44 if readlink -f "$imagePath" > /dev/null 2>&1 ; then 45 normalizedImagePath=$(readlink -f "$imagePath") 46 elif realpath "$imagePath" > /dev/null 2>&1 ; then 47 normalizedImagePath=$(realpath "$imagePath") 48 elif greadlink -f "$imagePath" > /dev/null 2>&1 ; then 49 normalizedImagePath=$(greadlink -f "$imagePath") 50 fi 51 if [ -n "$normalizedImagePath" ]; then 52 imagePath="$normalizedImagePath" 53 fi 54fi 55 56# this adds the build library dir to LD_LIBRARY_PATH 57eval "$addBuildCompatibilityLibDir" 58 59# map the shell commands 60if [ $isCD ]; then 61 outputDir=$tmpDir/cdsource 62 63 sPrefix= 64 tPrefix="$outputDir/" 65 cd=cd 66 scd=: 67 cp="$copyattr -d" 68 copyAttrs="$copyattr" 69 ln=ln 70 mkdir=mkdir 71 rm=rm 72elif [ $isImage ]; then 73 # If FIFOs are used for the communication with the FS shell, prepare them. 74 if $fsShellCommand --uses-fifos; then 75 fifoBasePath=/tmp/build_haiku_image-$$-fifo 76 toFSShellFifo=${fifoBasePath}-to-shell 77 fromFSShellFifo=${fifoBasePath}-from-shell 78 79 rm -f $toFSShellFifo $fromFSShellFifo 80 mkfifo $toFSShellFifo $fromFSShellFifo 81 82 # Open the FIFOs such that they are ready for the fsShellCommand. This 83 # also makes sure that they remain open until this script exits. When we 84 # exit while the FS shell is still running and waiting for commands, 85 # closing of our file descriptors will break the FIFOs and the FS shell 86 # will exit, too. 87 # Note: A bit of trickery is needed since opening one end blocks until 88 # someone opens the other end. 89 sleep 3<$fromFSShellFifo 1 & 90 exec 6>$fromFSShellFifo 3<$fromFSShellFifo 91 sleep 5<$toFSShellFifo 1 & 92 exec 4>$toFSShellFifo 5<$toFSShellFifo 93 94 # Remove the FIFO files again -- we have the open FDs, so they can 95 # still be used and this makes sure they won't hang around any further. 96 rm -f $toFSShellFifo $fromFSShellFifo 97 98 # Remap the fsShellCommand and bfsShell such that they don't inherit the 99 # wrong FDs. For both fsShellCommand and bfsShell FD 3 is the input from 100 # the respectively other program, FD 4 is the output to it. 101 actualFSShellCommand="$fsShellCommand" 102 actualBFSShell="$bfsShell" 103 104 fsShellCommandWrapper() 105 { 106 $actualFSShellCommand 5>&- 6>&- "$@" 107 } 108 109 bfsShellWrapper() 110 { 111 $actualBFSShell 3>&5 4<&6 "$@" 112 } 113 114 fsShellCommand=fsShellCommandWrapper 115 bfsShell=bfsShellWrapper 116 fi 117 118 # set up the other commands 119 sPrefix=: 120 tPrefix=/myfs/ 121 cd="$fsShellCommand cd" 122 scd="$fsShellCommand cd" 123 cp="$fsShellCommand cp -f" 124 copyAttrs="$fsShellCommand cp -a" 125 ln="$fsShellCommand ln" 126 mkdir="$fsShellCommand mkdir" 127 rm="$fsShellCommand rm" 128 mkindex="$fsShellCommand mkindex" 129else 130 sPrefix= 131 # TODO: This should come from the environment. 132 tPrefix="$installDir/" 133 cd=cd 134 scd=: 135 cp="$copyattr -d" 136 copyAttrs="$copyattr" 137 ln=ln 138 mkdir=mkdir 139 rm=rm 140 mkindex=mkindex 141fi 142 143 144stripDebugInfo() 145{ 146 file="$1" 147 148 # Determine whether the file is an ELF file by checking the ELF signature, 149 # or at least the printable characters. 150 elfMarker=`dd "if=$file" bs=1 skip=1 count=3 2> /dev/null` 151 if [ "$elfMarker" = 'ELF' ]; then 152 # make user-writable first -- some files aren't 153 chmod u+w "$file" 154 strip --strip-debug "$file" 155 fi 156} 157 158extractFile() 159{ 160 # extractFile <archive> <directory> <extractedSubDir> <stripDebugSymbols> 161 archiveFile=$1 162 targetExtractedDir=$2 163 extractedSubDir=$3 164 stripDebugSymbols=$4 165 166 echo "Extracting $archiveFile ..." 167 168 extractDir=$tmpDir/extract 169 $rmAttrs -rf "$extractDir" 170 mkdir -p "$extractDir" 171 172 case "$archiveFile" in 173 *.zip) 174 $unzip -q -d "$extractDir" "$archiveFile" 175 ;; 176 *.tgz|*.tar.gz) 177 tar -C "$extractDir" -xf "$archiveFile" 178 ;; 179 *) 180 echo "Unhandled archive extension in build_haiku_image extractFile()" 181 exit 1 182 ;; 183 esac 184 185 if [ -f $extractDir/.OptionalPackageDescription ]; then 186 cat $extractDir/.OptionalPackageDescription >> $copyrightsFile 187 echo >> $copyrightsFile 188 rm $extractDir/.OptionalPackageDescription 189 fi 190 191 if [ "$stripDebugSymbols" = "1" ]; then 192 # strip executables in common/bin 193 if [ -d $extractDir/common/bin ]; then 194 for file in `find $extractDir/common/bin -type f -a -perm +100 \ 195 -a -size +1k`; do 196 stripDebugInfo "$file" 197 done 198 fi 199 200 # strip libraries in common/lib 201 if [ -d $extractDir/common/lib ]; then 202 for file in `find $extractDir/common/lib -type f -a -size +1k \ 203 -a -name lib\*`; do 204 stripDebugInfo "$file" 205 done 206 fi 207 fi 208 209 $cp -r "${sPrefix}$extractDir/$extractedSubDir/." "${tPrefix}$targetExtractedDir" 210 211 $rmAttrs -rf "$extractDir" 212} 213 214 215mkdir -p $tmpDir 216copyrightsFile=$tmpDir/copyrights 217$rmAttrs -f $copyrightsFile 218if [ "$optionalPackageDescriptions" ]; then 219 cp "$optionalPackageDescriptions" $copyrightsFile 220fi 221 222if [ $isCD ]; then 223 # setup output dir 224 $rmAttrs -rf "$outputDir" 225 mkdir -p "$outputDir" 226fi 227 228# create the image and mount it 229if [ $isImage ]; then 230 echo 231 232 imageOffsetFlags= 233 if [ $isVMwareImage ]; then 234 imageOffsetFlags="--start-offset 65536" 235 fi 236 237 if [ ! $updateOnly ]; then 238 echo "Creating image ..." 239 240 imageFlags="-i${imageSize}M" 241 if [ ! "$dontClearImage" ]; then 242 imageFlags="$imageFlags -c" 243 fi 244 245 if [ $isVMwareImage ]; then 246 $vmdkimage -h 64k $imageFlags "$imagePath" 247 else 248 $createImage $imageFlags "$imagePath" 249 fi 250 251 $bfsShell --initialize $imageOffsetFlags "$imagePath" \ 252 "$imageLabel" "block_size 2048" 253 $makebootable $imageOffsetFlags "$imagePath" 254 fi 255 256 $bfsShell -n $imageOffsetFlags "$imagePath" > /dev/null & 257 sleep 1 258 259 # Close FDs 5 and 6. Those represent the pipe ends that are used by the 260 # FS shell. Closing them in the shell process makes sure an unexpected death 261 # of the FS shell causes writing to/reading from the other ends to fail 262 # immediately. 263 exec 5>&- 6>&- 264 265 # bail out, if mounting fails 266 $cd . 267fi 268 269echo "Populating image ..." 270while [ $# -gt 0 ]; do 271 . $1 272 shift 273done 274 275 276# install MIME database 277# TODO: It should be possible to do that in the build system too. 278 279if [ ! $updateOnly ]; then 280 mimeDBSource=$sourceDir/src/data/beos_mime 281 mimeDBDest=${tPrefix}home/config/settings/beos_mime 282 283 echo "Deleting old MIME database ..." 284 285 $rm -rf $mimeDBDest 286 $mkdir -p $mimeDBDest 287 mimeTmpDir=$tmpDir/mime 288 mimeDBTmpDir=$tmpDir/mime/db 289 mimeTmpIndex=0 290 mimeTmpFile=$mimeTmpDir/mimedb$$.rsrc 291 292 # create tmp dir for the MIME conversion stuff 293 mkdir -p $mimeDBTmpDir 294 295 echo "Installing MIME database ..." 296 297 for inSuperFile in $mimeDBSource/*.super; do 298 superType=$(basename $inSuperFile .super) 299 tmpSuperDir=$mimeDBTmpDir/$superType 300 301 # compile rdef to rsrc file and the rsrc file to attributes 302 $rc -o $mimeTmpFile $inSuperFile 303 mkdir -p $tmpSuperDir 304 $resattr -O -o $tmpSuperDir $mimeTmpFile 305 $rmAttrs $mimeTmpFile 306 307 # iterate through the sub types 308 for inSubFile in $mimeDBSource/$superType/*; do 309 # check, if the type exists 310 if test -f $inSubFile && grep META:TYPE $inSubFile > /dev/null 2>&1 ; then 311 subType=$(basename $inSubFile) 312 tmpSubFile=$mimeDBTmpDir/$superType/$subType 313 314 # compile rdef to rsrc file and the rsrc file to attributes 315 $rc -o $mimeTmpFile $inSubFile 316 $resattr -O -o $tmpSubFile $mimeTmpFile 317 $rmAttrs $mimeTmpFile 318 fi 319 done 320 done 321 322 $cp -r ${sPrefix}$mimeDBTmpDir/. $mimeDBDest 323 324 # cleanup tmp dir 325 $rmAttrs -rf $mimeTmpDir 326fi # ! updateOnly 327 328 329# add the concatenated copyrights as an attribute to AboutSystem 330 331if [ ! $updateOnly ]; then 332 if [ -f $copyrightsFile ]; then 333 copyrightAttrs=$tmpDir/copyrightAttrs 334 $rmAttrs -f $copyrightAttrs 335 touch $copyrightAttrs 336 $addattr -f $copyrightsFile COPYRIGHTS $copyrightAttrs 337 $copyAttrs ${sPrefix}$copyrightAttrs ${tPrefix}system/apps/AboutSystem 338 fi 339fi 340 341if [ $isCD ]; then 342 # generate the attribute stores 343 echo "Generating attribute stores ..." 344 $generate_attribute_stores "$tPrefix" 345 346 echo "Copying boot image ..." 347 $cp "$cdBootFloppy" "$outputDir" 348 349 if [ $(which mkisofs) ]; then 350 # build the iso image using mkisofs 351 echo "Building CD image (mkisofs)..." 352 mkisofs -uid 0 -gid 0 -b `basename $cdBootFloppy` -R -V "$cdLabel" -o "$cdImagePath" "$tPrefix" 353 elif [ $(which genisoimage) ]; then 354 # build the iso image using genisoimage 355 echo "Building CD image (genisoimage)..." 356 echo "WARNING: genisoimage fallback has known problems with long filenames!" 357 echo " Please install mkisofs before making production releases!" 358 genisoimage -r -iso-level 4 -b `basename $cdBootFloppy` -V "$cdLabel" -o "$cdImagePath" "$tPrefix" 359 else 360 echo "you need mkisofs (preferred) or genisoimage to create a CD image." 361 exit 1 362 fi 363 364 # cleanup output dir 365 $rmAttrs -rf "$outputDir" 366fi 367 368# unmount 369if [ $isImage ]; then 370 echo "Unmounting ..." 371 $fsShellCommand sync 372 $fsShellCommand quit 373fi 374