1rule FSameTargetWithPrependedGrist 2{ 3 # SameTargetWithPrependedGrist <target> : <grist to prepend> ; 4 # 5 local target = $(1) ; 6 local gristToPrepend = $(2) ; 7 local grist = $(target:G) ; 8 9 if $(grist) { 10 grist = $(gristToPrepend)!$(grist) ; 11 } else { 12 grist = $(gristToPrepend) ; 13 } 14 15 return $(target:G=$(grist)) ; 16} 17 18rule InitScript 19{ 20 # Note: The script must have been LOCATEd before. 21 local script = $(1) ; 22 local initScript 23 = [ FSameTargetWithPrependedGrist $(script) : init-script ] ; 24 25 if ! [ on $(script) return $(__is_initialized) ] { 26 __is_initialized on $(script) = true ; 27 28 MakeLocate $(initScript) : [ on $(script) return $(LOCATE) ] ; 29 Always $(initScript) ; 30 Depends $(script) : $(initScript) ; 31 32 InitScript1 $(initScript) ; 33 } 34 35 return $(initScript) ; 36} 37 38actions InitScript1 39{ 40 rm -f $(1) 41 echo -n > $(1) 42} 43 44rule AddVariableToScript script : variable : value 45{ 46 # AddVariableToScript <script> : <variable> : <value> ; 47 48 # interpret an empty variable value as empty string 49 if ! $(value) { 50 value = "" ; 51 } 52 53 InitScript $(script) ; 54 55 VARIABLE_DEFS on $(script) += "echo $(variable)=\\\"$(value[1])\\\" >> " ; 56 57 # if the value is an array, add the other array elements 58 value = $(value[2-]) ; 59 while $(value) { 60 VARIABLE_DEFS on $(script) 61 += "echo $(variable)+=\\\" $(value[1])\\\" >> " ; 62 value = $(value[2-]) ; 63 } 64 65 AddVariableToScript1 $(script) ; 66} 67 68actions together AddVariableToScript1 69{ 70 $(VARIABLE_DEFS)$(1); 71} 72 73rule AddTargetVariableToScript 74{ 75 # AddTargetVariableToScript <script> : <target> [ : <variable> ] ; 76 # 77 local script = $(1) ; 78 local target = $(2) ; 79 local variable = $(3:E=$(target:BS)) ; 80 81 InitScript $(script) ; 82 83 # That's not completely save, if one has more than on target with the 84 # same base name. A unique pseudo target would have to be introduced 85 # to do it more correctly. 86 VARIABLE_NAME($(target:BS)) on $(script) = $(variable) ; 87 88 Depends $(script) : $(target) ; 89 AddTargetVariableToScript1 $(script) : $(target) ; 90} 91 92actions AddTargetVariableToScript1 93{ 94 echo "$(VARIABLE_NAME($(2:BS)))=\"$(2)\"" >> $(1) 95} 96 97 98rule AddDirectoryToHaikuImage directoryTokens 99{ 100 # AddDirectoryToHaikuImage <directoryTokens> 101 102 local directory = [ FDirName $(directoryTokens) ] ; 103 directory = $(directory:G=HaikuImage) ; 104 105 if ! [ on $(directory) return $(__is_on_image) ] { 106 INSTALL_DIRECTORIES on haiku-image-contents += $(directory) ; 107 __is_on_image on $(directory) = true ; 108 NotFile $(directory) ; 109 110 # mark the parent dir as not to be created 111 local parent = [ FReverse $(directoryTokens) ] ; 112 parent = [ FReverse $(parent[2-]) ] ; 113 if $(parent) { 114 parent = [ FDirName $(parent) ] ; 115 parent = $(parent:G=HaikuImage) ; 116 DONT_CREATE on $(parent) = true ; 117 } 118 } 119 120 return $(directory) ; 121} 122 123rule FilterImageUpdateTargets targets 124{ 125 # FilterImageUpdateTargets targets 126 127 local filteredTargets ; 128 local target ; 129 for target in $(targets) { 130 if [ on $(target) return $(HAIKU_INCLUDE_IN_IMAGE) ] { 131 filteredTargets += $(target) ; 132 } 133 } 134 return $(filteredTargets) ; 135} 136 137rule AddFilesToHaikuImage 138{ 139 # AddFilesToHaikuImage <directory> : <targets> [ : dest name ] 140 # 141 local directory = [ AddDirectoryToHaikuImage $(1) ] ; 142 local targets = $(2) ; 143 local destName = $(3) ; 144 145 # If the image shall only be updated, we filter out all targets not marked 146 # accordingly. 147 if $(HAIKU_IMAGE_UPDATE_ONLY) { 148 targets = [ FilterImageUpdateTargets $(targets) ] ; 149 } 150 151 # We create a unique dummy target per target to install. 152 local target ; 153 for target in $(targets) { 154 local name ; 155 if $(destName) { 156 name = $(destName) ; 157 } else { 158 name = $(target:G=:D=) ; 159 } 160 161 local destTarget = $(name:G=HaikuImage__$(directory:G=)) ; 162 TARGET on $(destTarget) = $(target) ; 163 INSTALL_DIR on $(destTarget) = $(directory) ; 164 INSTALL_TARGETS on $(target) += $(destTarget) ; 165 TARGETS_TO_INSTALL on $(directory) += $(destTarget) ; 166 } 167} 168 169rule AddSymlinkToHaikuImage directoryTokens : linkTarget : linkName 170{ 171 # AddSymlinkToHaikuImage <directory> : <link target> [ : <link name> ] ; 172 # 173 174 # If the image shall only be updated, we don't add any symlinks. 175 if $(HAIKU_IMAGE_UPDATE_ONLY) { 176 return ; 177 } 178 179 local directory = [ AddDirectoryToHaikuImage $(directoryTokens) ] ; 180 181 if ! $(linkName) { 182 local path = [ FReverse [ FSplitPath $(linkTarget) ] ] ; 183 linkName = $(path[1]) ; 184 } 185 186 local link = $(directory)/$(linkName) ; 187 SYMLINK_TARGET on $(link) = $(linkTarget) ; 188 SYMLINKS_TO_INSTALL on $(directory) += $(link) ; 189} 190 191rule AddSourceDirectoryToHaikuImage dirTokens : alwaysUpdate 192{ 193 # AddSourceDirectoryToHaikuImage <dirTokens> : <alwaysUpdate> ; 194 195 # If the image shall only be updated, we update sources only, if explicitely 196 # requested. 197 if ! $(HAIKU_IMAGE_UPDATE_ONLY) || $(alwaysUpdate) { 198 HAIKU_INSTALL_SOURCE_DIRS += [ FDirName $(HAIKU_TOP) $(dirTokens) ] ; 199 } 200} 201 202rule AddDriversToHaikuImage 203{ 204 # AddDriversToHaikuImage <relative directory> : <targets> ; 205 # 206 local relativeDirectoryTokens = $(1) ; 207 local targets = $(2) ; 208 local directoryTokens = beos system add-ons kernel drivers dev 209 $(relativeDirectoryTokens) ; 210 211 AddFilesToHaikuImage beos system add-ons kernel drivers bin : $(targets) ; 212 213 # If the image shall only be updated, we don't add any symlinks. 214 if $(HAIKU_IMAGE_UPDATE_ONLY) { 215 return ; 216 } 217 218 # get the relative symlink path prefix 219 local linkPrefix = ; 220 for i in $(relativeDirectoryTokens) { 221 linkPrefix += .. ; 222 } 223 linkPrefix += .. bin ; 224 225 # add the symlinks 226 local name ; 227 for name in $(targets:BS) { 228 AddSymlinkToHaikuImage $(directoryTokens) 229 : [ FDirName $(linkPrefix) $(name) ] : $(name) ; 230 } 231} 232 233rule AddDriverRegistrationToHaikuImage 234{ 235 # AddDriverRegistrationToHaikuImage <directory> : <link target> : <link names> ] ; 236 # 237 local relativeDirectoryTokens = $(1) ; 238 local target = $(2) ; 239 local links = $(3) ; 240 local directoryTokens = beos system add-ons kernel registration 241 $(relativeDirectoryTokens) ; 242 243 # get the relative symlink path prefix 244 local linkPrefix = ; 245 for i in $(relativeDirectoryTokens) { 246 linkPrefix += .. ; 247 } 248 linkPrefix += .. drivers bin ; 249 250 # add the symlink 251 AddSymlinkToHaikuImage $(directoryTokens) 252 : [ FDirName $(linkPrefix) $(target:BS) ] : $(links) ; 253} 254 255rule AddBootModuleSymlinks targets 256{ 257 # AddBootModuleSymlinks <targets> ; 258 # 259 260 # If the image shall only be updated, we don't add any symlinks. 261 if $(HAIKU_IMAGE_UPDATE_ONLY) { 262 return ; 263 } 264 265 # add the symlinks 266 local target ; 267 for target in $(targets) { 268 # Symlink to the first place where the target has been installed. 269 local destTarget = [ on $(target) return $(INSTALL_TARGETS[1]) ] ; 270 local installDir = [ on $(destTarget) return $(INSTALL_DIR) ] ; 271 272 if ! $(installDir) { 273 Echo "ERROR: AddBootModuleSymlinks: Can't create a symlink to" 274 "target" \"$(target)"\"." ; 275 Exit "ERROR: Add*ToHaikuImage has not been invoked for it yet." ; 276 } 277 278 local name = $(target:BS) ; 279 local linkTarget = [ FDirName /boot $(installDir:G=) $(name) ] ; 280 281 AddSymlinkToHaikuImage beos system add-ons kernel boot 282 : $(linkTarget) : $(name) ; 283 } 284} 285 286rule CreateHaikuImageMakeDirectoriesScript 287{ 288 local script = $(1) ; 289 MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ; 290 Always $(script) ; 291 292 local initScript = [ InitScript $(script) ] ; 293 294 local scriptBody 295 = [ FSameTargetWithPrependedGrist $(script) : script-body ] ; 296 LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ; 297 Depends $(scriptBody) : $(initScript) ; 298 Depends $(script) : $(scriptBody) ; 299 300 local dirsToCreate ; 301 local dir ; 302 for dir in [ on haiku-image-contents return $(INSTALL_DIRECTORIES) ] { 303 if ! [ on $(dir) return $(DONT_CREATE) ] { 304 dirsToCreate += $(dir) ; 305 } 306 } 307 308 Depends $(scriptBody) : $(dirsToCreate) ; 309 # If the image shall only be updated, we don't create directories. 310 if $(dirsToCreate) && ! $(HAIKU_IMAGE_UPDATE_ONLY) { 311 CreateHaikuImageMakeDirectoriesScript1 $(scriptBody) : $(dirsToCreate) ; 312 } 313} 314 315actions piecemeal CreateHaikuImageMakeDirectoriesScript1 316{ 317 echo \$mkdir -p "\"\${tPrefix}$(2:G=)\"" >> $(1) 318} 319 320rule CreateHaikuImageCopyFilesScript 321{ 322 local script = $(1) ; 323 MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ; 324 Always $(script) ; 325 326 local initScript = [ InitScript $(script) ] ; 327 328 local scriptBody 329 = [ FSameTargetWithPrependedGrist $(script) : script-body ] ; 330 LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ; 331 Depends $(scriptBody) : $(initScript) ; 332 Depends $(script) : $(scriptBody) ; 333 334 local dir ; 335 for dir in [ on haiku-image-contents return $(INSTALL_DIRECTORIES) ] { 336 # filter the targets that shall be renamed; they have to be copied 337 # individually 338 local destTargets = [ on $(dir) return $(TARGETS_TO_INSTALL) ] ; 339 local remainingTargets ; 340 local destTarget ; 341 for destTarget in $(destTargets) { 342 local target = [ on $(destTarget) return $(TARGET) ] ; 343 local name = $(destTarget:BS) ; 344 if $(name) != $(target:BS) { 345 # use a unique dummy target for this file, on which we 346 # can define the TARGET_DIR variable 347 local dummyTarget = $(script)-dummy-$(dir:G=)-$(target) ; 348 NotFile $(dummyTarget) ; 349 TARGET_DIR on $(dummyTarget) = $(dir:G=) ; 350 INSTALL_TARGET_NAME on $(dummyTarget) = $(name) ; 351 352 Depends $(dummyTarget) : $(initScript) $(target) ; 353 Depends $(script) : $(dummyTarget) ; 354 355 AppendToHaikuImageCopyFilesScriptSingleFile $(dummyTarget) 356 : $(initScript) $(target) ; 357 } else { 358 remainingTargets += $(target) ; 359 } 360 } 361 targets = $(remainingTargets) ; 362 363 if $(targets) { 364 # use a unique dummy target for this directory, on which we 365 # can define the TARGET_DIR variable 366 local dummyTarget = $(script)-dummy-$(dir:G=) ; 367 NotFile $(dummyTarget) ; 368 TARGET_DIR on $(dummyTarget) = $(dir:G=) ; 369 370 Depends $(dummyTarget) : $(initScript) $(targets) ; 371 Depends $(script) : $(dummyTarget) ; 372 373 OUTPUT_SCRIPT on $(dummyTarget) = $(initScript) ; 374 AppendToHaikuImageCopyFilesScript $(dummyTarget) : $(targets) ; 375 } 376 377 local symlinks = [ on $(dir) return $(SYMLINKS_TO_INSTALL) ] ; 378 local symlink ; 379 for symlink in $(symlinks) { 380 NotFile $(symlink) ; 381 382 Depends $(script) : $(symlink) ; 383 Depends $(symlink) : $(initScript) ; 384 385 AddSymlinkToHaikuImageCopyFilesScript $(symlink) : $(initScript) ; 386 } 387 } 388} 389 390actions piecemeal AppendToHaikuImageCopyFilesScript bind OUTPUT_SCRIPT 391{ 392 echo \$cp "\"\${sPrefix}$(2)\"" "\"\${tPrefix}$(TARGET_DIR)\"" >> $(OUTPUT_SCRIPT) 393} 394 395actions AppendToHaikuImageCopyFilesScriptSingleFile 396{ 397 echo \$cp "\"\${sPrefix}$(2[2])\"" \ 398 "\"\${tPrefix}$(TARGET_DIR)/$(INSTALL_TARGET_NAME)\"" >> $(2[1]) 399} 400 401actions AddSymlinkToHaikuImageCopyFilesScript 402{ 403 echo \$ln -sfn "\"$(SYMLINK_TARGET)\"" "\"\${tPrefix}$(1:G=)\"" >> $(2[1]) 404} 405 406rule BuildHaikuImage 407{ 408 # BuildHaikuImage <haiku image> : <scripts> : <is image> ; 409 # 410 local haikuImage = $(1) ; 411 local scripts = $(2) ; 412 local isImage = $(3) ; 413 414 if $(isImage) = 1 || $(isImage) = true { 415 IS_IMAGE on $(haikuImage) = 1 ; 416 } else { 417 IS_IMAGE on $(haikuImage) = "" ; 418 } 419 420 local mainScript = build_haiku_image ; 421 SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ; 422 423 Depends $(haikuImage) : $(mainScript) $(scripts) ; 424 BuildHaikuImage1 $(haikuImage) : $(mainScript) $(scripts) ; 425} 426 427actions BuildHaikuImage1 428{ 429 export isImage="$(IS_IMAGE)" 430 $(2[1]) $(2[2-]) 431} 432 433rule BuildVMWareImage vmwareImage : plainImage : imageSize 434{ 435 # BuildVMWareImage <vmware image> : <plain image> : <image size in MB> 436 437 IMAGE_SIZE on $(vmwareImage) = $(imageSize) ; 438 439 Depends $(vmwareImage) : <build>vmdkheader $(plainImage) ; 440 BuildVMWareImage1 $(vmwareImage) : <build>vmdkheader $(plainImage) ; 441} 442 443actions BuildVMWareImage1 444{ 445 rm -f $(1) 446 $(2[1]) -h 64k -i$(IMAGE_SIZE)M $(1) && 447 cat $(2[2]) >> $(1) 448} 449