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) $(1) 41 touch $(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)=\\\" \\\$$(variable) $(value[1])\\\" >> " ; 62 value = $(value[2-]) ; 63 } 64 65 AddVariableToScript1 $(script) ; 66} 67 68actions together AddVariableToScript1 69{ 70 $(VARIABLE_DEFS)$(1); 71} 72 73 74rule AddTargetVariableToScript script : targets : variable 75{ 76 # AddTargetVariableToScript <script> : <targets> [ : <variable> ] ; 77 # 78 # If <targets> contains multiple targets, their paths must not contain 79 # whitespaces or other characters that need to be escaped in the shell. 80 # 81 variable ?= $(3:E=$(targets[1]:BS)) ; 82 83 local initScript = [ InitScript $(script) ] ; 84 85 serialization = [ on $(script) return $(HAIKU_SERIALIZATION) ] ; 86 87 local variableTarget = [ NewUniqueTarget ] ; 88 NotFile $(variableTarget) ; 89 Depends $(variableTarget) : $(initScript) $(targets) $(serialization) ; 90 Depends $(script) : $(variableTarget) ; 91 92 HAIKU_SERIALIZATION on $(script) = $(variableTarget) ; 93 94 HAIKU_VARIABLE_NAME on $(variableTarget) = $(variable) ; 95 AddTargetVariableToScript1 $(variableTarget) : $(initScript) $(targets) ; 96} 97 98 99actions AddTargetVariableToScript1 100{ 101 script="$(2[1])" 102 echo "$(HAIKU_VARIABLE_NAME)=" >> "$script" 103 104 firstSeen= 105 for value in "$(2[2-])" ; do 106 if [ -z "$firstSeen" ]; then 107 echo "$(HAIKU_VARIABLE_NAME)=\"$value\"" >> "$script" 108 firstSeen=1 109 else 110 echo "$(HAIKU_VARIABLE_NAME)=\"\$$(HAIKU_VARIABLE_NAME) $value\"" \ 111 >> "$script" 112 fi 113 done 114} 115 116 117#pragma mark - 118 119rule AddDirectoryToContainer container : directoryTokens : attributeFiles 120{ 121 # AddDirectoryToContainer <container> : <directoryTokens> : <attributeFiles> 122 123 local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ; 124 local directory = [ FDirName $(directoryTokens) ] ; 125 directory = $(directory:G=$(containerGrist)) ; 126 127 if ! [ on $(directory) return $(__is_on_image) ] { 128 HAIKU_INSTALL_DIRECTORIES on $(container) += $(directory) ; 129 __is_on_image on $(directory) = true ; 130 DIRECTORY_TOKENS on $(directory) = $(directoryTokens) ; 131 NotFile $(directory) ; 132 133 # mark the parent dir as not to be created 134 local parent = [ FReverse $(directoryTokens) ] ; 135 parent = [ FReverse $(parent[2-]) ] ; 136 if $(parent) { 137 parent = [ FDirName $(parent) ] ; 138 parent = $(parent:G=$(containerGrist)) ; 139 DONT_CREATE on $(parent) = true ; 140 } 141 } 142 143 if $(attributeFiles) { 144 SEARCH on $(attributeFiles) 145 += [ FDirName $(HAIKU_TOP) src data directory_attrs ] ; 146 ATTRIBUTE_FILES on $(directory) += $(attributeFiles) ; 147 } 148 149 return $(directory) ; 150} 151 152rule FilterContainerUpdateTargets targets : filterVariable 153{ 154 # FilterContainerUpdateTargets targets : filterVariable 155 156 local filteredTargets ; 157 local target ; 158 for target in $(targets) { 159 if [ on $(target) return $($(filterVariable)) ] { 160 filteredTargets += $(target) ; 161 } 162 } 163 return $(filteredTargets) ; 164} 165 166 167rule IncludeAllTargetsInContainer container 168{ 169 local filterVar 170 = [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ; 171 if $(filterVar) { 172 return $($(filterVar)) ; 173 } 174 175 return ; 176} 177 178 179rule PropagateContainerUpdateTargetFlags toTarget : fromTarget 180{ 181 if [ on $(fromTarget) return $(HAIKU_INCLUDE_IN_IMAGE) ] { 182 HAIKU_INCLUDE_IN_IMAGE on $(toTarget) = 1 ; 183 } 184 185 if [ on $(fromTarget) return $(HAIKU_INCLUDE_IN_PACKAGES) ] { 186 HAIKU_INCLUDE_IN_PACKAGES on $(toTarget) = 1 ; 187 } 188} 189 190 191rule AddFilesToContainer container : directoryTokens : targets : destName 192 : flags 193{ 194 # AddFilesToContainer <container> : <directoryTokens> : <targets> 195 # : [ <destName> ] : [ <flags> ] 196 # 197 # Supported flags: 198 # computeName - <destName> is the name of a shell command/function that 199 # computes the destination name. 200 # alwaysUpdate - When only updating the container, always also update the 201 # given targets. 202 203 local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ; 204 local systemDirTokens 205 = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; 206 207 targets = [ FFilterByBuildFeatures $(targets) ] ; 208 209 # If the image shall only be updated, we filter out all targets not marked 210 # accordingly. 211 if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] 212 && ! [ IncludeAllTargetsInContainer $(container) ] 213 && ! alwaysUpdate in $(flags) { 214 local filterVar 215 = [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ; 216 if $(filterVar) { 217 targets = [ FilterContainerUpdateTargets $(targets) 218 : $(filterVar) ] ; 219 220 # If there are any targets, mark the container as to be included in 221 # an update, too, if it has set the update inheritance variable. 222 # This makes updating a target that lives in a package on an image 223 # work. 224 if $(targets) { 225 local updateVariable = [ on $(container) return 226 $(HAIKU_CONTAINER_INHERIT_UPDATE_VARIABLE) ] ; 227 if $(updateVariable) { 228 $(updateVariable) on $(container) = 1 ; 229 } 230 } 231 } 232 } 233 234 if ! $(targets) { 235 return ; 236 } 237 238 local directory = [ AddDirectoryToContainer $(container) 239 : $(directoryTokens) ] ; 240 241 # We create a unique dummy target per target to install. 242 local installTargetsVar 243 = [ on $(container) return $(HAIKU_INSTALL_TARGETS_VAR) ] ; 244 local stripExecutables 245 = [ on $(container) return $(HAIKU_CONTAINER_STRIP_EXECUTABLES) ] ; 246 local target ; 247 for target in $(targets) { 248 local name ; 249 local nameFunction ; 250 if $(destName) { 251 if computeName in $(flags) { 252 nameFunction = $(destName) ; 253 name = $(destName)/$(target:BSM) ; 254 } else { 255 name = $(destName) ; 256 } 257 } else { 258 name = $(target:BSM) ; 259 } 260 261 local installTarget = $(target) ; 262 if $(stripExecutables) 263 && [ on $(target) return $(HAIKU_TARGET_IS_EXECUTABLE) ] { 264 installTarget = [ StripFiles $(target) ] ; 265 } 266 267 local destTarget = $(name:G=$(containerGrist)__$(directory:G=)) ; 268 TARGET on $(destTarget) = $(installTarget) ; 269 INSTALL_DIR on $(destTarget) = $(directory) ; 270 NAME_FUNCTION on $(destTarget) = $(nameFunction) ; 271 $(installTargetsVar) on $(target) += $(destTarget) ; 272 TARGETS_TO_INSTALL on $(directory) += $(destTarget) ; 273 274 # If the target and its static libraries are associated with catalog 275 # files, add those, too. 276 local catalogTargets = $(target) + [ on $(target) return $(NEEDLIBS) ] ; 277 for catalogTarget in $(catalogTargets) { 278 local catalogs 279 = [ on $(catalogTarget) return $(HAIKU_CATALOG_FILES) ] ; 280 if $(catalogs) { 281 local signature 282 = [ on $(catalogTarget) 283 return $(HAIKU_CATALOG_SIGNATURE) ] ; 284 AddFilesToContainer $(container) 285 : $(systemDirTokens) data locale catalogs $(signature) 286 : $(catalogs) ; 287 } 288 } 289 290 # If the target is associated with MIME DB entries, add those, too. 291 local mimeDBEntries = [ on $(target) return $(HAIKU_MIME_DB_ENTRIES) ] ; 292 if $(mimeDBEntries) { 293 # Make sure we add the entries only once by tracking the containers 294 # we have already added it to. 295 local containers = [ on $(mimeDBEntries) 296 return $(HAIKU_MIME_DB_ENTRIES_IN_CONTAINERS) ] ; 297 if ! $(container) in $(containers) { 298 HAIKU_MIME_DB_ENTRIES_IN_CONTAINERS on $(mimeDBEntries) 299 = $(containers) $(container) ; 300 CopyDirectoryToContainer $(container) : data 301 : $(mimeDBEntries) : mime_db : : alwaysUpdate isTarget ; 302 } 303 } 304 } 305} 306 307rule FFilesInContainerDirectory container : directoryTokens 308{ 309 local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ; 310 local directory = [ FDirName $(directoryTokens) ] ; 311 directory = $(directory:G=$(containerGrist)) ; 312 313 if [ on $(directory) return $(__is_on_image) ] { 314 on $(directory) return $(TARGETS_TO_INSTALL) ; 315 } 316 317 return ; 318} 319 320rule AddSymlinkToContainer container : directoryTokens : linkTarget : linkName 321{ 322 # AddSymlinkToContainer <container> : <directory> : <link target> 323 # [ : <link name> ] ; 324 # 325 326 # If the image shall only be updated, we don't add any symlinks. 327 if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] 328 && ! [ IncludeAllTargetsInContainer $(container) ] { 329 return ; 330 } 331 332 local directory = [ AddDirectoryToContainer $(container) 333 : $(directoryTokens) ] ; 334 335 if ! $(linkName) { 336 local path = [ FReverse [ FSplitPath $(linkTarget) ] ] ; 337 linkName = $(path[1]) ; 338 } 339 340 local link = $(directory)/$(linkName) ; 341 SYMLINK_TARGET on $(link) = $(linkTarget) ; 342 SYMLINKS_TO_INSTALL on $(directory) += $(link) ; 343} 344 345rule FSymlinksInContainerDirectory container : directoryTokens 346{ 347 local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ; 348 local directory = [ FDirName $(directoryTokens) ] ; 349 directory = $(directory:G=$(containerGrist)) ; 350 351 if [ on $(directory) return $(__is_on_image) ] { 352 on $(directory) return $(SYMLINKS_TO_INSTALL) ; 353 } 354 355 return ; 356} 357 358rule CopyDirectoryToContainer container : directoryTokens : sourceDirectory 359 : targetDirectoryName : excludePatterns : flags 360{ 361 # CopyDirectoryToContainer <container> : <directoryTokens> 362 # : <sourceDirectory> : <targetDirectoryName> : <excludePatterns> 363 # [ : <flags> ] ; 364 # 365 # Supported flags: alwaysUpdate, isTarget 366 # isTarget: <sourceDirectory> is a target, not a path 367 368 # If the image shall only be updated, we don't copy any directories 369 if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] 370 && ! [ IncludeAllTargetsInContainer $(container) ] 371 && ! alwaysUpdate in $(flags) { 372 return ; 373 } 374 375 if ! $(targetDirectoryName) { 376 targetDirectoryName = $(sourceDirectory[1]:BSM) ; 377 } 378 379 # If sourceDirectory is a path, not a target, make it a target, so we can 380 # treat both the same way. 381 if ! isTarget in $(flags) { 382 sourceDirectory = $(sourceDirectory:G=copy-directory-to-container) ; 383 SEARCH on $(sourceDirectory) = ; 384 TARGET on $(sourceDirectory) = ; 385 } 386 387 local directory = [ AddDirectoryToContainer $(container) 388 : $(directoryTokens) $(targetDirectoryName) ] ; 389 390 local targetDir = $(directory)/-/$(sourceDirectory) ; 391 Depends $(targetDir) : $(sourceDirectory) ; 392 EXCLUDE_PATTERNS on $(targetDir) = $(excludePatterns) ; 393 SOURCE_DIRECTORY on $(targetDir) = $(sourceDirectory) ; 394 TARGET_DIRECTORY on $(targetDir) = $(directory) ; 395 DIRECTORIES_TO_INSTALL on $(directory) += $(targetDir) ; 396} 397 398 399rule AddHeaderDirectoryToContainer container : dirTokens : dirName 400 : flags 401{ 402 # AddHeaderDirectoryToContainer <container> : <dirTokens> : [ <dirName> ] 403 # [ : <flags> ] ; 404 # 405 # Supported flags: alwaysUpdate 406 407 local systemDirTokens 408 = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; 409 410 CopyDirectoryToContainer $(container) : $(systemDirTokens) develop headers 411 : [ FDirName $(HAIKU_TOP) headers $(dirTokens) ] 412 : $(dirName) : -x *~ : $(flags) ; 413} 414 415 416rule AddWifiFirmwareToContainer container : driver : package : archive : extract 417{ 418 # AddWifiFirmwareToContainer <container> : <driver> : <package> : <archive> 419 # : <extract> 420 421 # complete location to wifi firmware archive 422 local firmwareArchive = [ FDirName 423 $(HAIKU_TOP) data system data firmware $(driver) $(archive) ] ; 424 425 local systemDirTokens 426 = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; 427 428 local dirTokens = $(systemDirTokens) data firmware $(driver) ; 429 if $(extract) = true || $(extract) = 1 { 430 ExtractArchiveToContainer $(container) : $(dirTokens) 431 : $(firmwareArchive) : : $(package) ; 432 } else { 433 AddFilesToContainer $(container) : $(dirTokens) : $(firmwareArchive) ; 434 } 435} 436 437 438rule ExtractArchiveToContainer container : directoryTokens : archiveFile 439 : flags : extractedSubDir 440{ 441 # ExtractArchiveToContainer <container> : <directory> : <archiveFile> 442 # : [ <flags> ] : <extractedSubDir> ; 443 # 444 # Supported flags: alwaysUpdate 445 446 # If the container shall only be updated, we extract only, if explicitely 447 # requested. 448 if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] 449 && ! alwaysUpdate in $(flags) { 450 return ; 451 } 452 453 local directory = [ AddDirectoryToContainer $(container) 454 : $(directoryTokens) ] ; 455 456 ARCHIVE_FILES_TO_INSTALL on $(directory) += $(archiveFile) ; 457 ARCHIVE_SUBDIR_TO_INSTALL_FROM on $(archiveFile) = $(extractedSubDir) ; 458} 459 460rule AddDriversToContainer container : relativeDirectoryTokens : targets 461{ 462 # AddDriversToContainer <container> : <relative directory> : <targets> ; 463 # 464 local systemDirTokens 465 = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; 466 local directoryTokens = $(systemDirTokens) add-ons kernel drivers dev 467 $(relativeDirectoryTokens) ; 468 469 targets = [ FFilterByBuildFeatures $(targets) ] ; 470 471 # A driver can be in multiple categories. Avoid adding it to the bin/ 472 # directory more than once. 473 local binTargets ; 474 local target ; 475 for target in $(targets) { 476 local containers 477 = [ on $(target) return $(HAIKU_DRIVER_IN_CONTAINERS) ] ; 478 if ! $(container) in $(containers) { 479 HAIKU_DRIVER_IN_CONTAINERS on $(target) 480 = $(containers) $(container) ; 481 binTargets += $(target) ; 482 } 483 } 484 485 AddFilesToContainer $(container) 486 : $(systemDirTokens) add-ons kernel drivers bin 487 : $(binTargets) ; 488 489 # If the image shall only be updated, we don't add any symlinks. 490 if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] 491 && ! [ IncludeAllTargetsInContainer $(container) ] { 492 return ; 493 } 494 495 # get the relative symlink path prefix 496 local linkPrefix = ; 497 local i ; 498 for i in $(relativeDirectoryTokens) { 499 linkPrefix += .. ; 500 } 501 linkPrefix += .. bin ; 502 503 # add the symlinks 504 local name ; 505 for name in $(targets:BSM) { 506 AddSymlinkToContainer $(container) : $(directoryTokens) 507 : [ FDirName $(linkPrefix) $(name) ] : $(name) ; 508 } 509} 510 511rule AddNewDriversToContainer container : relativeDirectoryTokens 512 : targets : flags 513{ 514 # AddNewDriversToContainer <container> : <directory> : <targets> : <flags> ; 515 # 516 # Supported flags: 517 # alwaysUpdate - When only updating the container, always also update the 518 # given targets. 519 520 local systemDirTokens 521 = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; 522 local directoryTokens = $(systemDirTokens) add-ons kernel drivers 523 $(relativeDirectoryTokens) ; 524 525 targets = [ FFilterByBuildFeatures $(targets) ] ; 526 527 AddFilesToContainer $(container) : $(directoryTokens) 528 : $(targets) : : $(flags) ; 529} 530 531rule AddBootModuleSymlinksToContainer container : targets 532{ 533 # AddBootModuleSymlinksToContainer <container> : <targets> ; 534 # 535 536 # If the container shall only be updated, we don't add any symlinks. 537 538 if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] 539 && ! [ IncludeAllTargetsInContainer $(container) ] { 540 return ; 541 } 542 543 local systemDirTokens 544 = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; 545 targets = [ FFilterByBuildFeatures $(targets) ] ; 546 547 # add the symlinks 548 local installTargetsVar 549 = [ on $(container) return $(HAIKU_INSTALL_TARGETS_VAR) ] ; 550 local target ; 551 for target in $(targets) { 552 # Symlink to the first place where the target has been installed. 553 local destTarget = [ on $(target) return $($(installTargetsVar)[1]) ] ; 554 local installDir = [ on $(destTarget) return $(INSTALL_DIR) ] ; 555 556 if ! $(installDir) { 557 Echo "ERROR: AddBootModuleSymlinksToContainer: Can't create a " 558 "symlink to target" \"$(target)"\"." ; 559 Exit "ERROR: Add*ToContainer has not been invoked for it yet." ; 560 } 561 562 # chop off the system dir prefix from installDir 563 installDir = [ on $(installDir) return $(DIRECTORY_TOKENS) ] ; 564 local dummy ; 565 for dummy in $(systemDirTokens) { 566 installDir = $(installDir[2-]) ; 567 } 568 569 local name = $(target:BSM) ; 570 local linkTarget = [ FDirName ../../.. $(installDir) $(name) ] ; 571 572 AddSymlinkToContainer $(container) 573 : $(systemDirTokens) add-ons kernel boot 574 : $(linkTarget) : $(name) ; 575 } 576} 577 578 579rule AddLibrariesToContainer container : directory : libs 580{ 581 # AddLibrariesToContainer <container> : <directory> : <libs> 582 # 583 # Installs libraries with the appropriate links into the container. 584 # 585 586 local lib ; 587 for lib in $(libs) { 588 local abiVersion = [ on $(lib) return $(HAIKU_LIB_ABI_VERSION) ] ; 589 if $(abiVersion) { 590 local abiVersionedLib = $(lib:G=).$(abiVersion) ; 591 AddFilesToContainer $(container) : $(directory) : $(lib) 592 : $(abiVersionedLib) ; 593 AddSymlinkToContainer $(container) : $(directory) 594 : $(abiVersionedLib) : $(lib:G=) ; 595 } else { 596 AddFilesToContainer $(container) : $(directory) : $(lib) ; 597 } 598 } 599} 600 601 602rule CreateContainerMakeDirectoriesScript container : script 603{ 604 MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ; 605 Always $(script) ; 606 607 local initScript = [ InitScript $(script) ] ; 608 609 local scriptBody 610 = [ FSameTargetWithPrependedGrist $(script) : script-body ] ; 611 LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ; 612 Depends $(scriptBody) : $(initScript) ; 613 Depends $(script) : $(scriptBody) ; 614 615 # collect the directories to create 616 local dirsToCreate ; 617 local directories 618 = [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] ; 619 local dir ; 620 for dir in $(directories) { 621 if ! [ on $(dir) return $(DONT_CREATE) ] { 622 dirsToCreate += $(dir) ; 623 } 624 } 625 626 # If the image shall only be updated, we don't create directories. 627 if $(dirsToCreate) 628 && ( ! [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] 629 || [ IncludeAllTargetsInContainer $(container) ] 630 || [ on $(container) return 631 $(HAIKU_CONTAINER_ALWAYS_CREATE_DIRECTORIES) ] ) { 632 Depends $(scriptBody) : $(dirsToCreate) ; 633 CreateContainerMakeDirectoriesScript1 $(scriptBody) : $(dirsToCreate) ; 634 635 local serializationDependency = $(scriptBody) ; 636 # Used to create a dependency chain between the dummy targets. 637 # This forces jam to build them one after the other, thus preventing 638 # concurrent writes to the script file when building with multiple 639 # jobs. 640 641 # For directories with attributes, we convert those the specified 642 # resource files to files with attributes and add commands to the script 643 # adding the attributes to the directories. 644 for dir in $(directories) { 645 local resourceFiles = [ on $(dir) return $(ATTRIBUTE_FILES) ] ; 646 if $(resourceFiles) { 647 local dirTokens = [ on $(dir) return $(DIRECTORY_TOKENS) ] ; 648 649 # translate resources file to file with attributes 650 local attributeFile = $(script)-attributes-$(dirTokens:J=-) ; 651 ResAttr $(attributeFile) : $(resourceFiles) ; 652 653 # use a unique dummy target for this file, on which we 654 # can define the TARGET_DIR variable 655 local dummyTarget = $(script)-attributes-dummy-$(dir:G=) ; 656 NotFile $(dummyTarget) ; 657 TARGET_DIR on $(dummyTarget) = $(dir:G=) ; 658 659 Depends $(dummyTarget) : $(initScript) $(attributeFile) 660 $(serializationDependency) ; 661 Depends $(script) : $(dummyTarget) ; 662 serializationDependency = $(dummyTarget) ; 663 664 AppendToContainerMakeDirectoriesScriptAttributes $(dummyTarget) 665 : $(initScript) $(attributeFile) ; 666 } 667 } 668 } 669} 670 671actions piecemeal CreateContainerMakeDirectoriesScript1 672{ 673 echo \$mkdir -p "\"\${tPrefix}$(2:G=)\"" >> $(1) 674} 675 676actions AppendToContainerMakeDirectoriesScriptAttributes 677{ 678 echo \$copyAttrs "\"\${sPrefix}$(2[2])\"" \ 679 "\"\${tPrefix}$(TARGET_DIR)\"" >> $(2[1]) 680} 681 682rule CreateContainerCopyFilesScript container : script 683{ 684 MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ; 685 Always $(script) ; 686 687 local initScript = [ InitScript $(script) ] ; 688 689 local scriptBody 690 = [ FSameTargetWithPrependedGrist $(script) : script-body ] ; 691 LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ; 692 Depends $(scriptBody) : $(initScript) ; 693 Depends $(script) : $(scriptBody) ; 694 695 local serializationDependency = $(scriptBody) ; 696 # Used to create a dependency chain between the dummy targets. 697 # This forces jam to build them one after the other, thus preventing 698 # concurrent writes to the script file when building with multiple 699 # jobs. 700 701 local dir ; 702 for dir in [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] { 703 # filter the targets that shall be renamed; they have to be copied 704 # individually 705 local destTargets = [ on $(dir) return $(TARGETS_TO_INSTALL) ] ; 706 local remainingTargets ; 707 local destTarget ; 708 for destTarget in $(destTargets) { 709 local target = [ on $(destTarget) return $(TARGET) ] ; 710 local name = $(destTarget:G=) ; 711 if $(name) != $(target:BSM) { 712 # use a unique dummy target for this file, on which we 713 # can define the TARGET_DIR variable 714 local dummyTarget = $(script)-dummy-$(dir:G=)-$(target) ; 715 NotFile $(dummyTarget) ; 716 TARGET_DIR on $(dummyTarget) = $(dir:G=) ; 717 718 local nameFunction 719 = [ on $(destTarget) return $(NAME_FUNCTION) ] ; 720 if $(nameFunction) { 721 INSTALL_TARGET_NAME on $(dummyTarget) = "\\${name}" ; 722 } else { 723 INSTALL_TARGET_NAME on $(dummyTarget) = $(name) ; 724 } 725 NAME_FUNCTION on $(dummyTarget) = $(nameFunction) ; 726 727 Depends $(dummyTarget) : $(initScript) $(target) 728 $(serializationDependency) ; 729 Depends $(script) : $(dummyTarget) ; 730 serializationDependency = $(dummyTarget) ; 731 732 AppendToContainerCopyFilesScriptSingleFile $(dummyTarget) 733 : $(initScript) $(target) ; 734 } else { 735 remainingTargets += $(target) ; 736 } 737 } 738 targets = $(remainingTargets) ; 739 740 if $(targets) { 741 # use a unique dummy target for this directory, on which we 742 # can define the TARGET_DIR variable 743 local dummyTarget = $(script)-dummy-$(dir:G=) ; 744 NotFile $(dummyTarget) ; 745 TARGET_DIR on $(dummyTarget) = $(dir:G=) ; 746 747 Depends $(dummyTarget) : $(initScript) $(targets) 748 $(serializationDependency) ; 749 Depends $(script) : $(dummyTarget) ; 750 serializationDependency = $(dummyTarget) ; 751 752 OUTPUT_SCRIPT on $(dummyTarget) = $(initScript) ; 753 AppendToContainerCopyFilesScript $(dummyTarget) : $(targets) ; 754 } 755 756 local symlinks = [ on $(dir) return $(SYMLINKS_TO_INSTALL) ] ; 757 local symlink ; 758 for symlink in $(symlinks) { 759 NotFile $(symlink) ; 760 761 Depends $(script) : $(symlink) ; 762 Depends $(symlink) : $(initScript) $(serializationDependency) ; 763 serializationDependency = $(symlink) ; 764 765 AddSymlinkToContainerCopyFilesScript $(symlink) : $(initScript) ; 766 } 767 768 local targetDirs = [ on $(dir) return $(DIRECTORIES_TO_INSTALL) ] ; 769 local targetDir ; 770 for targetDir in $(targetDirs) { 771 NotFile $(targetDir) ; 772 773 Depends $(script) : $(targetDir) ; 774 Depends $(targetDir) : $(initScript) $(serializationDependency) ; 775 serializationDependency = $(targetDir) ; 776 777 AddDirectoryToContainerCopyFilesScript $(targetDir) 778 : $(initScript) ; 779 } 780 } 781} 782 783 784actions piecemeal AppendToContainerCopyFilesScript bind OUTPUT_SCRIPT 785{ 786 echo \$cp "\"\${sPrefix}$(2)\"" "\"\${tPrefix}$(TARGET_DIR)\"" \ 787 >> $(OUTPUT_SCRIPT) 788} 789 790 791actions AppendToContainerCopyFilesScriptSingleFile 792{ 793 if [ -n "$(NAME_FUNCTION:E)" ]; then 794 echo "name=\`$(NAME_FUNCTION:E) \"$(2[2])\" 2> /dev/null \` || exit 1" \ 795 >> $(2[1]) 796 fi 797 798 echo \$cp "\"\${sPrefix}$(2[2])\"" \ 799 "\"\${tPrefix}$(TARGET_DIR)/$(INSTALL_TARGET_NAME)\"" >> $(2[1]) 800} 801 802 803actions AddSymlinkToContainerCopyFilesScript 804{ 805 echo \$ln -sfn "\"$(SYMLINK_TARGET)\"" "\"\${tPrefix}$(1:G=)\"" >> $(2[1]) 806} 807 808 809actions AddDirectoryToContainerCopyFilesScript bind SOURCE_DIRECTORY 810{ 811 echo \$cp -r $(EXCLUDE_PATTERNS) "\"\${sPrefix}$(SOURCE_DIRECTORY)/.\"" \ 812 "\"\${tPrefix}$(TARGET_DIRECTORY:G=)\"" >> $(2[1]) 813} 814 815 816rule CreateContainerExtractFilesScript container : script 817{ 818 MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ; 819 Always $(script) ; 820 821 local initScript = [ InitScript $(script) ] ; 822 823 local scriptBody 824 = [ FSameTargetWithPrependedGrist $(script) : script-body ] ; 825 LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ; 826 Depends $(scriptBody) : $(initScript) ; 827 Depends $(script) : $(scriptBody) ; 828 829 local serializationDependency = $(scriptBody) ; 830 # Used to create a dependency chain between the dummy targets. 831 # This forces jam to build them one after the other, thus preventing 832 # concurrent writes to the script file when building with multiple 833 # jobs. 834 835 local dir ; 836 for dir in [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] { 837 local archiveFiles = [ on $(dir) return $(ARCHIVE_FILES_TO_INSTALL) ] ; 838 local archiveFile ; 839 for archiveFile in $(archiveFiles) { 840 # use a unique dummy target for this file, on which we 841 # can define the TARGET_DIR variable 842 local dummyTarget = $(script)-dummy-$(dir:G=)-$(archiveFile) ; 843 NotFile $(dummyTarget) ; 844 TARGET_DIR on $(dummyTarget) = $(dir:G=) ; 845 846 local extractedSubDir = [ on $(archiveFile) 847 return $(ARCHIVE_SUBDIR_TO_INSTALL_FROM) ] ; 848 ARCHIVE_SUBDIR_TO_INSTALL_FROM on $(dummyTarget) = 849 $(extractedSubDir:E=.) ; 850 851 Depends $(dummyTarget) : $(initScript) $(archiveFile) 852 $(serializationDependency) ; 853 Depends $(script) : $(dummyTarget) ; 854 serializationDependency = $(dummyTarget) ; 855 856 AddExtractFileToContainerExtractFilesScript $(dummyTarget) 857 : $(initScript) $(archiveFile) ; 858 } 859 } 860} 861 862 863actions AddExtractFileToContainerExtractFilesScript 864{ 865 echo extractFile "\"$(2[2])\"" "\"$(TARGET_DIR)\"" \ 866 "\"$(ARCHIVE_SUBDIR_TO_INSTALL_FROM)\"" >> $(2[1]) 867} 868 869 870rule AddPackagesAndRepositoryVariablesToContainerScript script : container 871{ 872 AddVariableToScript $(script) : downloadDir : $(HAIKU_DOWNLOAD_DIR) ; 873 AddTargetVariableToScript $(script) : <build>package ; 874 AddTargetVariableToScript $(script) : <build>get_package_dependencies 875 : getPackageDependencies ; 876 877 # Add a variable to indicate whether packages dependencies shall be 878 # resolved. We always want to do that in non-update mode, but also in update 879 # mode when all packages are updated. 880 local updateOnly 881 = [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] ; 882 local resolvePackageDependencies ; 883 if ( ! $(updateOnly) || $(HAIKU_UPDATE_ALL_PACKAGES) ) 884 && $(HAIKU_BUILD_TYPE) != bootstrap { 885 resolvePackageDependencies = 1 ; 886 } 887 AddVariableToScript $(script) : resolvePackageDependencies 888 : $(resolvePackageDependencies) ; 889 890 AddVariableToScript $(script) : noDownloads : $(HAIKU_NO_DOWNLOADS) ; 891 892 AddVariableToScript $(script) : updateAllPackages 893 : $(HAIKU_UPDATE_ALL_PACKAGES) ; 894 895 # Add variable "systemPackages" with the packages copied/updated. 896 local systemPackages = [ on $(container) return $(HAIKU_SYSTEM_PACKAGES_IN_IMAGE) ] ; 897 if $(updateOnly) && ! [ IncludeAllTargetsInContainer $(container) ] { 898 systemPackages = [ FilterContainerUpdateTargets $(systemPackages) 899 : [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ] ; 900 } 901 AddTargetVariableToScript $(script) : $(systemPackages) : systemPackages ; 902 903 # Add variable "otherPackages" with the packages copied/updated. 904 local otherPackages = [ on $(container) return $(HAIKU_OTHER_PACKAGES_IN_IMAGE) ] ; 905 if $(updateOnly) && ! [ IncludeAllTargetsInContainer $(container) ] { 906 otherPackages = [ FilterContainerUpdateTargets $(otherPackages) 907 : [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ] ; 908 } 909 AddTargetVariableToScript $(script) : $(otherPackages) : otherPackages ; 910 911 # Generate the repository package lists and add variables for the 912 # repositories. 913 local repository ; 914 local repositoryFiles ; 915 for repository in $(HAIKU_REPOSITORIES) { 916 repositoryFiles 917 += [ on $(repository) return $(HAIKU_REPOSITORY_CACHE_FILE) ] ; 918 } 919 920 AddTargetVariableToScript $(script) : $(repositoryFiles) : repositories ; 921} 922 923 924#pragma mark - Haiku Image rules 925 926rule SetUpdateHaikuImageOnly flag 927{ 928 HAIKU_CONTAINER_UPDATE_ONLY on $(HAIKU_IMAGE_CONTAINER_NAME) = $(flag) ; 929} 930 931rule IsUpdateHaikuImageOnly 932{ 933 on $(HAIKU_IMAGE_CONTAINER_NAME) return $(HAIKU_CONTAINER_UPDATE_ONLY) ; 934} 935 936rule AddDirectoryToHaikuImage directoryTokens : attributeFiles 937{ 938 # AddDirectoryToHaikuImage <directoryTokens> : <attributeFiles> 939 940 return [ AddDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME) 941 : $(directoryTokens) : $(attributeFiles) ] ; 942} 943 944rule AddFilesToHaikuImage directory : targets : destName : flags 945{ 946 # AddFilesToHaikuImage <directory> : <targets> : [ <destName> ] 947 # : [ <flags> ] 948 949 AddFilesToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directory) 950 : $(targets) : $(destName) : $(flags) ; 951} 952 953rule FFilesInHaikuImageDirectory directoryTokens 954{ 955 return [ FFilesInContainerDirectory $(HAIKU_IMAGE_CONTAINER_NAME) 956 : $(directoryTokens) ] ; 957} 958 959rule AddSymlinkToHaikuImage directoryTokens : linkTarget : linkName 960{ 961 # AddSymlinkToHaikuImage <directory> : <link target> [ : <link name> ] ; 962 963 linkTarget = $(linkTarget:J=/) ; 964 965 AddSymlinkToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens) 966 : $(linkTarget) : $(linkName) ; 967} 968 969rule FSymlinksInHaikuImageDirectory directoryTokens 970{ 971 return [ FSymlinksInContainerDirectory $(HAIKU_IMAGE_CONTAINER_NAME) 972 : $(directoryTokens) ] ; 973} 974 975rule CopyDirectoryToHaikuImage directoryTokens : sourceDirectory 976 : targetDirectoryName : excludePatterns : flags 977{ 978 CopyDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens) 979 : $(sourceDirectory) : $(targetDirectoryName) : $(excludePatterns) 980 : $(flags) ; 981} 982 983rule AddSourceDirectoryToHaikuImage dirTokens : flags 984{ 985 # AddSourceDirectoryToHaikuImage <dirTokens> : <flags> ; 986 987 CopyDirectoryToHaikuImage home HaikuSources 988 : [ FDirName $(HAIKU_TOP) $(dirTokens) ] 989 : : : $(flags) ; 990} 991 992rule AddHeaderDirectoryToHaikuImage dirTokens : dirName : flags 993{ 994 # AddHeaderDirectoryToHaikuImage <dirTokens> : [ <dirName> ] 995 # : <flags> ; 996 997 AddHeaderDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(dirTokens) 998 : $(dirName) : $(flags) ; 999} 1000 1001rule AddWifiFirmwareToHaikuImage driver : package : archive : extract 1002{ 1003 # AddWifiFirmwareToHaikuImage <driver> : <package> : <archive> : <extract> 1004 1005 AddWifiFirmwareToHaikuImage $(HAIKU_IMAGE_CONTAINER_NAME) : $(driver) 1006 : $(package) : $(archive) : $(extract) ; 1007} 1008 1009rule ExtractArchiveToHaikuImage dirTokens : archiveFile : flags 1010 : extractedSubDir 1011{ 1012 # ExtractArchiveToHaikuImage <dirTokens> : <archiveFile> : <flags> 1013 # : <extractedSubDir> ; 1014 1015 ExtractArchiveToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(dirTokens) 1016 : $(archiveFile) : $(flags) : $(extractedSubDir) ; 1017} 1018 1019rule AddDriversToHaikuImage relativeDirectoryTokens : targets 1020{ 1021 # AddDriversToHaikuImage <relative directory> : <targets> ; 1022 1023 AddDriversToContainer $(HAIKU_IMAGE_CONTAINER_NAME) 1024 : $(relativeDirectoryTokens) : $(targets) ; 1025} 1026 1027rule AddNewDriversToHaikuImage relativeDirectoryTokens : targets : flags 1028{ 1029 # AddNewDriversToHaikuImage <relative directory> : <targets> : <flags> ; 1030 1031 AddNewDriversToContainer $(HAIKU_IMAGE_CONTAINER_NAME) 1032 : $(relativeDirectoryTokens) : $(targets) : $(flags) ; 1033} 1034 1035rule AddBootModuleSymlinksToHaikuImage targets 1036{ 1037 # AddBootModuleSymlinksToHaikuImage <targets> ; 1038 1039 AddBootModuleSymlinksToContainer $(HAIKU_IMAGE_CONTAINER_NAME) 1040 : $(targets) ; 1041} 1042 1043rule AddPackageFilesToHaikuImage location : packages : flags 1044{ 1045 # AddPackageFilesToHaikuImage <location> : <packages> : <flags> 1046 # 1047 # Supported flags: 1048 # nameFromMetaInfo - determine the target file name from the package meta 1049 # info 1050 1051 packages = [ FFilterByBuildFeatures $(packages) ] ; 1052 1053 if $(location[1]) = system && $(location[2]) = packages && ! $(location[3]) { 1054 HAIKU_SYSTEM_PACKAGES_IN_IMAGE on $(HAIKU_IMAGE_CONTAINER_NAME) 1055 = [ on $(HAIKU_IMAGE_CONTAINER_NAME) return $(HAIKU_SYSTEM_PACKAGES_IN_IMAGE) ] 1056 $(packages) ; 1057 } else { 1058 HAIKU_OTHER_PACKAGES_IN_IMAGE on $(HAIKU_IMAGE_CONTAINER_NAME) 1059 = [ on $(HAIKU_IMAGE_CONTAINER_NAME) return $(HAIKU_OTHER_PACKAGES_IN_IMAGE) ] 1060 $(packages) ; 1061 } 1062 1063 if nameFromMetaInfo in $(flags) { 1064 AddFilesToHaikuImage $(location) : $(packages) 1065 : packageFileName : computeName ; 1066 } else { 1067 AddFilesToHaikuImage $(location) : $(packages) ; 1068 } 1069} 1070 1071rule AddOptionalHaikuImagePackages packages 1072{ 1073 local package ; 1074 for package in $(packages) { 1075 if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] { 1076 HAIKU_OPTIONAL_PACKAGE_ADDED on $(package) = 1 ; 1077 HAIKU_ADDED_OPTIONAL_PACKAGES += $(package) ; 1078 } 1079 local dependencies = [ on $(package) 1080 return $(HAIKU_OPTIONAL_PACKAGE_DEPENDENCIES) ] ; 1081 AddOptionalHaikuImagePackages $(dependencies) ; 1082 } 1083} 1084 1085rule SuppressOptionalHaikuImagePackages packages 1086{ 1087 local package ; 1088 for package in $(packages) { 1089 if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_SUPPRESSED) ] { 1090 HAIKU_OPTIONAL_PACKAGE_SUPPRESSED on $(package) = 1 ; 1091 } 1092 } 1093} 1094 1095rule IsOptionalHaikuImagePackageAdded package 1096{ 1097 if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_EXISTS) ] { 1098 HAIKU_OPTIONAL_PACKAGE_EXISTS on $(package) = 1 ; 1099 HAIKU_EXISTING_OPTIONAL_PACKAGES += $(package) ; 1100 } 1101 1102 if [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] && 1103 ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_SUPPRESSED) ] { 1104 return 1 ; 1105 } 1106 1107 return ; 1108} 1109 1110rule OptionalPackageDependencies package : dependencies 1111{ 1112 HAIKU_OPTIONAL_PACKAGE_DEPENDENCIES on $(package) = $(dependencies) ; 1113 if [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] { 1114 AddOptionalHaikuImagePackages $(dependencies) ; 1115 } 1116} 1117 1118 1119rule AddHaikuImagePackages packages : directory 1120{ 1121 # AddHaikuImagePackages <packages> : <directory> ; 1122 # Adds the given packages <packages> to the image in the given directory. 1123 1124 packages = [ FFilterByBuildFeatures $(packages) ] ; 1125 1126 local package ; 1127 for package in $(packages) { 1128 local resolvedPackage = [ IsPackageAvailable $(package) ] ; 1129 if ! $(resolvedPackage) { 1130 Echo "AddHaikuImagePackages: package" $(package) 1131 "not available!" ; 1132 continue ; 1133 } 1134 1135 if ! [ on $(resolvedPackage) return $(HAIKU_PACKAGE_ADDED) ] { 1136 HAIKU_PACKAGE_ADDED on $(resolvedPackage) = 1 ; 1137 HAIKU_ADDED_PACKAGES += $(resolvedPackage) ; 1138 1139 # download the package file and add it to the image 1140 local file = [ FetchPackage $(package) ] ; 1141 1142 if $(HAIKU_UPDATE_ALL_PACKAGES) { 1143 HAIKU_INCLUDE_IN_IMAGE on $(file) = 1 ; 1144 } 1145 1146 AddPackageFilesToHaikuImage $(directory) : $(file) ; 1147 } 1148 } 1149} 1150 1151rule AddHaikuImageSourcePackages packages 1152{ 1153 # AddHaikuImageSourcePackages <packages> ; 1154 # Adds the given source packages for <packages> to the image. 1155 1156 if $(HAIKU_INCLUDE_SOURCES) = 1 { 1157 AddHaikuImagePackages $(packages)_source : _sources_ ; 1158 } 1159} 1160 1161rule AddHaikuImageSystemPackages packages 1162{ 1163 # AddHaikuImageSystemPackages <packages> ; 1164 # Adds the given packages for <packages> to the image, in the system 1165 # directory, so they will be activated on first boot. 1166 1167 AddHaikuImagePackages $(packages) : system packages ; 1168} 1169 1170rule AddHaikuImageDisabledPackages packages 1171{ 1172 # AddHaikuImageDisabledPackages <packages> ; 1173 # Adds the given packages for <packages> to the image, in the _packages_ 1174 # directory, so they can be later enabled in Installer. 1175 1176 AddHaikuImagePackages $(packages) : _packages_ ; 1177} 1178 1179rule IsHaikuImagePackageAdded package 1180{ 1181 local resolvedPackage = [ IsPackageAvailable $(package) ] ; 1182 if $(resolvedPackage) 1183 && [ on $(resolvedPackage) return $(HAIKU_PACKAGE_ADDED) ] { 1184 return 1 ; 1185 } 1186 1187 return ; 1188} 1189 1190 1191rule BuildHaikuImagePackageList target 1192{ 1193 if ! $(target) { 1194 return ; 1195 } 1196 1197 # get the file names of all added packages 1198 local packageFiles ; 1199 local package ; 1200 for package in $(HAIKU_ADDED_PACKAGES) { 1201 packageFiles += [ FetchPackage $(package) : nameResolved ] ; 1202 } 1203 1204 # extract the versioned package names (without revision) 1205 packageFiles = [ Match "^([^-]*)" : $(packageFiles:B) ] ; 1206 1207 HAIKU_IMAGE_PACKAGES on $(target) = $(packageFiles) ; 1208} 1209 1210 1211actions BuildHaikuImagePackageList 1212{ 1213 echo $(HAIKU_IMAGE_PACKAGES) | xargs -n 1 echo | LC_ALL=C sort -u > $(1) 1214} 1215 1216 1217rule AddEntryToHaikuImageUserGroupFile file : entry 1218{ 1219 local allEntries = [ on $(file) return $(HAIKU_IMAGE_USER_GROUP_ENTRIES) ] ; 1220 1221 if $(allEntries) { 1222 allEntries = $(allEntries)|$(entry) ; 1223 } else { 1224 allEntries = $(entry) ; 1225 1226 Always $(file) ; 1227 MakeLocate $(file) : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ; 1228 BuildHaikuImageUserGroupFile $(file) ; 1229 AddFilesToHaikuImage system settings etc : $(file) ; 1230 } 1231 1232 HAIKU_IMAGE_USER_GROUP_ENTRIES on $(file) = $(allEntries) ; 1233} 1234 1235actions BuildHaikuImageUserGroupFile 1236{ 1237 echo "$(HAIKU_IMAGE_USER_GROUP_ENTRIES)" | tr '|' '\n' > $(1) 1238} 1239 1240rule AddUserToHaikuImage user : uid : gid : home : shell : realName 1241{ 1242 if ! $(user) || ! $(uid) || ! $(gid) || ! $(home) { 1243 Exit "Invalid haiku user specification passed to AddUserToHaikuImage." ; 1244 } 1245 1246 local entry 1247 = $(user):x:$(uid):$(gid):$(realName:E=$(user)):$(home):$(shell:E="") ; 1248 1249 AddEntryToHaikuImageUserGroupFile <haiku-image>passwd : $(entry) ; 1250} 1251 1252rule AddGroupToHaikuImage group : gid : members 1253{ 1254 if ! $(group) || ! $(gid) { 1255 Exit "Invalid haiku group specification passed to" 1256 "AddGroupToHaikuImage." ; 1257 } 1258 1259 local entry = $(group):x:$(gid):$(members:J=,:E) ; 1260 1261 AddEntryToHaikuImageUserGroupFile <haiku-image>group : $(entry) ; 1262} 1263 1264 1265rule AddLibrariesToHaikuImage directory : libs 1266{ 1267 # AddLibraryToHaikuImage <directory> : <libs> 1268 # 1269 # Installs libraries with the appropriate links onto the image. 1270 # 1271 1272 AddLibrariesToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directory) 1273 : $(libs) ; 1274} 1275 1276 1277rule CreateHaikuImageMakeDirectoriesScript script 1278{ 1279 CreateContainerMakeDirectoriesScript $(HAIKU_IMAGE_CONTAINER_NAME) 1280 : $(script) ; 1281} 1282 1283rule CreateHaikuImageCopyFilesScript script 1284{ 1285 CreateContainerCopyFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ; 1286} 1287 1288rule CreateHaikuImageExtractFilesScript script 1289{ 1290 CreateContainerExtractFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) 1291 : $(script) ; 1292} 1293 1294rule BuildHaikuImage haikuImage : scripts : isImage : isVMwareImage 1295{ 1296 # BuildHaikuImage <haiku image> : <scripts> : <is image> : <isVMwareImage> ; 1297 1298 if $(isImage) = 1 || $(isImage) = true { 1299 IS_IMAGE on $(haikuImage) = 1 ; 1300 } else { 1301 IS_IMAGE on $(haikuImage) = "" ; 1302 } 1303 1304 if $(isVMwareImage) = 1 || $(isVMwareImage) = true { 1305 IS_VMWARE_IMAGE on $(haikuImage) = 1 ; 1306 } else { 1307 IS_VMWARE_IMAGE on $(haikuImage) = "" ; 1308 } 1309 1310 local mainScript = build_haiku_image ; 1311 SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ; 1312 1313 Depends $(haikuImage) : $(mainScript) $(scripts) ; 1314 BuildHaikuImage1 $(haikuImage) : $(mainScript) 1315 $(scripts:R=$(HAIKU_ABSOLUTE_OUTPUT_DIR)) ; 1316} 1317 1318actions BuildHaikuImage1 1319{ 1320 export imagePath="$(1)" 1321 export isImage="$(IS_IMAGE)" 1322 export isVMwareImage="$(IS_VMWARE_IMAGE)" 1323 $(2[1]) $(2[2-]) 1324} 1325 1326rule BuildVMWareImage vmwareImage : plainImage : imageSize 1327{ 1328 # BuildVMWareImage <vmware image> : <plain image> : <image size in MB> 1329 1330 IMAGE_SIZE on $(vmwareImage) = $(imageSize) ; 1331 1332 Depends $(vmwareImage) : <build>vmdkheader $(plainImage) ; 1333 BuildVMWareImage1 $(vmwareImage) : <build>vmdkheader $(plainImage) ; 1334} 1335 1336actions BuildVMWareImage1 1337{ 1338 $(RM) $(1) 1339 $(2[1]) -h 64k -i$(IMAGE_SIZE)M $(1) && 1340 cat $(2[2]) >> $(1) 1341} 1342 1343 1344#pragma mark - Network Boot Archive rules 1345 1346rule AddDirectoryToNetBootArchive directoryTokens 1347{ 1348 # AddDirectoryToNetBootArchive <directoryTokens> 1349 1350 return [ AddDirectoryToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) 1351 : $(directoryTokens) ] ; 1352} 1353 1354rule AddFilesToNetBootArchive directory : targets : destName 1355{ 1356 # AddFilesToNetBootArchive <directory> : <targets> [ : dest name ] 1357 1358 AddFilesToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(directory) 1359 : $(targets) : $(destName) ; 1360} 1361 1362rule AddSymlinkToNetBootArchive directoryTokens : linkTarget : linkName 1363{ 1364 # AddSymlinkToNetBootArchive <directory> : <link target> [ : <link name> ] ; 1365 1366 AddSymlinkToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) 1367 : $(directoryTokens) : $(linkTarget) : $(linkName) ; 1368} 1369 1370rule AddDriversToNetBootArchive relativeDirectoryTokens : targets 1371{ 1372 # AddDriversToNetBootArchive <relative directory> : <targets> ; 1373 1374 AddDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) 1375 : $(relativeDirectoryTokens) : $(targets) ; 1376} 1377 1378rule AddNewDriversToNetBootArchive relativeDirectoryTokens : targets 1379{ 1380 # AddNewDriversToNetBootArchive <relative directory> : <targets> ; 1381 1382 AddNewDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) 1383 : $(relativeDirectoryTokens) : $(targets) ; 1384} 1385 1386rule AddDriverRegistrationToNetBootArchive relativeDirectoryTokens : target 1387 : links 1388{ 1389 # AddDriverRegistrationToNetBootArchive <directory> : <link target> 1390 # : <link names> ] ; 1391 1392 AddDriverRegistrationToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) 1393 : $(relativeDirectoryTokens) : $(target) : $(links) ; 1394} 1395 1396rule AddBootModuleSymlinksToNetBootArchive targets 1397{ 1398 # AddBootModuleSymlinksToNetBootArchive <targets> ; 1399 1400 AddBootModuleSymlinksToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) 1401 : $(targets) ; 1402} 1403 1404rule CreateNetBootArchiveMakeDirectoriesScript script 1405{ 1406 CreateContainerMakeDirectoriesScript 1407 $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(script) ; 1408} 1409 1410rule CreateNetBootArchiveCopyFilesScript script 1411{ 1412 CreateContainerCopyFilesScript $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) 1413 : $(script) ; 1414} 1415 1416rule BuildNetBootArchive archive : scripts 1417{ 1418 # BuildNetBootArchive <archive> : <scripts> ; 1419 1420 local mainScript = build_archive ; 1421 SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ; 1422 1423 Depends $(archive) : $(mainScript) $(scripts) ; 1424 BuildNetBootArchive1 $(archive) : $(mainScript) 1425 $(scripts:R=$(HAIKU_ABSOLUTE_OUTPUT_DIR)) ; 1426} 1427 1428actions BuildNetBootArchive1 1429{ 1430 $(2[1]) $(1) $(2[2-]) 1431} 1432 1433 1434#pragma mark - Floppy Boot Archive rules 1435 1436 1437rule AddDirectoryToFloppyBootArchive directoryTokens 1438{ 1439 # AddDirectoryToFloppyBootArchive <directoryTokens> 1440 1441 return [ AddDirectoryToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) 1442 : $(directoryTokens) ] ; 1443} 1444 1445rule AddFilesToFloppyBootArchive directory : targets : destName 1446{ 1447 # AddFilesToFloppyBootArchive <directory> : <targets> [ : dest name ] 1448 1449 AddFilesToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(directory) 1450 : $(targets) : $(destName) ; 1451} 1452 1453rule AddSymlinkToFloppyBootArchive directoryTokens : linkTarget : linkName 1454{ 1455 # AddSymlinkToFloppyBootArchive <directory> : <link target> 1456 # [ : <link name> ] ; 1457 1458 AddSymlinkToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) 1459 : $(directoryTokens) : $(linkTarget) : $(linkName) ; 1460} 1461 1462rule AddDriversToFloppyBootArchive relativeDirectoryTokens : targets 1463{ 1464 # AddDriversToFloppyBootArchive <relative directory> : <targets> ; 1465 1466 AddDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) 1467 : $(relativeDirectoryTokens) : $(targets) ; 1468} 1469 1470rule AddNewDriversToFloppyBootArchive relativeDirectoryTokens : targets 1471{ 1472 # AddNewDriversToFloppyBootArchive <relative directory> : <targets> ; 1473 1474 AddNewDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) 1475 : $(relativeDirectoryTokens) : $(targets) ; 1476} 1477 1478rule AddDriverRegistrationToFloppyBootArchive relativeDirectoryTokens : target 1479 : links 1480{ 1481 # AddDriverRegistrationToFloppyBootArchive <directory> : <link target> 1482 # : <link names> ] ; 1483 1484 AddDriverRegistrationToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) 1485 : $(relativeDirectoryTokens) : $(target) : $(links) ; 1486} 1487 1488rule AddBootModuleSymlinksToFloppyBootArchive targets 1489{ 1490 # AddBootModuleSymlinksToFloppyBootArchive <targets> ; 1491 1492 AddBootModuleSymlinksToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) 1493 : $(targets) ; 1494} 1495 1496rule CreateFloppyBootArchiveMakeDirectoriesScript script 1497{ 1498 CreateContainerMakeDirectoriesScript 1499 $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(script) ; 1500} 1501 1502rule CreateFloppyBootArchiveCopyFilesScript script 1503{ 1504 CreateContainerCopyFilesScript $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) 1505 : $(script) ; 1506} 1507 1508rule BuildFloppyBootArchive archive : scripts 1509{ 1510 # BuildHFloppyBootArchive <archive> : <scripts> ; 1511 1512 local mainScript = build_archive ; 1513 SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ; 1514 1515 Depends $(archive) : $(mainScript) $(scripts) ; 1516 BuildFloppyBootArchive1 $(archive) : $(mainScript) 1517 $(scripts:R=$(HAIKU_ABSOLUTE_OUTPUT_DIR)) ; 1518} 1519 1520actions BuildFloppyBootArchive1 1521{ 1522 $(2[1]) $(1) $(2[2-]) 1523} 1524 1525# warning: that is quite x86 dependant... 1526 1527rule BuildFloppyBootImage image : haikuLoader : archive 1528{ 1529 Depends $(image) : $(haikuLoader) ; 1530 Depends $(image) : $(archive) ; 1531 #MakeLocateDebug $(image) ; 1532 FLOPPY_IMAGE_SIZE on $(image) = $(HAIKU_BOOT_FLOPPY_IMAGE_SIZE) ; 1533 ARCHIVE_IMAGE_OFFSET on $(image) = $(HAIKU_BOOT_ARCHIVE_IMAGE_OFFSET) ; 1534 1535 # FreeBSD's stat command doesn't support -c/--format option 1536 # and use %z specifier for file size 1537 if $(HOST_PLATFORM) = freebsd || $(HOST_PLATFORM) = darwin 1538 || $(HOST_PLATFORM) = openbsd { 1539 STAT_GET_SIZE = "stat -f %z" ; 1540 } else { 1541 STAT_GET_SIZE = "stat -c %s" ; 1542 } 1543 1544 BuildFloppyBootImage1 $(image) : $(haikuLoader) $(archive) ; 1545 if $(HAIKU_KERNEL_PLATFORM) = atari_m68k { 1546 Depends $(image) : <build>fixup_tos_boot_checksum ; 1547 BuildFloppyBootImageFixupM68K $(image) 1548 : <build>fixup_tos_boot_checksum ; 1549 } 1550 if $(HAIKU_KERNEL_PLATFORM) = amiga_m68k { 1551 Depends $(image) : <build>fixup_amiga_boot_checksum ; 1552 BuildFloppyBootImageFixupM68K $(image) 1553 : <build>fixup_amiga_boot_checksum ; 1554 } 1555} 1556 1557actions BuildFloppyBootImage1 1558{ 1559 haiku_loader_size=`$(STAT_GET_SIZE) "$(>[1])"` 1560 drivers_tgz_size=`$(STAT_GET_SIZE) "$(>[2])"` 1561 1562 archive_image_offset=`echo "$(ARCHIVE_IMAGE_OFFSET) * 1024" | bc` 1563 floppy_tgz_size=\ 1564 `echo "($(FLOPPY_IMAGE_SIZE) - $(ARCHIVE_IMAGE_OFFSET)) * 1024" | bc` 1565 if [ $haiku_loader_size -gt $archive_image_offset ] ; then 1566 echo "Error: $(>[1]) is too big ($haiku_loader_size) to fit " 1567 echo " before the boot archive starting at $archive_image_offset!" 1568 exit 1 1569 fi 1570 if [ $drivers_tgz_size -gt $floppy_tgz_size ] ; then 1571 echo "Error: $(>[2]) is too big ($drivers_tgz_size) to fit " 1572 echo " in the boot floppy ($floppy_tgz_size)!" 1573 exit 1 1574 fi 1575 $(RM) $(<) 1576 # make an empty image 1577 dd if=/dev/zero of=$(<) bs=1k count=$(FLOPPY_IMAGE_SIZE) 1578 # add haiku_loader 1579 dd if=$(>[1]) of=$(<) conv=notrunc 1580 # add the boot drivers tgz archive 1581 dd if=$(>[2]) of=$(<) bs=$(ARCHIVE_IMAGE_OFFSET)k seek=1 conv=notrunc 1582} 1583 1584actions BuildFloppyBootImageFixupM68K 1585{ 1586 # fixup the boot sector checksum 1587 $(>[1]) $(<) 1588} 1589 1590#pragma mark - CD Boot Image rules 1591 1592rule BuildCDBootImage image : bootfloppy : bootefi : extrafiles 1593{ 1594 Depends $(image) : $(bootfloppy) ; 1595 Depends $(image) : $(bootefi) ; 1596 Depends $(image) : $(extrafiles) ; 1597 BOOTIMG on $(image) = $(bootfloppy) ; 1598 1599 if $(HAIKU_NIGHTLY_BUILD) = 1 { 1600 VOLID on $(image) = haiku-nightly-$(TARGET_ARCH) ; 1601 } else { 1602 VOLID on $(image) = haiku-$(HAIKU_VERSION)-$(TARGET_ARCH) ; 1603 } 1604 1605 if $(HAIKU_ANYBOOT_LEGACY) = 1 { 1606 BuildCDBootImageMBR $(image) : $(bootfloppy) $(extrafiles) ; 1607 } else { 1608 BOOTEFI on $(image) = $(bootefi) ; 1609 BuildCDBootImageEFI $(image) : $(bootfloppy) $(bootefi) $(extrafiles) ; 1610 } 1611} 1612 1613actions BuildCDBootImageMBR 1614{ 1615 $(RM) $(<) 1616 xorriso -as mkisofs -b $(BOOTIMG) -r -J -V $(VOLID) -o $(<) $(>[1]) $(>[2-]) 1617} 1618 1619actions BuildCDBootImageEFI 1620{ 1621 $(RM) $(<) 1622 xorriso -as mkisofs -b $(BOOTIMG) -eltorito-alt-boot -no-emul-boot -e $(BOOTEFI) \ 1623 -r -J -V $(VOLID) -o $(<) $(>[1]) $(>[2]) $(>[3-]) 1624} 1625 1626 1627#pragma mark - CD Boot PPC Image rules 1628 1629rule BuildCDBootPPCImage image : hfsmaps : elfloader : coffloader : chrpscript 1630 : extrafiles 1631{ 1632 Depends $(image) : $(elfloader) ; 1633 Depends $(image) : $(coffloader) ; 1634 Depends $(image) : $(chrpscript) ; 1635 Depends $(image) : $(extrafiles) ; 1636 Depends $(image) : $(hfsmaps) ; 1637 MAPS on $(image) = $(hfsmaps) ; 1638 1639 if $(HAIKU_NIGHTLY_BUILD) = 1 { 1640 VOLID on $(image) = haiku-nightly-$(TARGET_ARCH) ; 1641 } else { 1642 VOLID on $(image) = haiku-$(HAIKU_VERSION)-$(TARGET_ARCH) ; 1643 } 1644 1645 BuildCDBootPPCImage1 $(image) : $(elfloader) $(coffloader) $(chrpscript) 1646 $(extrafiles) ; 1647} 1648 1649actions BuildCDBootPPCImage1 bind MAPS 1650{ 1651 $(RM) $(<) 1652 1653 mkdir -p $(HAIKU_OUTPUT_DIR)/cd/ppc 1654 mkdir -p $(HAIKU_OUTPUT_DIR)/cd/boot 1655 # CHRP Boot script 1656 cp $(>[3]) $(HAIKU_OUTPUT_DIR)/cd/ppc/bootinfo.txt 1657 cp $(>[3]) $(HAIKU_OUTPUT_DIR)/cd/boot/boot.chrp 1658 # Haiku Bootloaders 1659 cp $(>[2]) $(HAIKU_OUTPUT_DIR)/cd/boot/haikuloader.xcf 1660 cp $(>[1]) $(HAIKU_OUTPUT_DIR)/cd/boot/haikuloader.elf 1661 # Extras (readme files, etc) 1662 cp $(>[4]) $(HAIKU_OUTPUT_DIR)/cd/ 1663 1664 # Xorriso doesn't have map and some other required tools 1665 # to make bootable PowerPC images 1666 genisoimage -v -hfs -map $(MAPS) \ 1667 -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/boot -part -no-desktop \ 1668 -hfs-parms MAX_XTCSIZE=2656248 -hfs-volid Haiku \ 1669 --prep-boot boot/haikuloader.elf \ 1670 --chrp-boot -r -J -o $(<) $(HAIKU_OUTPUT_DIR)/cd 1671 1672 $(RM) -r $(HAIKU_OUTPUT_DIR)/cd 1673} 1674 1675#pragma mark - EFI System Partition rules 1676 1677rule BuildEfiSystemPartition image : efiLoader 1678{ 1679 local macVolumeIcon = [ FDirName 1680 $(HAIKU_TOP) data artwork VolumeIcon.icns ] ; 1681 local fatshell = <build>fat_shell ; 1682 1683 Depends $(image) : $(efiLoader) ; 1684 Depends $(image) : $(macVolumeIcon) ; 1685 Depends $(image) : $(fatshell) ; 1686 1687 switch $(TARGET_ARCH) { 1688 case x86 : 1689 EFINAME on $(image) = "BOOTIA32.EFI" ; 1690 case x86_64 : 1691 EFINAME on $(image) = "BOOTX64.EFI" ; 1692 case arm : 1693 EFINAME on $(image) = "BOOTARM.EFI" ; 1694 case arm64 : 1695 EFINAME on $(image) = "BOOTAA64.EFI" ; 1696 case riscv32 : 1697 EFINAME on $(image) = "BOOTRISCV32.EFI" ; 1698 case riscv64 : 1699 EFINAME on $(image) = "BOOTRISCV64.EFI" ; 1700 case * : 1701 Exit "Error: Unknown EFI architecture!" ; 1702 } 1703 1704 BuildEfiSystemPartition1 $(image) : $(fatshell) $(macVolumeIcon) $(efiLoader) ; 1705} 1706 1707# Usage: 1708# out : fatshell volumeIcon loader 1709actions BuildEfiSystemPartition1 1710{ 1711 $(RM) $(<) 1712 1713 export $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) 1714 1715 dd if=/dev/zero of=$(<) bs=1024 count=2880 1716 1717 FATFS="$(2[1])" 1718 EFIICON="$(2[2])" 1719 LOADER="$(2[3])" 1720 1721 ${FATFS} --initialize "$(<)" 'Haiku ESP' 1722 echo "mkdir myfs/EFI" | ${FATFS} $(<) 1723 echo "mkdir myfs/EFI/BOOT" | ${FATFS} $(<) 1724 echo "cp :${LOADER} myfs/EFI/BOOT/$(EFINAME)" | ${FATFS} $(<) 1725 echo "cp :${EFIICON} myfs/.VolumeIcon.icns" | ${FATFS} $(<) 1726} 1727