rule FSameTargetWithPrependedGrist { # SameTargetWithPrependedGrist <target> : <grist to prepend> ; # local target = $(1) ; local gristToPrepend = $(2) ; local grist = $(target:G) ; if $(grist) { grist = $(gristToPrepend)!$(grist) ; } else { grist = $(gristToPrepend) ; } return $(target:G=$(grist)) ; } rule InitScript { # Note: The script must have been LOCATEd before. local script = $(1) ; local initScript = [ FSameTargetWithPrependedGrist $(script) : init-script ] ; if ! [ on $(script) return $(__is_initialized) ] { __is_initialized on $(script) = true ; MakeLocate $(initScript) : [ on $(script) return $(LOCATE) ] ; Always $(initScript) ; Depends $(script) : $(initScript) ; InitScript1 $(initScript) ; } return $(initScript) ; } actions InitScript1 { $(RM) $(1) touch $(1) } rule AddVariableToScript script : variable : value { # AddVariableToScript <script> : <variable> : <value> ; # interpret an empty variable value as empty string if ! $(value) { value = "" ; } InitScript $(script) ; VARIABLE_DEFS on $(script) += "echo $(variable)=\\\"$(value[1])\\\" >> " ; # if the value is an array, add the other array elements value = $(value[2-]) ; while $(value) { VARIABLE_DEFS on $(script) += "echo $(variable)=\\\" \\\$$(variable) $(value[1])\\\" >> " ; value = $(value[2-]) ; } AddVariableToScript1 $(script) ; } actions together AddVariableToScript1 { $(VARIABLE_DEFS)$(1); } rule AddTargetVariableToScript script : targets : variable { # AddTargetVariableToScript <script> : <targets> [ : <variable> ] ; # # If <targets> contains multiple targets, their paths must not contain # whitespaces or other characters that need to be escaped in the shell. # variable ?= $(3:E=$(targets[1]:BS)) ; local initScript = [ InitScript $(script) ] ; serialization = [ on $(script) return $(HAIKU_SERIALIZATION) ] ; local variableTarget = [ NewUniqueTarget ] ; NotFile $(variableTarget) ; Depends $(variableTarget) : $(initScript) $(targets) $(serialization) ; Depends $(script) : $(variableTarget) ; HAIKU_SERIALIZATION on $(script) = $(variableTarget) ; HAIKU_VARIABLE_NAME on $(variableTarget) = $(variable) ; AddTargetVariableToScript1 $(variableTarget) : $(initScript) $(targets) ; } actions AddTargetVariableToScript1 { script="$(2[1])" echo "$(HAIKU_VARIABLE_NAME)=" >> "$script" firstSeen= for value in "$(2[2-])" ; do if [ -z "$firstSeen" ]; then echo "$(HAIKU_VARIABLE_NAME)=\"$value\"" >> "$script" firstSeen=1 else echo "$(HAIKU_VARIABLE_NAME)=\"\$$(HAIKU_VARIABLE_NAME) $value\"" \ >> "$script" fi done } #pragma mark - rule AddDirectoryToContainer container : directoryTokens : attributeFiles { # AddDirectoryToContainer <container> : <directoryTokens> : <attributeFiles> local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ; local directory = [ FDirName $(directoryTokens) ] ; directory = $(directory:G=$(containerGrist)) ; if ! [ on $(directory) return $(__is_on_image) ] { HAIKU_INSTALL_DIRECTORIES on $(container) += $(directory) ; __is_on_image on $(directory) = true ; DIRECTORY_TOKENS on $(directory) = $(directoryTokens) ; NotFile $(directory) ; # mark the parent dir as not to be created local parent = [ FReverse $(directoryTokens) ] ; parent = [ FReverse $(parent[2-]) ] ; if $(parent) { parent = [ FDirName $(parent) ] ; parent = $(parent:G=$(containerGrist)) ; DONT_CREATE on $(parent) = true ; } } if $(attributeFiles) { SEARCH on $(attributeFiles) += [ FDirName $(HAIKU_TOP) src data directory_attrs ] ; ATTRIBUTE_FILES on $(directory) += $(attributeFiles) ; } return $(directory) ; } rule FilterContainerUpdateTargets targets : filterVariable { # FilterContainerUpdateTargets targets : filterVariable local filteredTargets ; local target ; for target in $(targets) { if [ on $(target) return $($(filterVariable)) ] { filteredTargets += $(target) ; } } return $(filteredTargets) ; } rule IncludeAllTargetsInContainer container { local filterVar = [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ; if $(filterVar) { return $($(filterVar)) ; } return ; } rule PropagateContainerUpdateTargetFlags toTarget : fromTarget { if [ on $(fromTarget) return $(HAIKU_INCLUDE_IN_IMAGE) ] { HAIKU_INCLUDE_IN_IMAGE on $(toTarget) = 1 ; } if [ on $(fromTarget) return $(HAIKU_INCLUDE_IN_PACKAGES) ] { HAIKU_INCLUDE_IN_PACKAGES on $(toTarget) = 1 ; } } rule AddFilesToContainer container : directoryTokens : targets : destName : flags { # AddFilesToContainer <container> : <directoryTokens> : <targets> # : [ <destName> ] : [ <flags> ] # # Supported flags: # computeName - <destName> is the name of a shell command/function that # computes the destination name. # alwaysUpdate - When only updating the container, always also update the # given targets. local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ; local systemDirTokens = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; targets = [ FFilterByBuildFeatures $(targets) ] ; # If the image shall only be updated, we filter out all targets not marked # accordingly. if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] && ! [ IncludeAllTargetsInContainer $(container) ] && ! alwaysUpdate in $(flags) { local filterVar = [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ; if $(filterVar) { targets = [ FilterContainerUpdateTargets $(targets) : $(filterVar) ] ; # If there are any targets, mark the container as to be included in # an update, too, if it has set the update inheritance variable. # This makes updating a target that lives in a package on an image # work. if $(targets) { local updateVariable = [ on $(container) return $(HAIKU_CONTAINER_INHERIT_UPDATE_VARIABLE) ] ; if $(updateVariable) { $(updateVariable) on $(container) = 1 ; } } } } if ! $(targets) { return ; } local directory = [ AddDirectoryToContainer $(container) : $(directoryTokens) ] ; # We create a unique dummy target per target to install. local installTargetsVar = [ on $(container) return $(HAIKU_INSTALL_TARGETS_VAR) ] ; local stripExecutables = [ on $(container) return $(HAIKU_CONTAINER_STRIP_EXECUTABLES) ] ; local target ; for target in $(targets) { local name ; local nameFunction ; if $(destName) { if computeName in $(flags) { nameFunction = $(destName) ; name = $(destName)/$(target:BSM) ; } else { name = $(destName) ; } } else { name = $(target:BSM) ; } local installTarget = $(target) ; if $(stripExecutables) && [ on $(target) return $(HAIKU_TARGET_IS_EXECUTABLE) ] { installTarget = [ StripFiles $(target) ] ; } local destTarget = $(name:G=$(containerGrist)__$(directory:G=)) ; TARGET on $(destTarget) = $(installTarget) ; INSTALL_DIR on $(destTarget) = $(directory) ; NAME_FUNCTION on $(destTarget) = $(nameFunction) ; $(installTargetsVar) on $(target) += $(destTarget) ; TARGETS_TO_INSTALL on $(directory) += $(destTarget) ; # If the target and its static libraries are associated with catalog # files, add those, too. local catalogTargets = $(target) + [ on $(target) return $(NEEDLIBS) ] ; for catalogTarget in $(catalogTargets) { local catalogs = [ on $(catalogTarget) return $(HAIKU_CATALOG_FILES) ] ; if $(catalogs) { local signature = [ on $(catalogTarget) return $(HAIKU_CATALOG_SIGNATURE) ] ; AddFilesToContainer $(container) : $(systemDirTokens) data locale catalogs $(signature) : $(catalogs) ; } } # If the target is associated with MIME DB entries, add those, too. local mimeDBEntries = [ on $(target) return $(HAIKU_MIME_DB_ENTRIES) ] ; if $(mimeDBEntries) { # Make sure we add the entries only once by tracking the containers # we have already added it to. local containers = [ on $(mimeDBEntries) return $(HAIKU_MIME_DB_ENTRIES_IN_CONTAINERS) ] ; if ! $(container) in $(containers) { HAIKU_MIME_DB_ENTRIES_IN_CONTAINERS on $(mimeDBEntries) = $(containers) $(container) ; CopyDirectoryToContainer $(container) : data : $(mimeDBEntries) : mime_db : : alwaysUpdate isTarget ; } } } } rule FFilesInContainerDirectory container : directoryTokens { local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ; local directory = [ FDirName $(directoryTokens) ] ; directory = $(directory:G=$(containerGrist)) ; if [ on $(directory) return $(__is_on_image) ] { on $(directory) return $(TARGETS_TO_INSTALL) ; } return ; } rule AddSymlinkToContainer container : directoryTokens : linkTarget : linkName { # AddSymlinkToContainer <container> : <directory> : <link target> # [ : <link name> ] ; # # If the image shall only be updated, we don't add any symlinks. if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] && ! [ IncludeAllTargetsInContainer $(container) ] { return ; } local directory = [ AddDirectoryToContainer $(container) : $(directoryTokens) ] ; if ! $(linkName) { local path = [ FReverse [ FSplitPath $(linkTarget) ] ] ; linkName = $(path[1]) ; } local link = $(directory)/$(linkName) ; SYMLINK_TARGET on $(link) = $(linkTarget) ; SYMLINKS_TO_INSTALL on $(directory) += $(link) ; } rule FSymlinksInContainerDirectory container : directoryTokens { local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ; local directory = [ FDirName $(directoryTokens) ] ; directory = $(directory:G=$(containerGrist)) ; if [ on $(directory) return $(__is_on_image) ] { on $(directory) return $(SYMLINKS_TO_INSTALL) ; } return ; } rule CopyDirectoryToContainer container : directoryTokens : sourceDirectory : targetDirectoryName : excludePatterns : flags { # CopyDirectoryToContainer <container> : <directoryTokens> # : <sourceDirectory> : <targetDirectoryName> : <excludePatterns> # [ : <flags> ] ; # # Supported flags: alwaysUpdate, isTarget # isTarget: <sourceDirectory> is a target, not a path # If the image shall only be updated, we don't copy any directories if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] && ! [ IncludeAllTargetsInContainer $(container) ] && ! alwaysUpdate in $(flags) { return ; } if ! $(targetDirectoryName) { targetDirectoryName = $(sourceDirectory[1]:BSM) ; } # If sourceDirectory is a path, not a target, make it a target, so we can # treat both the same way. if ! isTarget in $(flags) { sourceDirectory = $(sourceDirectory:G=copy-directory-to-container) ; SEARCH on $(sourceDirectory) = ; TARGET on $(sourceDirectory) = ; } local directory = [ AddDirectoryToContainer $(container) : $(directoryTokens) $(targetDirectoryName) ] ; local targetDir = $(directory)/-/$(sourceDirectory) ; Depends $(targetDir) : $(sourceDirectory) ; EXCLUDE_PATTERNS on $(targetDir) = $(excludePatterns) ; SOURCE_DIRECTORY on $(targetDir) = $(sourceDirectory) ; TARGET_DIRECTORY on $(targetDir) = $(directory) ; DIRECTORIES_TO_INSTALL on $(directory) += $(targetDir) ; } rule AddHeaderDirectoryToContainer container : dirTokens : dirName : flags { # AddHeaderDirectoryToContainer <container> : <dirTokens> : [ <dirName> ] # [ : <flags> ] ; # # Supported flags: alwaysUpdate local systemDirTokens = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; CopyDirectoryToContainer $(container) : $(systemDirTokens) develop headers : [ FDirName $(HAIKU_TOP) headers $(dirTokens) ] : $(dirName) : -x *~ : $(flags) ; } rule AddWifiFirmwareToContainer container : driver : package : archive : extract { # AddWifiFirmwareToContainer <container> : <driver> : <package> : <archive> # : <extract> # complete location to wifi firmware archive local firmwareArchive = [ FDirName $(HAIKU_TOP) data system data firmware $(driver) $(archive) ] ; local systemDirTokens = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; local dirTokens = $(systemDirTokens) data firmware $(driver) ; if $(extract) = true || $(extract) = 1 { ExtractArchiveToContainer $(container) : $(dirTokens) : $(firmwareArchive) : : $(package) ; } else { AddFilesToContainer $(container) : $(dirTokens) : $(firmwareArchive) ; } } rule ExtractArchiveToContainer container : directoryTokens : archiveFile : flags : extractedSubDir { # ExtractArchiveToContainer <container> : <directory> : <archiveFile> # : [ <flags> ] : <extractedSubDir> ; # # Supported flags: alwaysUpdate # If the container shall only be updated, we extract only, if explicitely # requested. if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] && ! alwaysUpdate in $(flags) { return ; } local directory = [ AddDirectoryToContainer $(container) : $(directoryTokens) ] ; ARCHIVE_FILES_TO_INSTALL on $(directory) += $(archiveFile) ; ARCHIVE_SUBDIR_TO_INSTALL_FROM on $(archiveFile) = $(extractedSubDir) ; } rule AddDriversToContainer container : relativeDirectoryTokens : targets { # AddDriversToContainer <container> : <relative directory> : <targets> ; # local systemDirTokens = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; local directoryTokens = $(systemDirTokens) add-ons kernel drivers dev $(relativeDirectoryTokens) ; targets = [ FFilterByBuildFeatures $(targets) ] ; # A driver can be in multiple categories. Avoid adding it to the bin/ # directory more than once. local binTargets ; local target ; for target in $(targets) { local containers = [ on $(target) return $(HAIKU_DRIVER_IN_CONTAINERS) ] ; if ! $(container) in $(containers) { HAIKU_DRIVER_IN_CONTAINERS on $(target) = $(containers) $(container) ; binTargets += $(target) ; } } AddFilesToContainer $(container) : $(systemDirTokens) add-ons kernel drivers bin : $(binTargets) ; # If the image shall only be updated, we don't add any symlinks. if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] && ! [ IncludeAllTargetsInContainer $(container) ] { return ; } # get the relative symlink path prefix local linkPrefix = ; local i ; for i in $(relativeDirectoryTokens) { linkPrefix += .. ; } linkPrefix += .. bin ; # add the symlinks local name ; for name in $(targets:BSM) { AddSymlinkToContainer $(container) : $(directoryTokens) : [ FDirName $(linkPrefix) $(name) ] : $(name) ; } } rule AddNewDriversToContainer container : relativeDirectoryTokens : targets : flags { # AddNewDriversToContainer <container> : <directory> : <targets> : <flags> ; # # Supported flags: # alwaysUpdate - When only updating the container, always also update the # given targets. local systemDirTokens = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; local directoryTokens = $(systemDirTokens) add-ons kernel drivers $(relativeDirectoryTokens) ; targets = [ FFilterByBuildFeatures $(targets) ] ; AddFilesToContainer $(container) : $(directoryTokens) : $(targets) : : $(flags) ; } rule AddBootModuleSymlinksToContainer container : targets { # AddBootModuleSymlinksToContainer <container> : <targets> ; # # If the container shall only be updated, we don't add any symlinks. if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] && ! [ IncludeAllTargetsInContainer $(container) ] { return ; } local systemDirTokens = [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ; targets = [ FFilterByBuildFeatures $(targets) ] ; # add the symlinks local installTargetsVar = [ on $(container) return $(HAIKU_INSTALL_TARGETS_VAR) ] ; local target ; for target in $(targets) { # Symlink to the first place where the target has been installed. local destTarget = [ on $(target) return $($(installTargetsVar)[1]) ] ; local installDir = [ on $(destTarget) return $(INSTALL_DIR) ] ; if ! $(installDir) { Echo "ERROR: AddBootModuleSymlinksToContainer: Can't create a " "symlink to target" \"$(target)"\"." ; Exit "ERROR: Add*ToContainer has not been invoked for it yet." ; } # chop off the system dir prefix from installDir installDir = [ on $(installDir) return $(DIRECTORY_TOKENS) ] ; local dummy ; for dummy in $(systemDirTokens) { installDir = $(installDir[2-]) ; } local name = $(target:BSM) ; local linkTarget = [ FDirName ../../.. $(installDir) $(name) ] ; AddSymlinkToContainer $(container) : $(systemDirTokens) add-ons kernel boot : $(linkTarget) : $(name) ; } } rule AddLibrariesToContainer container : directory : libs { # AddLibrariesToContainer <container> : <directory> : <libs> # # Installs libraries with the appropriate links into the container. # local lib ; for lib in $(libs) { local abiVersion = [ on $(lib) return $(HAIKU_LIB_ABI_VERSION) ] ; if $(abiVersion) { local abiVersionedLib = $(lib:G=).$(abiVersion) ; AddFilesToContainer $(container) : $(directory) : $(lib) : $(abiVersionedLib) ; AddSymlinkToContainer $(container) : $(directory) : $(abiVersionedLib) : $(lib:G=) ; } else { AddFilesToContainer $(container) : $(directory) : $(lib) ; } } } rule CreateContainerMakeDirectoriesScript container : script { MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ; Always $(script) ; local initScript = [ InitScript $(script) ] ; local scriptBody = [ FSameTargetWithPrependedGrist $(script) : script-body ] ; LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ; Depends $(scriptBody) : $(initScript) ; Depends $(script) : $(scriptBody) ; # collect the directories to create local dirsToCreate ; local directories = [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] ; local dir ; for dir in $(directories) { if ! [ on $(dir) return $(DONT_CREATE) ] { dirsToCreate += $(dir) ; } } # If the image shall only be updated, we don't create directories. if $(dirsToCreate) && ( ! [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] || [ IncludeAllTargetsInContainer $(container) ] || [ on $(container) return $(HAIKU_CONTAINER_ALWAYS_CREATE_DIRECTORIES) ] ) { Depends $(scriptBody) : $(dirsToCreate) ; CreateContainerMakeDirectoriesScript1 $(scriptBody) : $(dirsToCreate) ; local serializationDependency = $(scriptBody) ; # Used to create a dependency chain between the dummy targets. # This forces jam to build them one after the other, thus preventing # concurrent writes to the script file when building with multiple # jobs. # For directories with attributes, we convert those the specified # resource files to files with attributes and add commands to the script # adding the attributes to the directories. for dir in $(directories) { local resourceFiles = [ on $(dir) return $(ATTRIBUTE_FILES) ] ; if $(resourceFiles) { local dirTokens = [ on $(dir) return $(DIRECTORY_TOKENS) ] ; # translate resources file to file with attributes local attributeFile = $(script)-attributes-$(dirTokens:J=-) ; ResAttr $(attributeFile) : $(resourceFiles) ; # use a unique dummy target for this file, on which we # can define the TARGET_DIR variable local dummyTarget = $(script)-attributes-dummy-$(dir:G=) ; NotFile $(dummyTarget) ; TARGET_DIR on $(dummyTarget) = $(dir:G=) ; Depends $(dummyTarget) : $(initScript) $(attributeFile) $(serializationDependency) ; Depends $(script) : $(dummyTarget) ; serializationDependency = $(dummyTarget) ; AppendToContainerMakeDirectoriesScriptAttributes $(dummyTarget) : $(initScript) $(attributeFile) ; } } } } actions piecemeal CreateContainerMakeDirectoriesScript1 { echo \$mkdir -p "\"\${tPrefix}$(2:G=)\"" >> $(1) } actions AppendToContainerMakeDirectoriesScriptAttributes { echo \$copyAttrs "\"\${sPrefix}$(2[2])\"" \ "\"\${tPrefix}$(TARGET_DIR)\"" >> $(2[1]) } rule CreateContainerCopyFilesScript container : script { MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ; Always $(script) ; local initScript = [ InitScript $(script) ] ; local scriptBody = [ FSameTargetWithPrependedGrist $(script) : script-body ] ; LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ; Depends $(scriptBody) : $(initScript) ; Depends $(script) : $(scriptBody) ; local serializationDependency = $(scriptBody) ; # Used to create a dependency chain between the dummy targets. # This forces jam to build them one after the other, thus preventing # concurrent writes to the script file when building with multiple # jobs. local dir ; for dir in [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] { # filter the targets that shall be renamed; they have to be copied # individually local destTargets = [ on $(dir) return $(TARGETS_TO_INSTALL) ] ; local remainingTargets ; local destTarget ; for destTarget in $(destTargets) { local target = [ on $(destTarget) return $(TARGET) ] ; local name = $(destTarget:G=) ; if $(name) != $(target:BSM) { # use a unique dummy target for this file, on which we # can define the TARGET_DIR variable local dummyTarget = $(script)-dummy-$(dir:G=)-$(target) ; NotFile $(dummyTarget) ; TARGET_DIR on $(dummyTarget) = $(dir:G=) ; local nameFunction = [ on $(destTarget) return $(NAME_FUNCTION) ] ; if $(nameFunction) { INSTALL_TARGET_NAME on $(dummyTarget) = "\\${name}" ; } else { INSTALL_TARGET_NAME on $(dummyTarget) = $(name) ; } NAME_FUNCTION on $(dummyTarget) = $(nameFunction) ; Depends $(dummyTarget) : $(initScript) $(target) $(serializationDependency) ; Depends $(script) : $(dummyTarget) ; serializationDependency = $(dummyTarget) ; AppendToContainerCopyFilesScriptSingleFile $(dummyTarget) : $(initScript) $(target) ; } else { remainingTargets += $(target) ; } } targets = $(remainingTargets) ; if $(targets) { # use a unique dummy target for this directory, on which we # can define the TARGET_DIR variable local dummyTarget = $(script)-dummy-$(dir:G=) ; NotFile $(dummyTarget) ; TARGET_DIR on $(dummyTarget) = $(dir:G=) ; Depends $(dummyTarget) : $(initScript) $(targets) $(serializationDependency) ; Depends $(script) : $(dummyTarget) ; serializationDependency = $(dummyTarget) ; OUTPUT_SCRIPT on $(dummyTarget) = $(initScript) ; AppendToContainerCopyFilesScript $(dummyTarget) : $(targets) ; } local symlinks = [ on $(dir) return $(SYMLINKS_TO_INSTALL) ] ; local symlink ; for symlink in $(symlinks) { NotFile $(symlink) ; Depends $(script) : $(symlink) ; Depends $(symlink) : $(initScript) $(serializationDependency) ; serializationDependency = $(symlink) ; AddSymlinkToContainerCopyFilesScript $(symlink) : $(initScript) ; } local targetDirs = [ on $(dir) return $(DIRECTORIES_TO_INSTALL) ] ; local targetDir ; for targetDir in $(targetDirs) { NotFile $(targetDir) ; Depends $(script) : $(targetDir) ; Depends $(targetDir) : $(initScript) $(serializationDependency) ; serializationDependency = $(targetDir) ; AddDirectoryToContainerCopyFilesScript $(targetDir) : $(initScript) ; } } } actions piecemeal AppendToContainerCopyFilesScript bind OUTPUT_SCRIPT { echo \$cp "\"\${sPrefix}$(2)\"" "\"\${tPrefix}$(TARGET_DIR)\"" \ >> $(OUTPUT_SCRIPT) } actions AppendToContainerCopyFilesScriptSingleFile { if [ -n "$(NAME_FUNCTION:E)" ]; then echo "name=\`$(NAME_FUNCTION:E) \"$(2[2])\" 2> /dev/null \` || exit 1" \ >> $(2[1]) fi echo \$cp "\"\${sPrefix}$(2[2])\"" \ "\"\${tPrefix}$(TARGET_DIR)/$(INSTALL_TARGET_NAME)\"" >> $(2[1]) } actions AddSymlinkToContainerCopyFilesScript { echo \$ln -sfn "\"$(SYMLINK_TARGET)\"" "\"\${tPrefix}$(1:G=)\"" >> $(2[1]) } actions AddDirectoryToContainerCopyFilesScript bind SOURCE_DIRECTORY { echo \$cp -r $(EXCLUDE_PATTERNS) "\"\${sPrefix}$(SOURCE_DIRECTORY)/.\"" \ "\"\${tPrefix}$(TARGET_DIRECTORY:G=)\"" >> $(2[1]) } rule CreateContainerExtractFilesScript container : script { MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ; Always $(script) ; local initScript = [ InitScript $(script) ] ; local scriptBody = [ FSameTargetWithPrependedGrist $(script) : script-body ] ; LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ; Depends $(scriptBody) : $(initScript) ; Depends $(script) : $(scriptBody) ; local serializationDependency = $(scriptBody) ; # Used to create a dependency chain between the dummy targets. # This forces jam to build them one after the other, thus preventing # concurrent writes to the script file when building with multiple # jobs. local dir ; for dir in [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] { local archiveFiles = [ on $(dir) return $(ARCHIVE_FILES_TO_INSTALL) ] ; local archiveFile ; for archiveFile in $(archiveFiles) { # use a unique dummy target for this file, on which we # can define the TARGET_DIR variable local dummyTarget = $(script)-dummy-$(dir:G=)-$(archiveFile) ; NotFile $(dummyTarget) ; TARGET_DIR on $(dummyTarget) = $(dir:G=) ; local extractedSubDir = [ on $(archiveFile) return $(ARCHIVE_SUBDIR_TO_INSTALL_FROM) ] ; ARCHIVE_SUBDIR_TO_INSTALL_FROM on $(dummyTarget) = $(extractedSubDir:E=.) ; Depends $(dummyTarget) : $(initScript) $(archiveFile) $(serializationDependency) ; Depends $(script) : $(dummyTarget) ; serializationDependency = $(dummyTarget) ; AddExtractFileToContainerExtractFilesScript $(dummyTarget) : $(initScript) $(archiveFile) ; } } } actions AddExtractFileToContainerExtractFilesScript { echo extractFile "\"$(2[2])\"" "\"$(TARGET_DIR)\"" \ "\"$(ARCHIVE_SUBDIR_TO_INSTALL_FROM)\"" >> $(2[1]) } rule AddPackagesAndRepositoryVariablesToContainerScript script : container { AddVariableToScript $(script) : downloadDir : $(HAIKU_DOWNLOAD_DIR) ; AddTargetVariableToScript $(script) : <build>package ; AddTargetVariableToScript $(script) : <build>get_package_dependencies : getPackageDependencies ; # Add a variable to indicate whether packages dependencies shall be # resolved. We always want to do that in non-update mode, but also in update # mode when all packages are updated. local updateOnly = [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] ; local resolvePackageDependencies ; if ( ! $(updateOnly) || $(HAIKU_UPDATE_ALL_PACKAGES) ) && $(HAIKU_BUILD_TYPE) != bootstrap { resolvePackageDependencies = 1 ; } AddVariableToScript $(script) : resolvePackageDependencies : $(resolvePackageDependencies) ; AddVariableToScript $(script) : noDownloads : $(HAIKU_NO_DOWNLOADS) ; AddVariableToScript $(script) : updateAllPackages : $(HAIKU_UPDATE_ALL_PACKAGES) ; # Add variable "systemPackages" with the packages copied/updated. local systemPackages = [ on $(container) return $(HAIKU_SYSTEM_PACKAGES_IN_IMAGE) ] ; if $(updateOnly) && ! [ IncludeAllTargetsInContainer $(container) ] { systemPackages = [ FilterContainerUpdateTargets $(systemPackages) : [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ] ; } AddTargetVariableToScript $(script) : $(systemPackages) : systemPackages ; # Add variable "otherPackages" with the packages copied/updated. local otherPackages = [ on $(container) return $(HAIKU_OTHER_PACKAGES_IN_IMAGE) ] ; if $(updateOnly) && ! [ IncludeAllTargetsInContainer $(container) ] { otherPackages = [ FilterContainerUpdateTargets $(otherPackages) : [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ] ; } AddTargetVariableToScript $(script) : $(otherPackages) : otherPackages ; # Generate the repository package lists and add variables for the # repositories. local repository ; local repositoryFiles ; for repository in $(HAIKU_REPOSITORIES) { repositoryFiles += [ on $(repository) return $(HAIKU_REPOSITORY_CACHE_FILE) ] ; } AddTargetVariableToScript $(script) : $(repositoryFiles) : repositories ; } #pragma mark - Haiku Image rules rule SetUpdateHaikuImageOnly flag { HAIKU_CONTAINER_UPDATE_ONLY on $(HAIKU_IMAGE_CONTAINER_NAME) = $(flag) ; } rule IsUpdateHaikuImageOnly { on $(HAIKU_IMAGE_CONTAINER_NAME) return $(HAIKU_CONTAINER_UPDATE_ONLY) ; } rule AddDirectoryToHaikuImage directoryTokens : attributeFiles { # AddDirectoryToHaikuImage <directoryTokens> : <attributeFiles> return [ AddDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens) : $(attributeFiles) ] ; } rule AddFilesToHaikuImage directory : targets : destName : flags { # AddFilesToHaikuImage <directory> : <targets> : [ <destName> ] # : [ <flags> ] AddFilesToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directory) : $(targets) : $(destName) : $(flags) ; } rule FFilesInHaikuImageDirectory directoryTokens { return [ FFilesInContainerDirectory $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens) ] ; } rule AddSymlinkToHaikuImage directoryTokens : linkTarget : linkName { # AddSymlinkToHaikuImage <directory> : <link target> [ : <link name> ] ; linkTarget = $(linkTarget:J=/) ; AddSymlinkToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens) : $(linkTarget) : $(linkName) ; } rule FSymlinksInHaikuImageDirectory directoryTokens { return [ FSymlinksInContainerDirectory $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens) ] ; } rule CopyDirectoryToHaikuImage directoryTokens : sourceDirectory : targetDirectoryName : excludePatterns : flags { CopyDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens) : $(sourceDirectory) : $(targetDirectoryName) : $(excludePatterns) : $(flags) ; } rule AddSourceDirectoryToHaikuImage dirTokens : flags { # AddSourceDirectoryToHaikuImage <dirTokens> : <flags> ; CopyDirectoryToHaikuImage home HaikuSources : [ FDirName $(HAIKU_TOP) $(dirTokens) ] : : : $(flags) ; } rule AddHeaderDirectoryToHaikuImage dirTokens : dirName : flags { # AddHeaderDirectoryToHaikuImage <dirTokens> : [ <dirName> ] # : <flags> ; AddHeaderDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(dirTokens) : $(dirName) : $(flags) ; } rule AddWifiFirmwareToHaikuImage driver : package : archive : extract { # AddWifiFirmwareToHaikuImage <driver> : <package> : <archive> : <extract> AddWifiFirmwareToHaikuImage $(HAIKU_IMAGE_CONTAINER_NAME) : $(driver) : $(package) : $(archive) : $(extract) ; } rule ExtractArchiveToHaikuImage dirTokens : archiveFile : flags : extractedSubDir { # ExtractArchiveToHaikuImage <dirTokens> : <archiveFile> : <flags> # : <extractedSubDir> ; ExtractArchiveToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(dirTokens) : $(archiveFile) : $(flags) : $(extractedSubDir) ; } rule AddDriversToHaikuImage relativeDirectoryTokens : targets { # AddDriversToHaikuImage <relative directory> : <targets> ; AddDriversToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(relativeDirectoryTokens) : $(targets) ; } rule AddNewDriversToHaikuImage relativeDirectoryTokens : targets : flags { # AddNewDriversToHaikuImage <relative directory> : <targets> : <flags> ; AddNewDriversToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(relativeDirectoryTokens) : $(targets) : $(flags) ; } rule AddBootModuleSymlinksToHaikuImage targets { # AddBootModuleSymlinksToHaikuImage <targets> ; AddBootModuleSymlinksToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(targets) ; } rule AddPackageFilesToHaikuImage location : packages : flags { # AddPackageFilesToHaikuImage <location> : <packages> : <flags> # # Supported flags: # nameFromMetaInfo - determine the target file name from the package meta # info packages = [ FFilterByBuildFeatures $(packages) ] ; if $(location[1]) = system && $(location[2]) = packages && ! $(location[3]) { HAIKU_SYSTEM_PACKAGES_IN_IMAGE on $(HAIKU_IMAGE_CONTAINER_NAME) = [ on $(HAIKU_IMAGE_CONTAINER_NAME) return $(HAIKU_SYSTEM_PACKAGES_IN_IMAGE) ] $(packages) ; } else { HAIKU_OTHER_PACKAGES_IN_IMAGE on $(HAIKU_IMAGE_CONTAINER_NAME) = [ on $(HAIKU_IMAGE_CONTAINER_NAME) return $(HAIKU_OTHER_PACKAGES_IN_IMAGE) ] $(packages) ; } if nameFromMetaInfo in $(flags) { AddFilesToHaikuImage $(location) : $(packages) : packageFileName : computeName ; } else { AddFilesToHaikuImage $(location) : $(packages) ; } } rule AddOptionalHaikuImagePackages packages { local package ; for package in $(packages) { if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] { HAIKU_OPTIONAL_PACKAGE_ADDED on $(package) = 1 ; HAIKU_ADDED_OPTIONAL_PACKAGES += $(package) ; } local dependencies = [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_DEPENDENCIES) ] ; AddOptionalHaikuImagePackages $(dependencies) ; } } rule SuppressOptionalHaikuImagePackages packages { local package ; for package in $(packages) { if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_SUPPRESSED) ] { HAIKU_OPTIONAL_PACKAGE_SUPPRESSED on $(package) = 1 ; } } } rule IsOptionalHaikuImagePackageAdded package { if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_EXISTS) ] { HAIKU_OPTIONAL_PACKAGE_EXISTS on $(package) = 1 ; HAIKU_EXISTING_OPTIONAL_PACKAGES += $(package) ; } if [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] && ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_SUPPRESSED) ] { return 1 ; } return ; } rule OptionalPackageDependencies package : dependencies { HAIKU_OPTIONAL_PACKAGE_DEPENDENCIES on $(package) = $(dependencies) ; if [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] { AddOptionalHaikuImagePackages $(dependencies) ; } } rule AddHaikuImagePackages packages : directory { # AddHaikuImagePackages <packages> : <directory> ; # Adds the given packages <packages> to the image in the given directory. packages = [ FFilterByBuildFeatures $(packages) ] ; local package ; for package in $(packages) { local resolvedPackage = [ IsPackageAvailable $(package) ] ; if ! $(resolvedPackage) { Echo "AddHaikuImagePackages: package" $(package) "not available!" ; continue ; } if ! [ on $(resolvedPackage) return $(HAIKU_PACKAGE_ADDED) ] { HAIKU_PACKAGE_ADDED on $(resolvedPackage) = 1 ; HAIKU_ADDED_PACKAGES += $(resolvedPackage) ; # download the package file and add it to the image local file = [ FetchPackage $(package) ] ; if $(HAIKU_UPDATE_ALL_PACKAGES) { HAIKU_INCLUDE_IN_IMAGE on $(file) = 1 ; } AddPackageFilesToHaikuImage $(directory) : $(file) ; } } } rule AddHaikuImageSourcePackages packages { # AddHaikuImageSourcePackages <packages> ; # Adds the given source packages for <packages> to the image. if $(HAIKU_INCLUDE_SOURCES) = 1 { AddHaikuImagePackages $(packages)_source : _sources_ ; } } rule AddHaikuImageSystemPackages packages { # AddHaikuImageSystemPackages <packages> ; # Adds the given packages for <packages> to the image, in the system # directory, so they will be activated on first boot. AddHaikuImagePackages $(packages) : system packages ; } rule AddHaikuImageDisabledPackages packages { # AddHaikuImageDisabledPackages <packages> ; # Adds the given packages for <packages> to the image, in the _packages_ # directory, so they can be later enabled in Installer. AddHaikuImagePackages $(packages) : _packages_ ; } rule IsHaikuImagePackageAdded package { local resolvedPackage = [ IsPackageAvailable $(package) ] ; if $(resolvedPackage) && [ on $(resolvedPackage) return $(HAIKU_PACKAGE_ADDED) ] { return 1 ; } return ; } rule BuildHaikuImagePackageList target { if ! $(target) { return ; } # get the file names of all added packages local packageFiles ; local package ; for package in $(HAIKU_ADDED_PACKAGES) { packageFiles += [ FetchPackage $(package) : nameResolved ] ; } # extract the versioned package names (without revision) packageFiles = [ Match "^([^-]*)" : $(packageFiles:B) ] ; HAIKU_IMAGE_PACKAGES on $(target) = $(packageFiles) ; } actions BuildHaikuImagePackageList { echo $(HAIKU_IMAGE_PACKAGES) | xargs -n 1 echo | LC_ALL=C sort -u > $(1) } rule AddEntryToHaikuImageUserGroupFile file : entry { local allEntries = [ on $(file) return $(HAIKU_IMAGE_USER_GROUP_ENTRIES) ] ; if $(allEntries) { allEntries = $(allEntries)|$(entry) ; } else { allEntries = $(entry) ; Always $(file) ; MakeLocate $(file) : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ; BuildHaikuImageUserGroupFile $(file) ; AddFilesToHaikuImage system settings etc : $(file) ; } HAIKU_IMAGE_USER_GROUP_ENTRIES on $(file) = $(allEntries) ; } actions BuildHaikuImageUserGroupFile { echo "$(HAIKU_IMAGE_USER_GROUP_ENTRIES)" | tr '|' '\n' > $(1) } rule AddUserToHaikuImage user : uid : gid : home : shell : realName { if ! $(user) || ! $(uid) || ! $(gid) || ! $(home) { Exit "Invalid haiku user specification passed to AddUserToHaikuImage." ; } local entry = $(user):x:$(uid):$(gid):$(realName:E=$(user)):$(home):$(shell:E="") ; AddEntryToHaikuImageUserGroupFile <haiku-image>passwd : $(entry) ; } rule AddGroupToHaikuImage group : gid : members { if ! $(group) || ! $(gid) { Exit "Invalid haiku group specification passed to" "AddGroupToHaikuImage." ; } local entry = $(group):x:$(gid):$(members:J=,:E) ; AddEntryToHaikuImageUserGroupFile <haiku-image>group : $(entry) ; } rule AddLibrariesToHaikuImage directory : libs { # AddLibraryToHaikuImage <directory> : <libs> # # Installs libraries with the appropriate links onto the image. # AddLibrariesToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directory) : $(libs) ; } rule CreateHaikuImageMakeDirectoriesScript script { CreateContainerMakeDirectoriesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ; } rule CreateHaikuImageCopyFilesScript script { CreateContainerCopyFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ; } rule CreateHaikuImageExtractFilesScript script { CreateContainerExtractFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ; } rule BuildHaikuImage haikuImage : scripts : isImage : isVMwareImage { # BuildHaikuImage <haiku image> : <scripts> : <is image> : <isVMwareImage> ; if $(isImage) = 1 || $(isImage) = true { IS_IMAGE on $(haikuImage) = 1 ; } else { IS_IMAGE on $(haikuImage) = "" ; } if $(isVMwareImage) = 1 || $(isVMwareImage) = true { IS_VMWARE_IMAGE on $(haikuImage) = 1 ; } else { IS_VMWARE_IMAGE on $(haikuImage) = "" ; } local mainScript = build_haiku_image ; SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ; Depends $(haikuImage) : $(mainScript) $(scripts) ; BuildHaikuImage1 $(haikuImage) : $(mainScript) $(scripts:R=$(HAIKU_ABSOLUTE_OUTPUT_DIR)) ; } actions BuildHaikuImage1 { export imagePath="$(1)" export isImage="$(IS_IMAGE)" export isVMwareImage="$(IS_VMWARE_IMAGE)" $(2[1]) $(2[2-]) } rule BuildVMWareImage vmwareImage : plainImage : imageSize { # BuildVMWareImage <vmware image> : <plain image> : <image size in MB> IMAGE_SIZE on $(vmwareImage) = $(imageSize) ; Depends $(vmwareImage) : <build>vmdkheader $(plainImage) ; BuildVMWareImage1 $(vmwareImage) : <build>vmdkheader $(plainImage) ; } actions BuildVMWareImage1 { $(RM) $(1) $(2[1]) -h 64k -i$(IMAGE_SIZE)M $(1) && cat $(2[2]) >> $(1) } #pragma mark - Network Boot Archive rules rule AddDirectoryToNetBootArchive directoryTokens { # AddDirectoryToNetBootArchive <directoryTokens> return [ AddDirectoryToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(directoryTokens) ] ; } rule AddFilesToNetBootArchive directory : targets : destName { # AddFilesToNetBootArchive <directory> : <targets> [ : dest name ] AddFilesToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(directory) : $(targets) : $(destName) ; } rule AddSymlinkToNetBootArchive directoryTokens : linkTarget : linkName { # AddSymlinkToNetBootArchive <directory> : <link target> [ : <link name> ] ; AddSymlinkToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(directoryTokens) : $(linkTarget) : $(linkName) ; } rule AddDriversToNetBootArchive relativeDirectoryTokens : targets { # AddDriversToNetBootArchive <relative directory> : <targets> ; AddDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(relativeDirectoryTokens) : $(targets) ; } rule AddNewDriversToNetBootArchive relativeDirectoryTokens : targets { # AddNewDriversToNetBootArchive <relative directory> : <targets> ; AddNewDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(relativeDirectoryTokens) : $(targets) ; } rule AddDriverRegistrationToNetBootArchive relativeDirectoryTokens : target : links { # AddDriverRegistrationToNetBootArchive <directory> : <link target> # : <link names> ] ; AddDriverRegistrationToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(relativeDirectoryTokens) : $(target) : $(links) ; } rule AddBootModuleSymlinksToNetBootArchive targets { # AddBootModuleSymlinksToNetBootArchive <targets> ; AddBootModuleSymlinksToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(targets) ; } rule CreateNetBootArchiveMakeDirectoriesScript script { CreateContainerMakeDirectoriesScript $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(script) ; } rule CreateNetBootArchiveCopyFilesScript script { CreateContainerCopyFilesScript $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(script) ; } rule BuildNetBootArchive archive : scripts { # BuildNetBootArchive <archive> : <scripts> ; local mainScript = build_archive ; SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ; Depends $(archive) : $(mainScript) $(scripts) ; BuildNetBootArchive1 $(archive) : $(mainScript) $(scripts:R=$(HAIKU_ABSOLUTE_OUTPUT_DIR)) ; } actions BuildNetBootArchive1 { $(2[1]) $(1) $(2[2-]) } #pragma mark - Floppy Boot Archive rules rule AddDirectoryToFloppyBootArchive directoryTokens { # AddDirectoryToFloppyBootArchive <directoryTokens> return [ AddDirectoryToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(directoryTokens) ] ; } rule AddFilesToFloppyBootArchive directory : targets : destName { # AddFilesToFloppyBootArchive <directory> : <targets> [ : dest name ] AddFilesToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(directory) : $(targets) : $(destName) ; } rule AddSymlinkToFloppyBootArchive directoryTokens : linkTarget : linkName { # AddSymlinkToFloppyBootArchive <directory> : <link target> # [ : <link name> ] ; AddSymlinkToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(directoryTokens) : $(linkTarget) : $(linkName) ; } rule AddDriversToFloppyBootArchive relativeDirectoryTokens : targets { # AddDriversToFloppyBootArchive <relative directory> : <targets> ; AddDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(relativeDirectoryTokens) : $(targets) ; } rule AddNewDriversToFloppyBootArchive relativeDirectoryTokens : targets { # AddNewDriversToFloppyBootArchive <relative directory> : <targets> ; AddNewDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(relativeDirectoryTokens) : $(targets) ; } rule AddDriverRegistrationToFloppyBootArchive relativeDirectoryTokens : target : links { # AddDriverRegistrationToFloppyBootArchive <directory> : <link target> # : <link names> ] ; AddDriverRegistrationToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(relativeDirectoryTokens) : $(target) : $(links) ; } rule AddBootModuleSymlinksToFloppyBootArchive targets { # AddBootModuleSymlinksToFloppyBootArchive <targets> ; AddBootModuleSymlinksToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(targets) ; } rule CreateFloppyBootArchiveMakeDirectoriesScript script { CreateContainerMakeDirectoriesScript $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(script) ; } rule CreateFloppyBootArchiveCopyFilesScript script { CreateContainerCopyFilesScript $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(script) ; } rule BuildFloppyBootArchive archive : scripts { # BuildHFloppyBootArchive <archive> : <scripts> ; local mainScript = build_archive ; SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ; Depends $(archive) : $(mainScript) $(scripts) ; BuildFloppyBootArchive1 $(archive) : $(mainScript) $(scripts:R=$(HAIKU_ABSOLUTE_OUTPUT_DIR)) ; } actions BuildFloppyBootArchive1 { $(2[1]) $(1) $(2[2-]) } # warning: that is quite x86 dependant... rule BuildFloppyBootImage image : haikuLoader : archive { Depends $(image) : $(haikuLoader) ; Depends $(image) : $(archive) ; #MakeLocateDebug $(image) ; FLOPPY_IMAGE_SIZE on $(image) = $(HAIKU_BOOT_FLOPPY_IMAGE_SIZE) ; ARCHIVE_IMAGE_OFFSET on $(image) = $(HAIKU_BOOT_ARCHIVE_IMAGE_OFFSET) ; BuildFloppyBootImage1 $(image) : $(haikuLoader) $(archive) ; if $(HAIKU_KERNEL_PLATFORM) = atari_m68k { Depends $(image) : <build>fixup_tos_boot_checksum ; BuildFloppyBootImageFixupM68K $(image) : <build>fixup_tos_boot_checksum ; } if $(HAIKU_KERNEL_PLATFORM) = amiga_m68k { Depends $(image) : <build>fixup_amiga_boot_checksum ; BuildFloppyBootImageFixupM68K $(image) : <build>fixup_amiga_boot_checksum ; } } actions BuildFloppyBootImage1 { haiku_loader_size=`stat -c %s "$(>[1])"` drivers_tgz_size=`stat -c %s "$(>[2])"` if [ $? -ne 0 ] ; then # FreeBSD's stat command don't support -c/--format option # and use %z specifier for file size haiku_loader_size=`stat -f %z "$(>[1])"` drivers_tgz_size=`stat -f %z "$(>[2])"` fi archive_image_offset=`echo "$(ARCHIVE_IMAGE_OFFSET) * 1024" | bc` floppy_tgz_size=\ `echo "($(FLOPPY_IMAGE_SIZE) - $(ARCHIVE_IMAGE_OFFSET)) * 1024" | bc` if [ $haiku_loader_size -gt $archive_image_offset ] ; then echo "Error: $(>[1]) is too big ($haiku_loader_size) to fit " echo " before the boot archive starting at $archive_image_offset!" exit 1 fi if [ $drivers_tgz_size -gt $floppy_tgz_size ] ; then echo "Error: $(>[2]) is too big ($drivers_tgz_size) to fit " echo " in the boot floppy ($floppy_tgz_size)!" exit 1 fi $(RM) $(<) # make an empty image dd if=/dev/zero of=$(<) bs=1k count=$(FLOPPY_IMAGE_SIZE) # add haiku_loader dd if=$(>[1]) of=$(<) conv=notrunc # add the boot drivers tgz archive dd if=$(>[2]) of=$(<) bs=$(ARCHIVE_IMAGE_OFFSET)k seek=1 conv=notrunc } actions BuildFloppyBootImageFixupM68K { # fixup the boot sector checksum $(>[1]) $(<) } #pragma mark - CD Boot Image rules rule BuildCDBootImage image : bootfloppy : bootefi : extrafiles { Depends $(image) : $(bootfloppy) ; Depends $(image) : $(bootefi) ; Depends $(image) : $(extrafiles) ; BOOTIMG on $(image) = $(bootfloppy) ; if $(HAIKU_NIGHTLY_BUILD) = 1 { VOLID on $(image) = haiku-nightly-$(TARGET_ARCH) ; } else { VOLID on $(image) = haiku-$(HAIKU_VERSION)-$(TARGET_ARCH) ; } if $(HAIKU_ANYBOOT_LEGACY) = 1 { BuildCDBootImageMBR $(image) : $(bootfloppy) $(extrafiles) ; } else { BOOTEFI on $(image) = $(bootefi) ; BuildCDBootImageEFI $(image) : $(bootfloppy) $(bootefi) $(extrafiles) ; } } actions BuildCDBootImageMBR { $(RM) $(<) xorriso -as mkisofs -b $(BOOTIMG) -r -J -V $(VOLID) -o $(<) $(>[1]) $(>[2-]) } actions BuildCDBootImageEFI { $(RM) $(<) xorriso -as mkisofs -b $(BOOTIMG) -eltorito-alt-boot -no-emul-boot -e $(BOOTEFI) \ -r -J -V $(VOLID) -o $(<) $(>[1]) $(>[2]) $(>[3-]) } #pragma mark - CD Boot PPC Image rules rule BuildCDBootPPCImage image : hfsmaps : elfloader : coffloader : chrpscript : extrafiles { Depends $(image) : $(elfloader) ; Depends $(image) : $(coffloader) ; Depends $(image) : $(chrpscript) ; Depends $(image) : $(extrafiles) ; Depends $(image) : $(hfsmaps) ; MAPS on $(image) = $(hfsmaps) ; if $(HAIKU_NIGHTLY_BUILD) = 1 { VOLID on $(image) = haiku-nightly-$(TARGET_ARCH) ; } else { VOLID on $(image) = haiku-$(HAIKU_VERSION)-$(TARGET_ARCH) ; } BuildCDBootPPCImage1 $(image) : $(elfloader) $(coffloader) $(chrpscript) $(extrafiles) ; } actions BuildCDBootPPCImage1 bind MAPS { $(RM) $(<) mkdir -p $(HAIKU_OUTPUT_DIR)/cd/ppc mkdir -p $(HAIKU_OUTPUT_DIR)/cd/boot # CHRP Boot script cp $(>[3]) $(HAIKU_OUTPUT_DIR)/cd/ppc/bootinfo.txt cp $(>[3]) $(HAIKU_OUTPUT_DIR)/cd/boot/boot.chrp # Haiku Bootloaders cp $(>[2]) $(HAIKU_OUTPUT_DIR)/cd/boot/haikuloader.xcf cp $(>[1]) $(HAIKU_OUTPUT_DIR)/cd/boot/haikuloader.elf # Extras (readme files, etc) cp $(>[4]) $(HAIKU_OUTPUT_DIR)/cd/ # Xorriso doesn't have map and some other required tools # to make bootable PowerPC images genisoimage -v -hfsplus -map $(MAPS) \ -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/boot -part -no-desktop \ -hfs-parms MAX_XTCSIZE=2656248 -hfs-volid Haiku \ --chrp-boot -r -J -o $(<) $(HAIKU_OUTPUT_DIR)/cd $(RM) -r $(HAIKU_OUTPUT_DIR)/cd } #pragma mark - EFI System Partition rules rule BuildEfiSystemPartition image : efiLoader { local macVolumeIcon = [ FDirName $(HAIKU_TOP) data artwork VolumeIcon.icns ] ; local fatshell = <build>fat_shell ; Depends $(image) : $(efiLoader) ; Depends $(image) : $(macVolumeIcon) ; Depends $(image) : $(fatshell) ; switch $(TARGET_ARCH) { case x86_64 : EFINAME on $(image) = "BOOTX64.EFI" ; case arm : EFINAME on $(image) = "BOOTARM.EFI" ; case arm64 : EFINAME on $(image) = "BOOTAA64.EFI" ; case riscv32 : EFINAME on $(image) = "BOOTRISCV32.EFI" ; case riscv64 : EFINAME on $(image) = "BOOTRISCV64.EFI" ; case * : Exit "Error: Unknown EFI architecture!" ; } BuildEfiSystemPartition1 $(image) : $(fatshell) $(macVolumeIcon) $(efiLoader) ; } # Usage: # out : fatshell volumeIcon loader actions BuildEfiSystemPartition1 { $(RM) $(<) export $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) dd if=/dev/zero of=$(<) bs=1024 count=2880 FATFS="$(2[1])" EFIICON="$(2[2])" LOADER="$(2[3])" ${FATFS} --initialize "$(<)" 'Haiku ESP' echo "mkdir myfs/EFI" | ${FATFS} $(<) echo "mkdir myfs/EFI/BOOT" | ${FATFS} $(<) echo "cp :${LOADER} myfs/EFI/BOOT/$(EFINAME)" | ${FATFS} $(<) echo "cp :${EFIICON} myfs/.VolumeIcon.icns" | ${FATFS} $(<) }