vfs: check userland buffers before reading them.
[haiku.git] / build / jam / FileRules
blobb0d6d7369d441cc9cd7e19f9f769985c7bcaae4b
1 rule Copy
3         if $(2) {
4                 SEARCH on $(2) += $(SEARCH_SOURCE) ;
5                 Depends $(1) : <build>copyattr $(2) ;
6                 Copy1 $(1) : <build>copyattr $(2) ;
7         }
11 actions Copy1
13         $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
14         "$(2[1])" -d "$(2[2-])" "$(1)"
18 rule SymLink
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
25         # on `jam clean'.
27         local target = $(1) ;
28         local source = $(2) ;
29         local makeDefaultDependencies = $(3) ;
30         if ! $(makeDefaultDependencies) {
31                 makeDefaultDependencies = true ;
32         }
33         LINKCONTENTS on $(target) = $(source) ;
34         SymLink1 $(target) ;
35         if $(makeDefaultDependencies) = true {
36                 LocalDepends files : $(target) ;
37                 LocalClean clean : $(target) ;
38         }
41 actions SymLink1
43         $(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)"
46 rule RelSymLink
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'.
57         local target = $(1) ;
58         local source = $(2) ;
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) ] ;
67         SymLink $(target)
68                 : [ FRelPath $(targetDirComponents) : $(sourceComponents) ]
69                 : $(makeDefaultDependencies) ;
70         NOUPDATE $(target) ;
71         Depends $(target) : $(source) ;
74 rule AbsSymLink
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 ;
88         }
90         Depends $(1) : $(2) ;
91         if $(3) {
92                 MakeLocate $(1) : $(3) ;
93         }
94         SEARCH on $(2) += $(SEARCH_SOURCE) ;
95         if $(makeDefaultDependencies) = true {
96                 LocalDepends files : $(1) ;
97                 LocalClean clean : $(1) ;
98         }
101 actions AbsSymLink
103         target="$(2)"
104         case "$target" in
105                 /*) ;;
106                 *) target=`pwd`/"$target";;
107         esac
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]) ;
119         install ?= install ;
120         local uninstall = $(installAndUninstall[2]) ;
121         uninstall ?= un$(install) ;
122         installgrist ?= $(INSTALLGRIST) ;
123         installRule ?= Install ;
125         targets ?= $(sources) ;
126         targets = $(targets:G=$(installgrist)) ;
128         NotFile $(install) ;
129         NotFile $(uninstall) ;
130         Depends $(install) : $(targets) ;
131         Clean $(uninstall) : $(targets) ;
133         SEARCH on $(sources) += $(SEARCH_SOURCE) ;
134         MakeLocate $(targets) : $(dir) ;
136         local source ;
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) ] {
145                         Chmod $(target) ;
146                 }
148                 if $(OWNER) && $(CHOWN) {
149                         Chown $(target) ;
150                         OWNER on $(target) = $(OWNER) ;
151                 }
153                 if $(GROUP) && $(CHGRP) {
154                         Chgrp $(target) ;
155                         GROUP on $(target) = $(GROUP) ;
156                 }
157         }
160 rule InstallAbsSymLinkAdapter
162         # InstallAbsSymLinkAdapter <link> : <link target>
163         if ! [ on $(2) return $(TARGET) ] {
164                 TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
165         }
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) ] ;
182         }
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> ]
214         #
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.
218         #
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
229         #               "extracted".
231         grist ?= extracted ;
233         # Turn the entries into targets to build.
234         local targets ;
235         local entry ;
236         for entry in $(entries) {
237                 local target = $(entry:G=$(grist)) ;
238                 targets += $(target) ;
239         }
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) ;
250                 MkDir $(parentDir) ;
252                 NoUpdate $(directory) ;
253                 Depends $(directory) : $(archiveFile) ;
254                 switch $(archiveFile:S)
255                 {
256                         case .zip :
257                                 ExtractZipArchive1 $(directory) : $(archiveFile) ;
259                         case .tgz :
260                                 ExtractTarArchive1 $(directory) : $(archiveFile) ;
262                         case .hpkg :
263                                 Depends $(directory) : <build>package ;
264                                 ExtractHPKGArchive1 $(directory)
265                                         : <build>package $(archiveFile) ;
267                         case "" :
268                                 Exit "ExtractArchive: No archive passed" ;
270                         case * :
271                                 Exit "ExtractArchive: Unhandled archive extension:"
272                                         "$(archiveFile:S)" ;
273                 }
274                 INITIALIZED on $(directory) = 1 ;
275         }
277         return $(targets) ;
281 actions ExtractZipArchive1
283         mkdir -p $(1)
284         unzip -q -u -o -d $(1) $(2)
288 actions ExtractTarArchive1
290         mkdir -p $(1)
291         tar -C $(1) -xf $(2)
295 actions ExtractHPKGArchive1
297         mkdir -p "$(1)"
298         $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
299         $(2[1]) extract -C "$(1)" "$(2[2])"
303 rule ObjectReference
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.
310         local ref = $(1) ;
311         local source = $(2) ;
312         if $(ref) != $(source) {
313                 Depends $(ref) : $(source) ;
314                 LOCATE on $(ref) = [ on $(source) return $(LOCATE) ] ;
315         }
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.
325         local source ;
326         for source in $(1) {
327                 ObjectReference [ FGristFiles $(source) ] : $(source) ;
328         }
332 rule CopySetHaikuRevision target : source
334         # CopySetHaikuRevision <target> : <source>
335         #
336         # Copy <source> to <target>, writing the Git revision of the working
337         # directory into the haiku revision section of <target>.
338         #
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 ] ;
349         Depends $(target)
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
362         revision=0
363         if [ -n "$(2[4]:E=)" ]; then
364                 revision="`cat $(2[4]:E=)`"
365         fi
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
374         # commits or merges.
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) ;
387                 } else {
388                         revisionFile = ;
389                 }
390         }
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) ;
418         }
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"
431                 exit 1
432         fi
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> ] ;
461         #
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) ;
467         if $(source) {
468                 Depends $(target) : $(source) ;
469         }
471         DownloadLocatedFile1 $(target) : $(source) ;
474 actions DownloadLocatedFile1
476         source="$(2)"
477         if [ "$(HAIKU_NO_DOWNLOADS)" = 1 ]; then
478                 echo "ERROR: Would need to download $(URL), but HAIKU_NO_DOWNLOADS is set!"
479                 exit 1
480         fi
481         wget --retry-connrefused --timeout 30 -O "$(1)" $(URL) || exit 1
482         touch "$(1)"
485 rule DownloadFile file : url : source
487         # DownloadFile <file> : <url> [ : <source> ] ;
488         #
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) ] {
496                 return $(file) ;
497         }
499         HAIKU_FILE_DOWNLOAD on $(file) = 1 ;
501         MakeLocate $(file) : $(HAIKU_DOWNLOAD_DIR) ;
502         DownloadLocatedFile $(file) : $(url) : $(source) ;
504         return $(file) ;
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
513                 # sha256 either.
517 rule Sed target : source : substitutions : targetMap
519         # Sed <target> : [ <source> ] : <substitutions> [ : <targetMap> ] ;
520         #
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
524         # target.
525         #
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
542         # variables.
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) ;
554         }
556         HAIKU_SED_SCRIPT_SUBSTITUTIONS on $(script)
557                 = "-e \"s,$(substitutions),g\"" ;
558         HAIKU_SED_SCRIPT_SOURCE on $(script) = $(source) ;
559         if $(source) {
560                 HAIKU_SED_SCRIPT_SOURCE_ARGUMENTS on $(script) = ">" ;
561         } else {
562                 HAIKU_SED_SCRIPT_SOURCE_ARGUMENTS on $(script) = -i ;
563         }
565         # build the script
566         MakeLocate $(script) : $(HAIKU_TMP_DIR) ;
567         Depends $(script) : $(mappedTargets) $(source) ;
568         SedCreateScript $(script) : $(mappedTargets) ;
570         # build the target
571         Depends $(target) : $(script) ;
572         Sed1 $(target) : $(script) ;
573         RmTemps $(target) : $(script) ;
577 actions SedCreateScript bind HAIKU_SED_SCRIPT_SOURCE
579         set -o errexit
581         $(RM) "$(1)"
582         touch "$(1)"
584         set -- $(2)
585         for variable in "$(HAIKU_SED_SCRIPT_VARIABLE)" ; do
586                 echo "$variable=\"$1\"" >> "$(1)"
587                 shift
588         done
590         echo sed '$(HAIKU_SED_SCRIPT_SUBSTITUTIONS)' \
591                 '"$(HAIKU_SED_SCRIPT_SOURCE)"' "$(HAIKU_SED_SCRIPT_SOURCE_ARGUMENTS)" \
592                 '"$target"' >> "$(1)"
596 actions Sed1
598         set -o errexit
600         target="$(1)"
601         . "$(2)"
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 ;
619 actions StripFile1
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 ;
633         local file ;
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
637                 # location.
638                 local location = [ on $(file) return $(LOCATE) ] ;
639                 if ! $(location) {
640                         location
641                                 = $(TARGET_COMMON_DEBUG_OBJECT_DIR_$(TARGET_PACKAGING_ARCH)) ;
642                 }
643                 MakeLocateArch $(strippedFile) : [ FDirName $(location) stripped ] ;
644                 StripFile $(strippedFile) : $(file) ;
645                 strippedFiles += $(strippedFile) ;
646         }
648         return $(strippedFiles) ;