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# stripCommand 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 "$stripCommand" --strip-debug "$file" 156 fi 157} 158 159extractFile() 160{ 161 # extractFile <archive> <directory> <extractedSubDir> <stripDebugSymbols> 162 archiveFile=$1 163 targetExtractedDir=$2 164 extractedSubDir=$3 165 stripDebugSymbols=$4 166 167 echo "Extracting $archiveFile ..." 168 169 extractDir=$tmpDir/extract 170 $rmAttrs -rf "$extractDir" 171 mkdir -p "$extractDir" 172 173 case "$archiveFile" in 174 *.zip) 175 $unzip -q -d "$extractDir" "$archiveFile" 176 ;; 177 *.tgz|*.tar.gz) 178 tar -C "$extractDir" -xf "$archiveFile" 179 ;; 180 *) 181 echo "Unhandled archive extension in build_haiku_image extractFile()" 182 exit 1 183 ;; 184 esac 185 186 if [ -f $extractDir/.OptionalPackageDescription ]; then 187 cat $extractDir/.OptionalPackageDescription >> $copyrightsFile 188 echo >> $copyrightsFile 189 rm $extractDir/.OptionalPackageDescription 190 fi 191 192 if [ "$stripDebugSymbols" = "1" ]; then 193 # strip executables in common/bin 194 if [ -d $extractDir/common/bin ]; then 195 for file in `find $extractDir/common/bin -type f -a -perm +100 \ 196 -a -size +1k`; do 197 stripDebugInfo "$file" 198 done 199 fi 200 201 # strip libraries in common/lib 202 if [ -d $extractDir/common/lib ]; then 203 for file in `find $extractDir/common/lib -type f -a -size +1k \ 204 -a -name lib\*`; do 205 stripDebugInfo "$file" 206 done 207 fi 208 fi 209 210 $cp -r "${sPrefix}$extractDir/$extractedSubDir/." "${tPrefix}$targetExtractedDir" 211 212 $rmAttrs -rf "$extractDir" 213} 214 215 216mkdir -p $tmpDir 217copyrightsFile=$tmpDir/copyrights 218$rmAttrs -f $copyrightsFile 219if [ "$optionalPackageDescriptions" ]; then 220 cp "$optionalPackageDescriptions" $copyrightsFile 221fi 222 223if [ $isCD ]; then 224 # setup output dir 225 $rmAttrs -rf "$outputDir" 226 mkdir -p "$outputDir" 227fi 228 229# create the image and mount it 230if [ $isImage ]; then 231 echo 232 233 imageOffsetFlags= 234 if [ $isVMwareImage ]; then 235 imageOffsetFlags="--start-offset 65536" 236 fi 237 238 if [ ! $updateOnly ]; then 239 echo "Creating image ..." 240 241 imageFlags="-i${imageSize}M" 242 if [ ! "$dontClearImage" ]; then 243 imageFlags="$imageFlags -c" 244 fi 245 246 if [ $isVMwareImage ]; then 247 $vmdkimage -h 64k $imageFlags "$imagePath" 248 else 249 $createImage $imageFlags "$imagePath" 250 fi 251 252 $bfsShell --initialize $imageOffsetFlags "$imagePath" \ 253 "$imageLabel" "block_size 2048" 254 $makebootable $imageOffsetFlags "$imagePath" 255 fi 256 257 $bfsShell -n $imageOffsetFlags "$imagePath" > /dev/null & 258 sleep 1 259 260 # Close FDs 5 and 6. Those represent the pipe ends that are used by the 261 # FS shell. Closing them in the shell process makes sure an unexpected death 262 # of the FS shell causes writing to/reading from the other ends to fail 263 # immediately. 264 exec 5>&- 6>&- 265 266 # bail out, if mounting fails 267 $cd . 268fi 269 270echo "Populating image ..." 271while [ $# -gt 0 ]; do 272 . $1 273 shift 274done 275 276 277# install MIME database 278# TODO: It should be possible to do that in the build system too. 279 280if [ ! $updateOnly ]; then 281 mimeDBSource=$sourceDir/src/data/beos_mime 282 mimeDBDest=${tPrefix}home/config/settings/beos_mime 283 284 echo "Deleting old MIME database ..." 285 286 $rm -rf $mimeDBDest 287 $mkdir -p $mimeDBDest 288 mimeTmpDir=$tmpDir/mime 289 mimeDBTmpDir=$tmpDir/mime/db 290 mimeTmpIndex=0 291 mimeTmpFile=$mimeTmpDir/mimedb$$.rsrc 292 293 # create tmp dir for the MIME conversion stuff 294 mkdir -p $mimeDBTmpDir 295 296 echo "Installing MIME database ..." 297 298 for inSuperFile in $mimeDBSource/*.super; do 299 superType=$(basename $inSuperFile .super) 300 tmpSuperDir=$mimeDBTmpDir/$superType 301 302 # compile rdef to rsrc file and the rsrc file to attributes 303 $rc -o $mimeTmpFile $inSuperFile 304 mkdir -p $tmpSuperDir 305 $resattr -O -o $tmpSuperDir $mimeTmpFile 306 $rmAttrs $mimeTmpFile 307 308 # iterate through the sub types 309 for inSubFile in $mimeDBSource/$superType/*; do 310 # check, if the type exists 311 if test -f $inSubFile && grep META:TYPE $inSubFile > /dev/null 2>&1 ; then 312 subType=$(basename $inSubFile) 313 tmpSubFile=$mimeDBTmpDir/$superType/$subType 314 315 # compile rdef to rsrc file and the rsrc file to attributes 316 $rc -o $mimeTmpFile $inSubFile 317 $resattr -O -o $tmpSubFile $mimeTmpFile 318 $rmAttrs $mimeTmpFile 319 fi 320 done 321 done 322 323 $cp -r ${sPrefix}$mimeDBTmpDir/. $mimeDBDest 324 325 # cleanup tmp dir 326 $rmAttrs -rf $mimeTmpDir 327fi # ! updateOnly 328 329 330# add the concatenated copyrights as an attribute to AboutSystem 331 332if [ ! $updateOnly ]; then 333 if [ -f $copyrightsFile ]; then 334 copyrightAttrs=$tmpDir/copyrightAttrs 335 $rmAttrs -f $copyrightAttrs 336 touch $copyrightAttrs 337 $addattr -f $copyrightsFile COPYRIGHTS $copyrightAttrs 338 $copyAttrs ${sPrefix}$copyrightAttrs ${tPrefix}system/apps/AboutSystem 339 fi 340fi 341 342if [ $isCD ]; then 343 # generate the attribute stores 344 echo "Generating attribute stores ..." 345 $generate_attribute_stores "$tPrefix" 346 347 echo "Copying boot image ..." 348 $cp "$cdBootFloppy" "$outputDir" 349 350 if [ $(which mkisofs) ]; then 351 # build the iso image using mkisofs 352 echo "Building CD image (mkisofs)..." 353 mkisofs -uid 0 -gid 0 -b `basename $cdBootFloppy` -R -V "$cdLabel" -o "$cdImagePath" "$tPrefix" 354 elif [ $(which genisoimage) ]; then 355 # build the iso image using genisoimage 356 echo "Building CD image (genisoimage)..." 357 echo "WARNING: genisoimage fallback has known problems with long filenames!" 358 echo " Please install mkisofs before making production releases!" 359 genisoimage -r -iso-level 4 -b `basename $cdBootFloppy` -V "$cdLabel" -o "$cdImagePath" "$tPrefix" 360 else 361 echo "you need mkisofs (preferred) or genisoimage to create a CD image." 362 exit 1 363 fi 364 365 # cleanup output dir 366 $rmAttrs -rf "$outputDir" 367fi 368 369# unmount 370if [ $isImage ]; then 371 echo "Unmounting ..." 372 $fsShellCommand sync 373 $fsShellCommand quit 374fi 375