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# stripOptionalPackageDebugSymbols 20# 21# addattr 22# copyattr 23# rc 24# rmAttrs 25# unzip 26# The following are only for image types: 27# bfsShell 28# fsShellCommand 29# makebootable 30# resattr 31# vmdkimage 32# The following is only for cd types: 33# generate_attribute_stores 34# isCD 35# 36if [ $# -gt 0 ]; then 37 . $1 38 shift 39fi 40 41if [ ! $isCD ]; then 42 # If the haiku image path is a symlink resolve it now (makebootable needs the 43 # path of the actual device path under Linux). 44 normalizedImagePath='' 45 if readlink -f "$imagePath" > /dev/null 2>&1 ; then 46 normalizedImagePath=$(readlink -f "$imagePath") 47 elif realpath "$imagePath" > /dev/null 2>&1 ; then 48 normalizedImagePath=$(realpath "$imagePath") 49 elif greadlink -f "$imagePath" > /dev/null 2>&1 ; then 50 normalizedImagePath=$(greadlink -f "$imagePath") 51 fi 52 if [ -n "$normalizedImagePath" ]; then 53 imagePath="$normalizedImagePath" 54 fi 55fi 56 57# this adds the build library dir to LD_LIBRARY_PATH 58eval "$addBuildCompatibilityLibDir" 59 60# map the shell commands 61if [ $isCD ]; then 62 outputDir=$tmpDir/cdsource 63 64 sPrefix= 65 tPrefix="$outputDir/" 66 cd=cd 67 scd=: 68 cp="$copyattr -d" 69 copyAttrs="$copyattr" 70 ln=ln 71 mkdir=mkdir 72 rm=rm 73elif [ $isImage ]; then 74 # If FIFOs are used for the communication with the FS shell, prepare them. 75 if $fsShellCommand --uses-fifos; then 76 fifoBasePath=/tmp/build_haiku_image-$$-fifo 77 toFSShellFifo=${fifoBasePath}-to-shell 78 fromFSShellFifo=${fifoBasePath}-from-shell 79 80 rm -f $toFSShellFifo $fromFSShellFifo 81 mkfifo $toFSShellFifo $fromFSShellFifo 82 83 # Open the FIFOs such that they are ready for the fsShellCommand. This 84 # also makes sure that they remain open until this script exits. When we 85 # exit while the FS shell is still running and waiting for commands, 86 # closing of our file descriptors will break the FIFOs and the FS shell 87 # will exit, too. 88 # Note: A bit of trickery is needed since opening one end blocks until 89 # someone opens the other end. 90 sleep 3<$fromFSShellFifo 1 & 91 exec 6>$fromFSShellFifo 3<$fromFSShellFifo 92 sleep 5<$toFSShellFifo 1 & 93 exec 4>$toFSShellFifo 5<$toFSShellFifo 94 95 # Remove the FIFO files again -- we have the open FDs, so they can 96 # still be used and this makes sure they won't hang around any further. 97 rm -f $toFSShellFifo $fromFSShellFifo 98 99 # Remap the fsShellCommand and bfsShell such that they don't inherit the 100 # wrong FDs. For both fsShellCommand and bfsShell FD 3 is the input from 101 # the respectively other program, FD 4 is the output to it. 102 actualFSShellCommand="$fsShellCommand" 103 actualBFSShell="$bfsShell" 104 105 fsShellCommandWrapper() 106 { 107 $actualFSShellCommand 5>&- 6>&- "$@" 108 } 109 110 bfsShellWrapper() 111 { 112 $actualBFSShell 3>&5 4<&6 "$@" 113 } 114 115 fsShellCommand=fsShellCommandWrapper 116 bfsShell=bfsShellWrapper 117 fi 118 119 # set up the other commands 120 sPrefix=: 121 tPrefix=/myfs/ 122 cd="$fsShellCommand cd" 123 scd="$fsShellCommand cd" 124 cp="$fsShellCommand cp -f" 125 copyAttrs="$fsShellCommand cp -a" 126 ln="$fsShellCommand ln" 127 mkdir="$fsShellCommand mkdir" 128 rm="$fsShellCommand rm" 129 mkindex="$fsShellCommand mkindex" 130else 131 sPrefix= 132 # TODO: This should come from the environment. 133 tPrefix="$installDir/" 134 cd=cd 135 scd=: 136 cp="$copyattr -d" 137 copyAttrs="$copyattr" 138 ln=ln 139 mkdir=mkdir 140 rm=rm 141 mkindex=mkindex 142fi 143 144 145stripDebugInfo() 146{ 147 file="$1" 148 149 # Determine whether the file is an ELF file by checking the ELF signature, 150 # or at least the printable characters. 151 elfMarker=`dd "if=$file" bs=1 skip=1 count=3 2> /dev/null` 152 if [ "$elfMarker" = 'ELF' ]; then 153 # make user-writable first -- some files aren't 154 chmod u+w "$file" 155 strip --strip-debug "$file" 156 fi 157} 158 159extractFile() 160{ 161 # extractFile <archive> <directory> 162 archiveFile=$1 163 targetExtractedDir=$2 164 extractedSubDir=$3 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 [ "$stripOptionalPackageDebugSymbols" = "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