haiku/build/jam/FileRules
Ingo Weinhold b0944c78b0 More work towards hybrid support
* All packaging architecture dependent variables do now have a
  respective suffix and are set up for each configured packaging
  architecture, save for the kernel and boot loader variables, which
  are still only set up for the primary architecture.
  For convenience TARGET_PACKAGING_ARCH, TARGET_ARCH, TARGET_LIBSUPC++,
  and TARGET_LIBSTDC++ are set to the respective values for the primary
  packaging architecture by default.
* Introduce a set of MultiArch* rules to help with building targets for
  multiple packaging architectures. Generally the respective targets are
  (additionally) gristed with the packaging architecture. For libraries
  the additional grist is usually omitted for the primary architecture
  (e.g. libroot.so and <x86>libroot.so for x86_gcc2/x86 hybrid), so that
  Jamfiles for targets built only for the primary architecture don't
  need to be changed.
* Add multi-arch build support for all targets needed for the stage 1
  cross devel package as well as for libbe (untested).
2013-08-01 08:54:06 +02:00

449 lines
12 KiB
Plaintext

rule Copy
{
if $(2) {
SEARCH on $(2) += $(SEARCH_SOURCE) ;
Depends $(1) : <build>copyattr $(2) ;
Copy1 $(1) : <build>copyattr $(2) ;
}
}
actions Copy1
{
$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
"$(2[1])" -d "$(2[2-])" "$(1)"
}
rule SymLink
{
# SymLink <target> : <source> : <makeDefaultDependencies> ;
# Links <target> to <source>.
# <source> is the exact link contents. No binding is done.
# <makeDefaultDependencies> If true, <target> will be made a dependency
# of the `all' pseudo target, i.e. it will be made by default, and removed
# on `jam clean'.
local target = $(1) ;
local source = $(2) ;
local makeDefaultDependencies = $(3) ;
if ! $(makeDefaultDependencies) {
makeDefaultDependencies = true ;
}
LINKCONTENTS on $(target) = $(source) ;
SymLink1 $(target) ;
if $(makeDefaultDependencies) = true {
LocalDepends files : $(target) ;
LocalClean clean : $(target) ;
}
}
actions SymLink1
{
$(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)"
}
rule RelSymLink
{
# RelSymLink <link> : <link target> : <makeDefaultDependencies> ;
# Creates a relative symbolic link from <link> to <link target>.
# <link> and <link target> can be usual targets. They may have a grist
# and don't need to have any dirname. Their LOCATE variables are used to
# find their locations.
# <makeDefaultDependencies> If true (which is the default), <link> will be
# made a dependency of the `files' pseudo target, i.e. it will be made by
# default, and removed on `jam clean'.
local target = $(1) ;
local source = $(2) ;
local makeDefaultDependencies = $(3) ;
local targetDir = [ on $(target) FDirName $(LOCATE[1]) $(target:D) ] ;
local sourceDir = [ on $(source) FDirName $(LOCATE[1]) $(source:D) ] ;
local sourcePath = $(source:G=) ;
sourcePath = $(sourcePath:D=$(sourceDir)) ;
local targetDirComponents = [ FSplitPath $(targetDir) ] ;
local sourceComponents = [ FSplitPath $(sourcePath) ] ;
SymLink $(target)
: [ FRelPath $(targetDirComponents) : $(sourceComponents) ]
: $(makeDefaultDependencies) ;
NOUPDATE $(target) ;
Depends $(target) : $(source) ;
}
rule AbsSymLink
{
# AbsSymLink <link> : <link target> : <link dir>
# : <makeDefaultDependencies> ;
# Creates an absolute symbolic link from <link> to <link target>.
# <link> and <link target> must be usual targets. If <link dir> is
# given, then it is set as LOCATE directory on <link>.
# <makeDefaultDependencies> If true (which is the default), <link> will be
# made a dependency of the `files' pseudo target, i.e. it will be made by
# default, and removed on `jam clean'.
local makeDefaultDependencies = $(4) ;
if ! $(makeDefaultDependencies) {
makeDefaultDependencies = true ;
}
Depends $(1) : $(2) ;
if $(3) {
MakeLocate $(1) : $(3) ;
}
SEARCH on $(2) += $(SEARCH_SOURCE) ;
if $(makeDefaultDependencies) = true {
LocalDepends files : $(1) ;
LocalClean clean : $(1) ;
}
}
actions AbsSymLink
{
target="$(2)"
case "$target" in
/*) ;;
*) target=`pwd`/"$target";;
esac
$(RM) "$(1)" && $(LN) -s "$target" "$(1)"
}
rule HaikuInstall installAndUninstall : dir : sources : installgrist
: installRule : targets
{
# Usage: HaikuInstall <[ install [ and uninstall ] pseudotarget ]>
# : <directory> : <sources to install> : [ <installgrist> ]
# : [ <install rule> ] : [ <targets> ] ;
local install = $(installAndUninstall[1]) ;
install ?= install ;
local uninstall = $(installAndUninstall[2]) ;
uninstall ?= un$(install) ;
installgrist ?= $(INSTALLGRIST) ;
installRule ?= Install ;
targets ?= $(sources) ;
targets = $(targets:G=$(installgrist)) ;
NotFile $(install) ;
NotFile $(uninstall) ;
Depends $(install) : $(targets) ;
Clean $(uninstall) : $(targets) ;
SEARCH on $(sources) += $(SEARCH_SOURCE) ;
MakeLocate $(targets) : $(dir) ;
local source ;
for source in $(sources) {
local target = $(targets[1]) ;
targets = $(targets[2-]) ;
Depends $(target) : $(source) ;
$(installRule) $(target) : $(source) ;
if [ on $(target) return $(MODE) ] {
Chmod $(target) ;
}
if $(OWNER) && $(CHOWN) {
Chown $(target) ;
OWNER on $(target) = $(OWNER) ;
}
if $(GROUP) && $(CHGRP) {
Chgrp $(target) ;
GROUP on $(target) = $(GROUP) ;
}
}
}
rule InstallAbsSymLinkAdapter
{
# InstallAbsSymLinkAdapter <link> : <link target>
if ! [ on $(2) return $(TARGET) ] {
TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
}
AbsSymLink $(1) : $(2) : : false ;
}
rule HaikuInstallAbsSymLink
{
# Usage: HaikuInstallAbsSymLink <[ install [ and uninstall ] pseudotarget ]>
# : <directory> : <sources to install>
# : [ <installgrist> ] ;
HaikuInstall $(1) : $(2) : $(3) : $(4) : InstallAbsSymLinkAdapter ;
}
rule InstallRelSymLinkAdapter
{
# InstallRelSymLinkAdapter <link> : <link target>
if ! [ on $(2) return $(TARGET) ] {
TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
}
RelSymLink $(1) : $(2) : false ;
}
rule HaikuInstallRelSymLink
{
# Usage: HaikuInstallRelSymLink <[ install [ and uninstall ] pseudotarget ]>
# : <directory> : <sources to install>
# : [ <installgrist> ] ;
HaikuInstall $(1) : $(2) : $(3) : $(4) : InstallRelSymLinkAdapter ;
}
rule UnarchiveObjects
{
# UnarchiveObjects <target objects> : <static object>
MakeLocateArch $(1) ;
Depends $(1) : $(2) ;
SEARCH on $(2) = $(SEARCH_SOURCE) ;
}
actions UnarchiveObjects
{
( cd $(1[1]:D) && $(TARGET_AR_$(TARGET_PACKAGING_ARCH)) \
$(TARGET_UNARFLAGS_$(TARGET_PACKAGING_ARCH)) "$(2)" $(1:BS) )
}
rule ExtractArchive directory : entries : archiveFile : grist
{
# ExtractArchive <directory> : <entries> : <archiveFile> [ : <grist> ]
#
# Extract the archive file target <archiveFile> to directory <directory>.
# The rule can be called multiple times for different <entries> for the same
# <directory> and <archiveFile> combo.
#
# <directory> - The directory into which to extract the archive file. The
# directory is created by this rule and it is the target
# that the extract action is associated with.
# <entries> - The entries of the archive file one is interested in. The
# rule always extracts the complete archive file, from the
# given entries the rule creates targets (using <grist>)
# representing the extracted entries. Those targets are
# returned by the rule.
# <archiveFile> - The archive file target to extract.
# <grist> - The grist used to create targets from <entries>. Defaults to
# "extracted".
grist ?= extracted ;
# Turn the entries into targets to build.
local targets ;
local entry ;
for entry in $(entries) {
local target = $(entry:G=$(grist)) ;
targets += $(target) ;
}
LOCATE on $(targets) = $(directory:G=) ;
Depends $(targets) : $(directory) $(archiveFile) ;
NoUpdate $(targets) ;
# one-time initialization for the main target (the directory)
if ! [ on $(directory) return $(INITIALIZED) ] {
# make sure the parent dir exists
local parentDir = $(directory:PG=dir) ;
Depends $(directory) : $(parentDir) ;
MkDir $(parentDir) ;
NoUpdate $(directory) ;
Depends $(directory) : $(archiveFile) ;
switch $(archiveFile:S)
{
case .zip :
ExtractZipArchive1 $(directory) : $(archiveFile) ;
case .tgz :
ExtractTarArchive1 $(directory) : $(archiveFile) ;
case .hpkg :
Depends $(directory) : <build>package ;
ExtractHPKGArchive1 $(directory)
: <build>package $(archiveFile) ;
case "" :
Exit "ExtractArchive: No archive passed" ;
case * :
Exit "ExtractArchive: Unhandled archive extension:"
"$(archiveFile:S)" ;
}
INITIALIZED on $(directory) = 1 ;
}
return $(targets) ;
}
actions ExtractZipArchive1
{
mkdir -p $(1)
unzip -q -u -o -d $(1) $(2)
}
actions ExtractTarArchive1
{
mkdir -p $(1)
tar -C $(1) -xf $(2)
}
actions ExtractHPKGArchive1
{
mkdir -p "$(1)"
$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
$(2[1]) extract -C "$(1)" "$(2[2])"
}
rule ObjectReference
{
# ObjectReference <reference object> : <source object>
# Makes <reference object> refer to the same file as <source object>.
# The filenames must of course be identical.
# <source object> must have already been LOCATEd.
local ref = $(1) ;
local source = $(2) ;
if $(ref) != $(source) {
Depends $(ref) : $(source) ;
LOCATE on $(ref) = [ on $(source) return $(LOCATE) ] ;
}
}
rule ObjectReferences
{
# ObjectReferences <source objects>
# Creates local references to <source objects>, i.e. identifiers with the
# current grist referring to the same files. <source objects> must have
# already been LOCATEd.
local source ;
for source in $(1) {
ObjectReference [ FGristFiles $(source) ] : $(source) ;
}
}
rule CopySetHaikuRevision target : source
{
# CopySetHaikuRevision <target> : <source>
#
# Copy <source> to <target>, writing the SVN revision of the working root
# directory into the haiku revision section of <target>.
#
# <target> - Output file target. Gristed and located target.
# <source> - ELF object to be copied. Gristed and located target.
# If existent, make the target depend on the .svn/entries file in the
# root directory, so it gets updated when the revision changes due to
# "svn up".
if [ Glob [ FDirName $(HAIKU_TOP) .svn ] : entries ] {
local svnEntries = <haiku-rootdir-svn>entries ;
SEARCH on $(svnEntries) = [ FDirName $(HAIKU_TOP) .svn ] ;
Depends $(target) : $(svnEntries) ;
} else if [ Glob [ FDirName $(HAIKU_TOP) .git ] : index ] {
local gitIndex = <haiku-rootdir-git>index ;
SEARCH on $(gitIndex) = [ FDirName $(HAIKU_TOP) .git ] ;
Depends $(target) : $(gitIndex) ;
} else if [ Glob [ FDirName $(HAIKU_TOP) .hg ] : store ] {
local hgStore = <haiku-rootdir-hg>store ;
SEARCH on $(hgStore) = [ FDirName $(HAIKU_TOP) .hg ] ;
Depends $(target) : $(hgStore) ;
}
PropagateContainerUpdateTargetFlags $(target) : $(source) ;
Depends $(target) : <build>copyattr <build>set_haiku_revision $(source) ;
CopySetHaikuRevision1 $(target)
: <build>copyattr <build>set_haiku_revision $(source) ;
}
actions CopySetHaikuRevision1
{
$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
. $(HAIKU_TOP)/build/scripts/determine_haiku_revision
determineHaikuRevision $(HAIKU_TOP) $(HAIKU_BUILD_OUTPUT_DIR)
$(2[1]) --data $(2[3]) $(1) &&
$(2[2]) $(1) ${revision}
}
rule DataFileToSourceFile sourceFile : dataFile : dataVariable : sizeVariable
{
sourceFile = [ FGristFiles $(sourceFile) ] ;
MakeLocateCommonPlatform $(sourceFile) ;
sizeVariable ?= $(dataVariable)Size ;
DATA_VARIABLE on $(sourceFile) = $(dataVariable) ;
SIZE_VARIABLE on $(sourceFile) = $(sizeVariable) ;
Depends $(sourceFile) : <build>data_to_source $(dataFile) ;
DataFileToSourceFile1 $(sourceFile) : <build>data_to_source $(dataFile) ;
LocalClean clean : $(sourceFile) ;
}
actions DataFileToSourceFile1
{
$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
$(2[1]) $(DATA_VARIABLE) $(SIZE_VARIABLE) $(2[2]) $(1)
}
rule DownloadLocatedFile target : url : source
{
# DownloadLocatedFile <target> : <url> [ : <source> ] ;
#
# <source> is an optional target that <target> will be made dependent on.
# Its resolved path can be used in <url> via '$source'.
URL on $(target) = $(url) ;
if $(source) {
Depends $(target) : $(source) ;
}
DownloadLocatedFile1 $(target) : $(source) ;
}
actions DownloadLocatedFile1
{
source="$(2)"
wget -O "$(1)" $(URL)
touch "$(1)"
}
rule DownloadFile file : url : source
{
# DownloadFile <file> : <url> [ : <source> ] ;
#
# <source> is an optional target that the target will be made dependent on.
# Its resolved path can be used in <url> via '$source'.
file = $(file:G=download) ;
# Request the download only once.
if [ on $(file) return $(HAIKU_FILE_DOWNLOAD) ] {
return $(file) ;
}
HAIKU_FILE_DOWNLOAD on $(file) = 1 ;
MakeLocate $(file) : $(HAIKU_DOWNLOAD_DIR) ;
DownloadLocatedFile $(file) : $(url) : $(source) ;
return $(file) ;
}
actions ChecksumFileSHA256
{
$(HOST_SHA256) $(2) | sed -r 's,([^[:space:]]*).*,\1,' > $(1)
# The sed part is only necessary for sha256sum, but it doesn't harm for
# sha256 either.
}