4 SEARCH on $(2) += $(SEARCH_SOURCE) ;
5 Depends $(1) : <build>copyattr $(2) ;
6 Copy1 $(1) : <build>copyattr $(2) ;
13 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
14 "$(2[1])" -d "$(2[2-])" "$(1)"
20 # SymLink <target> : <source> : <makeDefaultDependencies> ;
21 # Links <target> to <source>.
22 # <source> is the exact link contents. No binding is done.
23 # <makeDefaultDependencies> If true, <target> will be made a dependency
24 # of the `all' pseudo target, i.e. it will be made by default, and removed
29 local makeDefaultDependencies = $(3) ;
30 if ! $(makeDefaultDependencies) {
31 makeDefaultDependencies = true ;
33 LINKCONTENTS on $(target) = $(source) ;
35 if $(makeDefaultDependencies) = true {
36 LocalDepends files : $(target) ;
37 LocalClean clean : $(target) ;
43 $(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)"
48 # RelSymLink <link> : <link target> : <makeDefaultDependencies> ;
49 # Creates a relative symbolic link from <link> to <link target>.
50 # <link> and <link target> can be usual targets. They may have a grist
51 # and don't need to have any dirname. Their LOCATE variables are used to
52 # find their locations.
53 # <makeDefaultDependencies> If true (which is the default), <link> will be
54 # made a dependency of the `files' pseudo target, i.e. it will be made by
55 # default, and removed on `jam clean'.
59 local makeDefaultDependencies = $(3) ;
60 local targetDir = [ on $(target) FDirName $(LOCATE[1]) $(target:D) ] ;
61 local sourceDir = [ on $(source) FDirName $(LOCATE[1]) $(source:D) ] ;
62 local sourcePath = $(source:G=) ;
63 sourcePath = $(sourcePath:D=$(sourceDir)) ;
64 local targetDirComponents = [ FSplitPath $(targetDir) ] ;
65 local sourceComponents = [ FSplitPath $(sourcePath) ] ;
68 : [ FRelPath $(targetDirComponents) : $(sourceComponents) ]
69 : $(makeDefaultDependencies) ;
71 Depends $(target) : $(source) ;
76 # AbsSymLink <link> : <link target> : <link dir>
77 # : <makeDefaultDependencies> ;
78 # Creates an absolute symbolic link from <link> to <link target>.
79 # <link> and <link target> must be usual targets. If <link dir> is
80 # given, then it is set as LOCATE directory on <link>.
81 # <makeDefaultDependencies> If true (which is the default), <link> will be
82 # made a dependency of the `files' pseudo target, i.e. it will be made by
83 # default, and removed on `jam clean'.
85 local makeDefaultDependencies = $(4) ;
86 if ! $(makeDefaultDependencies) {
87 makeDefaultDependencies = true ;
92 MakeLocate $(1) : $(3) ;
94 SEARCH on $(2) += $(SEARCH_SOURCE) ;
95 if $(makeDefaultDependencies) = true {
96 LocalDepends files : $(1) ;
97 LocalClean clean : $(1) ;
106 *) target=`pwd`/"$target";;
108 $(RM) "$(1)" && $(LN) -s "$target" "$(1)"
111 rule HaikuInstall installAndUninstall : dir : sources : installgrist
112 : installRule : targets
114 # Usage: HaikuInstall <[ install [ and uninstall ] pseudotarget ]>
115 # : <directory> : <sources to install> : [ <installgrist> ]
116 # : [ <install rule> ] : [ <targets> ] ;
118 local install = $(installAndUninstall[1]) ;
120 local uninstall = $(installAndUninstall[2]) ;
121 uninstall ?= un$(install) ;
122 installgrist ?= $(INSTALLGRIST) ;
123 installRule ?= Install ;
125 targets ?= $(sources) ;
126 targets = $(targets:G=$(installgrist)) ;
129 NotFile $(uninstall) ;
130 Depends $(install) : $(targets) ;
131 Clean $(uninstall) : $(targets) ;
133 SEARCH on $(sources) += $(SEARCH_SOURCE) ;
134 MakeLocate $(targets) : $(dir) ;
137 for source in $(sources) {
138 local target = $(targets[1]) ;
139 targets = $(targets[2-]) ;
141 Depends $(target) : $(source) ;
142 $(installRule) $(target) : $(source) ;
144 if [ on $(target) return $(MODE) ] {
148 if $(OWNER) && $(CHOWN) {
150 OWNER on $(target) = $(OWNER) ;
153 if $(GROUP) && $(CHGRP) {
155 GROUP on $(target) = $(GROUP) ;
160 rule InstallAbsSymLinkAdapter
162 # InstallAbsSymLinkAdapter <link> : <link target>
163 if ! [ on $(2) return $(TARGET) ] {
164 TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
166 AbsSymLink $(1) : $(2) : : false ;
169 rule HaikuInstallAbsSymLink
171 # Usage: HaikuInstallAbsSymLink <[ install [ and uninstall ] pseudotarget ]>
172 # : <directory> : <sources to install>
173 # : [ <installgrist> ] ;
174 HaikuInstall $(1) : $(2) : $(3) : $(4) : InstallAbsSymLinkAdapter ;
177 rule InstallRelSymLinkAdapter
179 # InstallRelSymLinkAdapter <link> : <link target>
180 if ! [ on $(2) return $(TARGET) ] {
181 TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
183 RelSymLink $(1) : $(2) : false ;
186 rule HaikuInstallRelSymLink
188 # Usage: HaikuInstallRelSymLink <[ install [ and uninstall ] pseudotarget ]>
189 # : <directory> : <sources to install>
190 # : [ <installgrist> ] ;
191 HaikuInstall $(1) : $(2) : $(3) : $(4) : InstallRelSymLinkAdapter ;
195 rule UnarchiveObjects
197 # UnarchiveObjects <target objects> : <static object>
199 MakeLocateArch $(1) ;
200 Depends $(1) : $(2) ;
201 SEARCH on $(2) = $(SEARCH_SOURCE) ;
204 actions UnarchiveObjects
206 ( cd $(1[1]:D) && $(TARGET_AR_$(TARGET_PACKAGING_ARCH)) \
207 $(TARGET_UNARFLAGS_$(TARGET_PACKAGING_ARCH)) "$(2)" $(1:BS) )
211 rule ExtractArchive directory : entries : archiveFile : grist
213 # ExtractArchive <directory> : <entries> : <archiveFile> [ : <grist> ]
215 # Extract the archive file target <archiveFile> to directory <directory>.
216 # The rule can be called multiple times for different <entries> for the same
217 # <directory> and <archiveFile> combo.
219 # <directory> - The directory into which to extract the archive file. The
220 # directory is created by this rule and it is the target
221 # that the extract action is associated with.
222 # <entries> - The entries of the archive file one is interested in. The
223 # rule always extracts the complete archive file, from the
224 # given entries the rule creates targets (using <grist>)
225 # representing the extracted entries. Those targets are
226 # returned by the rule.
227 # <archiveFile> - The archive file target to extract.
228 # <grist> - The grist used to create targets from <entries>. Defaults to
233 # Turn the entries into targets to build.
236 for entry in $(entries) {
237 local target = $(entry:G=$(grist)) ;
238 targets += $(target) ;
241 LOCATE on $(targets) = $(directory:G=) ;
242 Depends $(targets) : $(directory) $(archiveFile) ;
243 NoUpdate $(targets) ;
245 # one-time initialization for the main target (the directory)
246 if ! [ on $(directory) return $(INITIALIZED) ] {
247 # make sure the parent dir exists
248 local parentDir = $(directory:PG=dir) ;
249 Depends $(directory) : $(parentDir) ;
252 NoUpdate $(directory) ;
253 Depends $(directory) : $(archiveFile) ;
254 switch $(archiveFile:S)
257 ExtractZipArchive1 $(directory) : $(archiveFile) ;
260 ExtractTarArchive1 $(directory) : $(archiveFile) ;
263 Depends $(directory) : <build>package ;
264 ExtractHPKGArchive1 $(directory)
265 : <build>package $(archiveFile) ;
268 Exit "ExtractArchive: No archive passed" ;
271 Exit "ExtractArchive: Unhandled archive extension:"
274 INITIALIZED on $(directory) = 1 ;
281 actions ExtractZipArchive1
284 unzip -q -u -o -d $(1) $(2)
288 actions ExtractTarArchive1
295 actions ExtractHPKGArchive1
298 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
299 $(2[1]) extract -C "$(1)" "$(2[2])"
305 # ObjectReference <reference object> : <source object>
306 # Makes <reference object> refer to the same file as <source object>.
307 # The filenames must of course be identical.
308 # <source object> must have already been LOCATEd.
311 local source = $(2) ;
312 if $(ref) != $(source) {
313 Depends $(ref) : $(source) ;
314 LOCATE on $(ref) = [ on $(source) return $(LOCATE) ] ;
318 rule ObjectReferences
320 # ObjectReferences <source objects>
321 # Creates local references to <source objects>, i.e. identifiers with the
322 # current grist referring to the same files. <source objects> must have
323 # already been LOCATEd.
327 ObjectReference [ FGristFiles $(source) ] : $(source) ;
332 rule CopySetHaikuRevision target : source
334 # CopySetHaikuRevision <target> : <source>
336 # Copy <source> to <target>, writing the Git revision of the working
337 # directory into the haiku revision section of <target>.
339 # <target> - Output file target. Gristed and located target.
340 # <source> - ELF object to be copied. Gristed and located target.
342 PropagateContainerUpdateTargetFlags $(target) : $(source) ;
344 HAIKU_TARGET_IS_EXECUTABLE on $(target) = [ on $(source)
345 return $(HAIKU_TARGET_IS_EXECUTABLE) ] ;
347 local revisionFile = [ DetermineHaikuRevision ] ;
350 : <build>copyattr <build>set_haiku_revision $(source) $(revisionFile) ;
351 CopySetHaikuRevision1 $(target)
352 : <build>copyattr <build>set_haiku_revision $(source) $(revisionFile) ;
356 actions CopySetHaikuRevision1
358 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
360 $(2[1]) --data $(2[3]) $(1) || exit 1
363 if [ -n "$(2[4]:E=)" ]; then
364 revision="`cat $(2[4]:E=)`"
366 $(2[2]) $(1) "$revision"
370 rule DetermineHaikuRevision
372 # If existing, make the target depend on the .git/index file in the
373 # root directory, so it gets updated when the revision changes due to
375 local gitIndex = <haiku-rootdir-git>index ;
376 local revisionFile = <haiku-rootdir>haiku-revision ;
377 if ! [ on $(gitIndex) return $(HAIKU_GIT_REVISION_DETERMINED) ] {
378 HAIKU_GIT_REVISION_DETERMINED on $(gitIndex) = 1 ;
379 MakeLocate $(revisionFile) : $(HAIKU_BUILD_OUTPUT_DIR) ;
380 LocalClean clean : $(revisionFile) ;
381 if $(HAIKU_REVISION) {
382 DetermineHaikuRevision2 $(revisionFile) ;
383 } else if [ Glob [ FDirName $(HAIKU_TOP) .git ] : index ] {
384 SEARCH on $(gitIndex) = [ FDirName $(HAIKU_TOP) .git ] ;
385 Depends $(revisionFile) : $(gitIndex) ;
386 DetermineHaikuRevision1 $(revisionFile) : $(gitIndex) ;
392 return $(revisionFile) ;
396 actions DetermineHaikuRevision1
398 $(HAIKU_TOP)/build/scripts/determine_haiku_revision $(HAIKU_TOP) $(1)
402 actions DetermineHaikuRevision2
404 echo $(HAIKU_REVISION) > $(1)
408 rule DetermineEffectiveHaikuRevision
410 local revisionFile = <haiku-rootdir>effective-haiku-revision ;
411 if ! [ on $(revisionFile) return $(HAIKU_EFFECTIVE_REVISION_DETERMINED) ] {
412 HAIKU_EFFECTIVE_REVISION_DETERMINED on $(revisionFile) = 1 ;
413 MakeLocate $(revisionFile) : $(HAIKU_BUILD_OUTPUT_DIR) ;
414 local rawRevision = [ DetermineHaikuRevision ] ;
415 Depends $(revisionFile) : $(rawRevision) ;
416 DetermineEffectiveHaikuRevision1 $(revisionFile) : $(rawRevision) ;
417 LocalClean clean : $(revisionFile) ;
420 return $(revisionFile) ;
424 actions DetermineEffectiveHaikuRevision1
426 revision=`sed -n 's,^\(hrev[0-9]*\).*,\1,p' "$(2:E=unknown-revision)"`
427 if [ -z "$revision" ]; then
428 echo "Error: unable to determine the effective Haiku revision."
429 echo " If you are using a Haiku clone without tags, you can set"
430 echo " the revision tag to use with e.g. HAIKU_REVISION=hrev43210"
433 echo "${revision:-0}" > "$(1)"
437 rule DataFileToSourceFile sourceFile : dataFile : dataVariable : sizeVariable
439 sourceFile = [ FGristFiles $(sourceFile) ] ;
440 MakeLocateCommonPlatform $(sourceFile) ;
442 sizeVariable ?= $(dataVariable)Size ;
444 DATA_VARIABLE on $(sourceFile) = $(dataVariable) ;
445 SIZE_VARIABLE on $(sourceFile) = $(sizeVariable) ;
447 Depends $(sourceFile) : <build>data_to_source $(dataFile) ;
448 DataFileToSourceFile1 $(sourceFile) : <build>data_to_source $(dataFile) ;
449 LocalClean clean : $(sourceFile) ;
452 actions DataFileToSourceFile1
454 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
455 $(2[1]) $(DATA_VARIABLE) $(SIZE_VARIABLE) $(2[2]) $(1)
458 rule DownloadLocatedFile target : url : source
460 # DownloadLocatedFile <target> : <url> [ : <source> ] ;
462 # <source> is an optional target that <target> will be made dependent on.
463 # Its resolved path can be used in <url> via '$source'.
465 URL on $(target) = $(url) ;
468 Depends $(target) : $(source) ;
471 DownloadLocatedFile1 $(target) : $(source) ;
474 actions DownloadLocatedFile1
477 if [ "$(HAIKU_NO_DOWNLOADS)" = 1 ]; then
478 echo "ERROR: Would need to download $(URL), but HAIKU_NO_DOWNLOADS is set!"
481 wget --retry-connrefused --timeout 30 -O "$(1)" $(URL) || exit 1
485 rule DownloadFile file : url : source
487 # DownloadFile <file> : <url> [ : <source> ] ;
489 # <source> is an optional target that the target will be made dependent on.
490 # Its resolved path can be used in <url> via '$source'.
492 file = $(file:G=download) ;
494 # Request the download only once.
495 if [ on $(file) return $(HAIKU_FILE_DOWNLOAD) ] {
499 HAIKU_FILE_DOWNLOAD on $(file) = 1 ;
501 MakeLocate $(file) : $(HAIKU_DOWNLOAD_DIR) ;
502 DownloadLocatedFile $(file) : $(url) : $(source) ;
508 actions ChecksumFileSHA256
510 $(HOST_SHA256) $(2) \
511 | $(HOST_EXTENDED_REGEX_SED) 's,([^[:space:]]*).*,\1,' > $(1)
512 # The sed part is only necessary for sha256sum, but it doesn't harm for
517 rule Sed target : source : substitutions : targetMap
519 # Sed <target> : [ <source> ] : <substitutions> [ : <targetMap> ] ;
521 # Performs substitutions in a text file. If <source> is given, that is the
522 # input, otherwise the substitutions are performed in place on <target>. The
523 # caller is responsible for locating <target>, <source>, and any other used
526 # <target> - The target file.
527 # <source> - The source file. If not given, the substitutions are performed
528 # in place on <target>. If given, a dependency of <target> to <source>
529 # will be established.
530 # <substitutions> - List of substitutions to be performed. Each element
531 # specifies a substitution. It's a partial sed "s" command of the form
532 # "<pattern>,<replacement>".
533 # <targetMap> - A list of elements of the form "<variable>=<mappedTarget>".
534 # <variable> specifies a name of a shell variable, <mappedTarget> a jam
535 # target whose bound name will be assigned to the shell variable. The
536 # variable can be used in <substitutions>. A dependency of <target> to
537 # <mappedTarget> will be established.
539 # We need a temporary (shell) file to which we write the target variable
540 # mappings and the sed invocations. This is necessary, since multiple rule
541 # invocations are allowed for a target, so that we cannot use on-target
543 local script = [ NextID ] ;
544 script = temp-sed-script-$(target:BS)-$(script) ;
546 # process the target variable mappings
547 local mappedTargets ;
548 local targetMapElement ;
549 for targetMapElement in $(targetMap) {
550 local split = [ Match ([^=]+)=(.*) : $(targetMapElement) ] ;
551 HAIKU_SED_SCRIPT_VARIABLE on $(script) += $(split[1]) ;
552 local mappedTarget = $(split[2]) ;
553 mappedTargets += $(mappedTarget) ;
556 HAIKU_SED_SCRIPT_SUBSTITUTIONS on $(script)
557 = "-e \"s,$(substitutions),g\"" ;
558 HAIKU_SED_SCRIPT_SOURCE on $(script) = $(source) ;
560 HAIKU_SED_SCRIPT_SOURCE_ARGUMENTS on $(script) = ">" ;
562 HAIKU_SED_SCRIPT_SOURCE_ARGUMENTS on $(script) = -i ;
566 MakeLocate $(script) : $(HAIKU_TMP_DIR) ;
567 Depends $(script) : $(mappedTargets) $(source) ;
568 SedCreateScript $(script) : $(mappedTargets) ;
571 Depends $(target) : $(script) ;
572 Sed1 $(target) : $(script) ;
573 RmTemps $(target) : $(script) ;
577 actions SedCreateScript bind HAIKU_SED_SCRIPT_SOURCE
585 for variable in "$(HAIKU_SED_SCRIPT_VARIABLE)" ; do
586 echo "$variable=\"$1\"" >> "$(1)"
590 echo sed '$(HAIKU_SED_SCRIPT_SUBSTITUTIONS)' \
591 '"$(HAIKU_SED_SCRIPT_SOURCE)"' "$(HAIKU_SED_SCRIPT_SOURCE_ARGUMENTS)" \
592 '"$target"' >> "$(1)"
605 rule StripFile target : source
607 # Note: The caller is reponsible for matching TARGET_PACKAGING_ARCH with
608 # the architecture the target was built for.
609 STRIP on $(target) = $(HAIKU_STRIP_$(TARGET_PACKAGING_ARCH)) ;
611 PropagateContainerUpdateTargetFlags $(target) : $(source) ;
613 LocalClean clean : $(target) ;
614 Depends $(target) : $(source) <build>xres <build>copyattr ;
615 StripFile1 $(target) : $(source) <build>xres <build>copyattr ;
621 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
622 "$(STRIP)" -o "$(1)" "$(2[1])"
623 "$(2[2])" -o "$(1)" "$(2[1])"
624 "$(2[3])" "$(2[1])" "$(1)"
628 rule StripFiles files
630 # Note: The caller is reponsible for matching TARGET_PACKAGING_ARCH with
631 # the architecture the targets were built for.
632 local strippedFiles ;
634 for file in $(files) {
635 local strippedFile = $(file:G=stripped_$(file:G)) ;
636 # Place the stripped file in a "stripped" subdirectory of the file's
638 local location = [ on $(file) return $(LOCATE) ] ;
641 = $(TARGET_COMMON_DEBUG_OBJECT_DIR_$(TARGET_PACKAGING_ARCH)) ;
643 MakeLocateArch $(strippedFile) : [ FDirName $(location) stripped ] ;
644 StripFile $(strippedFile) : $(file) ;
645 strippedFiles += $(strippedFile) ;
648 return $(strippedFiles) ;