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