haiku/build/jam/MiscRules
Augustin Cavalier 128781e740 build/jam: Inline HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR where possible.
The "exec" tool can only handle one command with environs set at
the beginning of the line, so now we set the ADD_BUILD_COMPAT...
in this format. This also seems to be a general performance
improvement to builds using real shells, too.

Change-Id: If4b3117651b5475039d5e8116cd3de398582290a
2019-08-30 17:11:50 -04:00

451 lines
12 KiB
Plaintext

rule SetupObjectsDir
{
# SetupObjectsDir
#
# Internal rule used to set up the *{LOCATE,SEARCH}*_{TARGET,SOURCE}
# variables for the current directory.
local relPath = [ FDirName $(SUBDIR_TOKENS[2-]) ] ;
if $(relPath) = . {
relPath = ;
}
COMMON_PLATFORM_LOCATE_TARGET
= [ FDirName $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) $(relPath) ] ;
HOST_COMMON_ARCH_LOCATE_TARGET
= [ FDirName $(HOST_COMMON_ARCH_OBJECT_DIR) $(relPath) ] ;
TARGET_COMMON_ARCH_LOCATE_TARGET
= [ FDirName $(TARGET_COMMON_ARCH_OBJECT_DIR) $(relPath) ] ;
local var ;
for var in COMMON_DEBUG DEBUG_$(HAIKU_DEBUG_LEVELS) {
HOST_$(var)_LOCATE_TARGET
= [ FDirName $(HOST_$(var)_OBJECT_DIR) $(relPath) ] ;
TARGET_$(var)_LOCATE_TARGET
= [ FDirName $(TARGET_$(var)_OBJECT_DIR_$(TARGET_PACKAGING_ARCH))
$(relPath) ] ;
}
LOCATE_TARGET = $(COMMON_PLATFORM_LOCATE_TARGET) ;
LOCATE_SOURCE = $(LOCATE_TARGET) ;
SEARCH_SOURCE = $(SUBDIR) $(LOCATE_SOURCE)
$(HOST_COMMON_DEBUG_LOCATE_TARGET) # Also add the standard output
$(TARGET_COMMON_DEBUG_LOCATE_TARGET) # dirs for generated sources.
;
}
rule SetupFeatureObjectsDir feature
{
# SetupFeatureObjectsDir <feature>
#
# Updates the *{LOCATE,SEARCH}*_{TARGET,SOURCE} variables for the current
# directory appending a <feature> to each of them. Note that it resets
# the LOCATE_TARGET, LOCATE_SOURCE, SEARCH_SOURCE (!) variables. I.e. it
# should be invoked before customizing these variables further (e.g. like
# adding additional source directories to SEARCH_SOURCE).
COMMON_PLATFORM_LOCATE_TARGET
= [ FDirName $(COMMON_PLATFORM_LOCATE_TARGET) $(feature) ] ;
local var ;
for var in COMMON_ARCH COMMON_DEBUG DEBUG_$(HAIKU_DEBUG_LEVELS) {
HOST_$(var)_LOCATE_TARGET
= [ FDirName $(HOST_$(var)_LOCATE_TARGET) $(feature) ] ;
TARGET_$(var)_LOCATE_TARGET
= [ FDirName $(TARGET_$(var)_LOCATE_TARGET) $(feature) ] ;
}
LOCATE_TARGET = [ FDirName $(LOCATE_TARGET) $(feature) ] ;
LOCATE_SOURCE = $(LOCATE_TARGET) ;
SEARCH_SOURCE = $(SUBDIR) $(LOCATE_SOURCE)
$(HOST_COMMON_DEBUG_LOCATE_TARGET) # Also add the standard output
$(TARGET_COMMON_DEBUG_LOCATE_TARGET) # dirs for generated sources.
;
}
# pragma mark - MakeLocate variants
rule MakeLocateCommonPlatform files : subdir
{
# The file is shared between all target platforms.
MakeLocate $(files)
: [ FDirName $(COMMON_PLATFORM_LOCATE_TARGET) $(subdir) ] ;
}
rule MakeLocatePlatform files : subdir
{
# The file is specific for the target platform, but
# architecture independent. Usually the right rule for generated
# sources, though sometimes sources can be architecture specific.
local file ;
for file in $(files) {
local directory ;
if [ on $(file) return $(PLATFORM) ] = host {
directory = $(HOST_COMMON_ARCH_LOCATE_TARGET) ;
} else {
directory = $(TARGET_COMMON_ARCH_LOCATE_TARGET) ;
}
MakeLocate $(file) : [ FDirName $(directory) $(subdir) ] ;
}
}
rule MakeLocateArch files : subdir
{
# The file is platform+architecture specific, but is debug
# level independent. This is usually the right rule for generated
# architecture specific data or source files.
local file ;
for file in $(files) {
local directory ;
if [ on $(file) return $(PLATFORM) ] = host {
directory = $(HOST_COMMON_DEBUG_LOCATE_TARGET) ;
} else {
directory = $(TARGET_COMMON_DEBUG_LOCATE_TARGET) ;
}
MakeLocate $(file) : [ FDirName $(directory) $(subdir) ] ;
}
}
rule MakeLocateDebug files : subdir
{
# The file is platform+architecture+debug level specific.
# That's what should be used for compiled code.
local file ;
for file in $(files) {
local directory ;
on $(file) {
if $(PLATFORM) = host {
directory = $(HOST_DEBUG_$(DEBUG)_LOCATE_TARGET) ;
} else {
directory = $(TARGET_DEBUG_$(DEBUG)_LOCATE_TARGET) ;
}
}
MakeLocate $(file) : [ FDirName $(directory) $(subdir) ] ;
}
}
# pragma mark - Deferred SubIncludes
# The variable used to collect the deferred SubIncludes.
HAIKU_DEFERRED_SUB_INCLUDES = ;
rule DeferredSubInclude params : jamfile : scope
{
# DeferredSubInclude <subdir tokens> [ : <jamfile name> [ : <scope> ] ] ;
#
# Takes the same directory tokens parameter as SubInclude plus an optional
# alternative Jamfile name. The the subdirectory referred to by
# <subdir tokens> will be included when ExecuteDeferredSubIncludes is
# invoked, i.e. at the end of the root Jamfile. The <jamfile name> parameter
# specifies the name of the Jamfile to include. By default it is "Jamfile".
# The <scope> parameter can be "global" (default) or "local", specifying
# whether the alternative Jamfile name shall also be used for subdirectories.
HAIKU_DEFERRED_SUB_INCLUDES += "/" $(params) ;
if $(jamfile) {
SetConfigVar JAMFILE : $(params) : $(jamfile) : $(scope) ;
}
}
rule ExecuteDeferredSubIncludes
{
# ExecuteDeferredSubIncludes ;
#
# Performs the deferred SubIncludes scheduled by DeferredSubInclude.
local tokensList = $(HAIKU_DEFERRED_SUB_INCLUDES) ;
while $(tokensList) {
# chop off leading "/"
tokensList = $(tokensList[2-]) ;
# get the tokens for the next include
local tokens ;
while $(tokensList) && $(tokensList[1]) != "/" {
tokens += $(tokensList[1]) ;
tokensList = $(tokensList[2-]) ;
}
# perform the include
if $(tokens) {
SubInclude $(tokens) ;
}
}
}
rule HaikuSubInclude tokens
{
# HaikuSubInclude <tokens> ;
#
# Current subdir relative SubInclude.
# <tokens> - subdir tokens specifying the subdirectory to be include
# (relative to the current subdir)
if $(tokens) {
SubInclude HAIKU_TOP $(SUBDIR_TOKENS) $(tokens) ;
}
}
# pragma mark - Unique IDs/targets
# private to NextID; incremented with each NextID invocation
HAIKU_NEXT_ID = 0 ;
rule NextID
{
# NextID ;
local result = $(HAIKU_NEXT_ID:J=) ;
HAIKU_NEXT_ID = [ AddNumAbs $(HAIKU_NEXT_ID) : 1 ] ;
return $(result) ;
}
rule NewUniqueTarget basename
{
# NewUniqueTarget [ basename ] ;
local id = [ NextID ] ;
return $(basename[1]:E=_target:G=unique!target)_$(id) ;
}
# pragma mark - RunCommandLine
rule RunCommandLine commandLine
{
# RunCommandLine <commandLine>
#
# Creates a pseudo target that, when made by jam, causes the supplied shell
# command line to be executed. Elements of <commandLine> with the prefix ":"
# are replaced by the rule. After stripping the prefix such a string specifies
# a build system target and the finally executed command line will contain
# a path to the target instead.
# The pseudo target will depend on all targets thus identified. Each
# invocation of this rule creates a different pseudo target, which is
# returned to the caller.
# collect the targets in the command line and replace them by $targetX*
# variables
local substitutedCommandLine ;
local targets ;
local targetVarName = target ;
local i ;
for i in $(commandLine) {
# targets are marked by the ":" prefix
local target = [ Match ^:(.*) : $(i) ] ;
if $(target) {
targets += $(target) ;
targetVarName = $(targetVarName)X ;
i = "$"$(targetVarName) ;
}
substitutedCommandLine += $(i) ;
}
# define the "run" target
local run = [ NewUniqueTarget run ] ;
COMMAND_LINE on $(run) = $(substitutedCommandLine) ;
NotFile $(run) ;
Always $(run) ;
Depends $(run) : $(targets) ;
RunCommandLine1 $(run) : $(targets) ;
return $(run) ;
}
actions RunCommandLine1 {
target=target;
for t in $(2) ; do
target=${target}X
eval "${target}=${t}"
done
$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) \
"$(COMMAND_LINE)"
}
#pragma mark - DefineBuildProfile
rule DefineBuildProfile name : type : path {
# DefineBuildProfile <name> : <type> [ : <path> ]
#
# Makes a build profile known. Build profiles can be used to define
# different sets of settings for Haiku images/installations. For each
# profile the default actions "build", "update", and "mount" (the latter
# only for disks or image types) will be available (i.e. can be specified
# as second parameter on the jam command line). They will build an image
# or installation, update only given targets, respectively just mount the
# image or disk using the bfs_shell.
#
# <name> - The name of the build profile.
# <type> - The type of the build profile. Must be one of "image" (plain
# disk image), "anyboot-image" (custom disk image that can be
# written to CD or disk device), "cd-image" (ISO CD image),
# "vmware-image" (VMware disk image), "disk" (actual partition
# or hard disk device), "install" (installation in a directory),
# or "custom" (user-defined).
# <path> - The path associated with the profile. Depending on the profile
# type, this is the path to the disk image/VMware image, hard
# disk/partition device, or the installation directory. If the
# parameter is omitted, the value of the HAIKU[_VMWARE]_IMAGE_NAME,
# HAIKU_IMAGE_DIR, respectively HAIKU_INSTALL_DIR or their default
# values will be used instead.
if [ on $(name) return $(HAIKU_BUILD_PROFILE_SPECIFIED) ] {
Exit "ERROR: Build profile \"$(name)\" defined twice!" ;
}
HAIKU_BUILD_PROFILE_SPECIFIED on $(name) = 1 ;
if ! $(HAIKU_BUILD_PROFILE) || $(HAIKU_BUILD_PROFILE) != $(name) {
return ;
}
HAIKU_BUILD_PROFILE_DEFINED = 1 ;
# split path into directory path and name
local targetDir = $(path:D) ;
local targetName = $(path:BS) ;
# Jam's path splitting produces an empty string, if a component doesn't
# exist. That's a little unhandy for checks.
if $(targetDir) = "" {
targetDir = ;
}
if $(targetName) = "" {
targetName = ;
}
targetDir ?= $(HAIKU_IMAGE_DIR) ;
targetDir ?= $(HAIKU_DEFAULT_IMAGE_DIR) ;
# "disk" is "image" with HAIKU_DONT_CLEAR_IMAGE
if $(type) = "disk" {
type = "image" ;
HAIKU_DONT_CLEAR_IMAGE = 1 ;
}
local buildTarget ;
local startOffset ;
switch $(type) {
case "anyboot-image" : {
targetName ?= $(HAIKU_ANYBOOT_NAME) ;
targetName ?= $(HAIKU_DEFAULT_ANYBOOT_NAME) ;
HAIKU_ANYBOOT_DIR = $(targetDir) ;
HAIKU_ANYBOOT_NAME = $(targetName) ;
buildTarget = haiku-anyboot-image ;
}
case "cd-image" : {
targetName ?= $(HAIKU_CD_NAME) ;
targetName ?= $(HAIKU_DEFAULT_CD_NAME) ;
HAIKU_CD_DIR = $(targetDir) ;
HAIKU_CD_NAME = $(targetName) ;
buildTarget = haiku-cd ;
}
case "image" : {
targetName ?= $(HAIKU_IMAGE_NAME) ;
targetName ?= $(HAIKU_DEFAULT_IMAGE_NAME) ;
HAIKU_IMAGE_DIR = $(targetDir) ;
HAIKU_IMAGE_NAME = $(targetName) ;
buildTarget = haiku-image ;
}
case "haiku-mmc-image" : {
targetName ?= $(HAIKU_MMC_IMAGE_NAME) ;
targetName ?= $(HAIKU_DEFAULT_MMC_IMAGE_NAME) ;
HAIKU_IMAGE_DIR = $(targetDir) ;
HAIKU_IMAGE_NAME = $(targetName) ;
buildTarget = haiku-mmc-image ;
}
case "vmware-image" : {
targetName ?= $(HAIKU_VMWARE_IMAGE_NAME) ;
targetName ?= $(HAIKU_DEFAULT_VMWARE_IMAGE_NAME) ;
HAIKU_IMAGE_DIR = $(targetDir) ;
HAIKU_VMWARE_IMAGE_NAME = $(targetName) ;
buildTarget = haiku-vmware-image ;
startOffset = --start-offset 65536 ;
}
case "install" : {
path ?= $(HAIKU_INSTALL_DIR) ;
path ?= $(HAIKU_DEFAULT_INSTALL_DIR) ;
HAIKU_INSTALL_DIR = $(path) ;
buildTarget = install-haiku ;
}
case "custom" : {
# user-defined -- don't do anything
return 1 ;
}
case * : {
Exit "Unsupported build profile type: " $(type) ;
}
}
switch $(HAIKU_BUILD_PROFILE_ACTION) {
case "build" : {
# If parameters are specified, only build those targets (under the
# influence of the build profile).
if $(HAIKU_BUILD_PROFILE_PARAMETERS) {
JAM_TARGETS = $(HAIKU_BUILD_PROFILE_PARAMETERS) ;
} else {
JAM_TARGETS = $(buildTarget) ;
}
}
case "update" : {
JAM_TARGETS = $(buildTarget) ;
SetUpdateHaikuImageOnly 1 ;
HAIKU_PACKAGES_UPDATE_ONLY = 1 ;
HAIKU_INCLUDE_IN_IMAGE on $(HAIKU_BUILD_PROFILE_PARAMETERS) = 1 ;
HAIKU_INCLUDE_IN_PACKAGES on $(HAIKU_BUILD_PROFILE_PARAMETERS) = 1 ;
}
case "update-all" : {
JAM_TARGETS = $(buildTarget) ;
SetUpdateHaikuImageOnly 1 ;
HAIKU_INCLUDE_IN_IMAGE = 1 ;
HAIKU_UPDATE_ALL_PACKAGES = 1 ;
}
case "update-packages" : {
JAM_TARGETS = $(buildTarget) ;
SetUpdateHaikuImageOnly 1 ;
HAIKU_UPDATE_ALL_PACKAGES = 1 ;
}
case "build-package-list" : {
HAIKU_IMAGE_LIST_PACKAGES_TARGET
= $(HAIKU_BUILD_PROFILE_PARAMETERS[1]) ;
HAIKU_IMAGE_ADDITIONAL_PACKAGES
= $(HAIKU_BUILD_PROFILE_PARAMETERS[2-]) ;
JAM_TARGETS = $(HAIKU_IMAGE_LIST_PACKAGES_TARGET) ;
}
case "mount" : {
if $(type) in "install" "cd-image" {
Exit "Build action \"mount\" not supported for profile type"
"\"$(type)\"." ;
}
local commandLine = :<build>bfs_shell $(startOffset)
\"$(targetName:D=$(targetDir))\" ;
JAM_TARGETS = [ RunCommandLine $(commandLine) ] ;
}
}
return 1 ;
}