haiku/build/jam/ImageRules
Ingo Weinhold 1ca065fa88 * Added second parameter to AddDirectoryToHaikuImage, a list of resource
(or rdef) files which will be converted to attributes and added to the
  installed directory. Adjusted build_haiku_image script accordingly.
* Added directory data/image_directories, which is where the resource
  files for the directories attributes shall be stored. As naming
  convention I suggest using the target directory path with slashes
  replaced by hyphens, e.g. home-config-bin.rdef for home/config/bin.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21711 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-26 23:20:58 +00:00

654 lines
18 KiB
Plaintext

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 -f $(1)
echo -n > $(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)+=\\\" $(value[1])\\\" >> " ;
value = $(value[2-]) ;
}
AddVariableToScript1 $(script) ;
}
actions together AddVariableToScript1
{
$(VARIABLE_DEFS)$(1);
}
rule AddTargetVariableToScript
{
# AddTargetVariableToScript <script> : <target> [ : <variable> ] ;
#
local script = $(1) ;
local target = $(2) ;
local variable = $(3:E=$(target:BS)) ;
InitScript $(script) ;
# That's not completely save, if one has more than on target with the
# same base name. A unique pseudo target would have to be introduced
# to do it more correctly.
VARIABLE_NAME($(target:BS)) on $(script) = $(variable) ;
Depends $(script) : $(target) ;
AddTargetVariableToScript1 $(script) : $(target) ;
}
actions AddTargetVariableToScript1
{
echo "$(VARIABLE_NAME($(2:BS)))=\"$(2)\"" >> $(1)
}
#pragma mark -
rule AddDirectoryToContainer container : directoryTokens
{
# AddDirectoryToContainer <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) ] {
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 ;
}
}
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 AddFilesToContainer container : directoryTokens : targets : destName
{
# AddFilesToContainer <container> : <directoryTokens> : <targets>
# [ : dest name ]
#
local directory = [ AddDirectoryToContainer $(container)
: $(directoryTokens) ] ;
local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
# If the image shall only be updated, we filter out all targets not marked
# accordingly.
if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] {
local filterVar
= [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ;
if $(filterVar) {
targets = [ FilterContainerUpdateTargets $(targets)
: $(filterVar) ] ;
}
}
# We create a unique dummy target per target to install.
local installTargetsVar
= [ on $(container) return $(HAIKU_INSTALL_TARGETS_VAR) ] ;
local target ;
for target in $(targets) {
local name ;
if $(destName) {
name = $(destName) ;
} else {
name = $(target:G=:D=) ;
}
local destTarget = $(name:G=$(containerGrist)__$(directory:G=)) ;
TARGET on $(destTarget) = $(target) ;
INSTALL_DIR on $(destTarget) = $(directory) ;
$(installTargetsVar) on $(target) += $(destTarget) ;
TARGETS_TO_INSTALL on $(directory) += $(destTarget) ;
}
}
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) ] {
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 AddDriversToContainer container : relativeDirectoryTokens : targets
{
# AddDriversToContainer <container> : <relative directory> : <targets> ;
#
local directoryTokens = beos system add-ons kernel drivers dev
$(relativeDirectoryTokens) ;
AddFilesToContainer $(container) : beos system add-ons kernel drivers bin
: $(targets) ;
# If the image shall only be updated, we don't add any symlinks.
if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] {
return ;
}
# get the relative symlink path prefix
local linkPrefix = ;
for i in $(relativeDirectoryTokens) {
linkPrefix += .. ;
}
linkPrefix += .. bin ;
# add the symlinks
local name ;
for name in $(targets:BS) {
AddSymlinkToContainer $(container) : $(directoryTokens)
: [ FDirName $(linkPrefix) $(name) ] : $(name) ;
}
}
rule AddDriverRegistrationToContainer container : relativeDirectoryTokens
: target : links
{
# AddDriverRegistrationToContainer <container> : <directory>
# : <link target> : <link names> ] ;
#
local directoryTokens = beos system add-ons kernel registration
$(relativeDirectoryTokens) ;
# get the relative symlink path prefix
local linkPrefix = ;
for i in $(relativeDirectoryTokens) {
linkPrefix += .. ;
}
linkPrefix += .. drivers bin ;
# add the symlink
AddSymlinkToContainer $(container) : $(directoryTokens)
: [ FDirName $(linkPrefix) $(target:BS) ] : $(links) ;
}
rule AddBootModuleSymlinksToContainer container : targets
{
# AddBootModuleSymlinksToContainer <container> : <targets> ;
#
# If the image shall only be updated, we don't add any symlinks.
if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] {
return ;
}
# 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." ;
}
local name = $(target:BS) ;
local linkTarget = [ FDirName /boot $(installDir:G=) $(name) ] ;
AddSymlinkToContainer $(container) : beos system add-ons kernel boot
: $(linkTarget) : $(name) ;
}
}
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) ] {
Depends $(scriptBody) : $(dirsToCreate) ;
CreateContainerMakeDirectoriesScript1 $(scriptBody) : $(dirsToCreate) ;
# 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) ;
Depends $(script) : $(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 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:BS) ;
if $(name) != $(target:BS) {
# 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=) ;
INSTALL_TARGET_NAME on $(dummyTarget) = $(name) ;
Depends $(dummyTarget) : $(initScript) $(target) ;
Depends $(script) : $(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) ;
Depends $(script) : $(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) ;
AddSymlinkToContainerCopyFilesScript $(symlink) : $(initScript) ;
}
}
}
actions piecemeal AppendToContainerCopyFilesScript bind OUTPUT_SCRIPT
{
echo \$cp "\"\${sPrefix}$(2)\"" "\"\${tPrefix}$(TARGET_DIR)\"" >> $(OUTPUT_SCRIPT)
}
actions AppendToContainerCopyFilesScriptSingleFile
{
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])
}
#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>
local dir = [ AddDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
: $(directoryTokens) ] ;
if $(attributeFiles) {
SEARCH on $(attributeFiles)
+= [ FDirName $(HAIKU_TOP) data image_directories ] ;
ATTRIBUTE_FILES on $(dir) += $(attributeFiles) ;
}
return $(dir) ;
}
rule AddFilesToHaikuImage directory : targets : destName
{
# AddFilesToHaikuImage <directory> : <targets> [ : dest name ]
AddFilesToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directory)
: $(targets) : $(destName) ;
}
rule AddSymlinkToHaikuImage directoryTokens : linkTarget : linkName
{
# AddSymlinkToHaikuImage <directory> : <link target> [ : <link name> ] ;
AddSymlinkToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens)
: $(linkTarget) : $(linkName) ;
}
rule AddSourceDirectoryToHaikuImage dirTokens : alwaysUpdate
{
# AddSourceDirectoryToHaikuImage <dirTokens> : <alwaysUpdate> ;
# If the image shall only be updated, we update sources only, if explicitely
# requested.
if ! $(HAIKU_IMAGE_UPDATE_ONLY) || $(alwaysUpdate) {
HAIKU_INSTALL_SOURCE_DIRS += [ FDirName $(HAIKU_TOP) $(dirTokens) ] ;
}
}
rule AddDriversToHaikuImage relativeDirectoryTokens : targets
{
# AddDriversToHaikuImage <relative directory> : <targets> ;
AddDriversToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
: $(relativeDirectoryTokens) : $(targets) ;
}
rule AddDriverRegistrationToHaikuImage relativeDirectoryTokens : target : links
{
# AddDriverRegistrationToHaikuImage <directory> : <link target> : <link names> ] ;
AddDriverRegistrationToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
: $(relativeDirectoryTokens) : $(target) : $(links) ;
}
rule AddBootModuleSymlinksToHaikuImage targets
{
# AddBootModuleSymlinksToHaikuImage <targets> ;
AddBootModuleSymlinksToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
: $(targets) ;
}
rule CreateHaikuImageMakeDirectoriesScript script
{
CreateContainerMakeDirectoriesScript $(HAIKU_IMAGE_CONTAINER_NAME)
: $(script) ;
}
rule CreateHaikuImageCopyFilesScript script
{
CreateContainerCopyFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ;
}
rule BuildHaikuImage haikuImage : scripts : isImage
{
# BuildHaikuImage <haiku image> : <scripts> : <is image> ;
if $(isImage) = 1 || $(isImage) = true {
IS_IMAGE on $(haikuImage) = 1 ;
} else {
IS_IMAGE on $(haikuImage) = "" ;
}
local mainScript = build_haiku_image ;
SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
Depends $(haikuImage) : $(mainScript) $(scripts) ;
BuildHaikuImage1 $(haikuImage) : $(mainScript) $(scripts) ;
}
actions BuildHaikuImage1
{
export isImage="$(IS_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 -f $(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 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
{
# BuildHNetBootArchive <archive> : <scripts> ;
local mainScript = build_tgz_archive ;
SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
Depends $(archive) : $(mainScript) $(scripts) ;
BuildNetBootArchive1 $(archive) : $(mainScript) $(scripts) ;
}
actions BuildNetBootArchive1
{
$(2[1]) $(1) $(2[2-])
}