1rule Copy 2{ 3 if $(2) { 4 SEARCH on $(2) += $(SEARCH_SOURCE) ; 5 Depends $(1) : <build>copyattr $(2) ; 6 Copy1 $(1) : <build>copyattr $(2) ; 7 } 8} 9 10 11actions Copy1 12{ 13 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) 14 "$(2[1])" -d "$(2[2-])" "$(1)" 15} 16 17 18rule SymLink 19{ 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'. 26 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 } 39} 40 41actions SymLink1 42{ 43 $(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)" 44} 45 46rule RelSymLink 47{ 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'. 56 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) ] ; 66 67 SymLink $(target) 68 : [ FRelPath $(targetDirComponents) : $(sourceComponents) ] 69 : $(makeDefaultDependencies) ; 70 NOUPDATE $(target) ; 71 Depends $(target) : $(source) ; 72} 73 74rule AbsSymLink 75{ 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'. 84 85 local makeDefaultDependencies = $(4) ; 86 if ! $(makeDefaultDependencies) { 87 makeDefaultDependencies = true ; 88 } 89 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 } 99} 100 101actions AbsSymLink 102{ 103 target="$(2)" 104 case "$target" in 105 /*) ;; 106 *) target=`pwd`/"$target";; 107 esac 108 $(RM) "$(1)" && $(LN) -s "$target" "$(1)" 109} 110 111rule HaikuInstall installAndUninstall : dir : sources : installgrist 112 : installRule : targets 113{ 114 # Usage: HaikuInstall <[ install [ and uninstall ] pseudotarget ]> 115 # : <directory> : <sources to install> : [ <installgrist> ] 116 # : [ <install rule> ] : [ <targets> ] ; 117 118 local install = $(installAndUninstall[1]) ; 119 install ?= install ; 120 local uninstall = $(installAndUninstall[2]) ; 121 uninstall ?= un$(install) ; 122 installgrist ?= $(INSTALLGRIST) ; 123 installRule ?= Install ; 124 125 targets ?= $(sources) ; 126 targets = $(targets:G=$(installgrist)) ; 127 128 NotFile $(install) ; 129 NotFile $(uninstall) ; 130 Depends $(install) : $(targets) ; 131 Clean $(uninstall) : $(targets) ; 132 133 SEARCH on $(sources) += $(SEARCH_SOURCE) ; 134 MakeLocate $(targets) : $(dir) ; 135 136 local source ; 137 for source in $(sources) { 138 local target = $(targets[1]) ; 139 targets = $(targets[2-]) ; 140 141 Depends $(target) : $(source) ; 142 $(installRule) $(target) : $(source) ; 143 144 if [ on $(target) return $(MODE) ] { 145 Chmod $(target) ; 146 } 147 148 if $(OWNER) && $(CHOWN) { 149 Chown $(target) ; 150 OWNER on $(target) = $(OWNER) ; 151 } 152 153 if $(GROUP) && $(CHGRP) { 154 Chgrp $(target) ; 155 GROUP on $(target) = $(GROUP) ; 156 } 157 } 158} 159 160rule InstallAbsSymLinkAdapter 161{ 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 ; 167} 168 169rule HaikuInstallAbsSymLink 170{ 171 # Usage: HaikuInstallAbsSymLink <[ install [ and uninstall ] pseudotarget ]> 172 # : <directory> : <sources to install> 173 # : [ <installgrist> ] ; 174 HaikuInstall $(1) : $(2) : $(3) : $(4) : InstallAbsSymLinkAdapter ; 175} 176 177rule InstallRelSymLinkAdapter 178{ 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 ; 184} 185 186rule HaikuInstallRelSymLink 187{ 188 # Usage: HaikuInstallRelSymLink <[ install [ and uninstall ] pseudotarget ]> 189 # : <directory> : <sources to install> 190 # : [ <installgrist> ] ; 191 HaikuInstall $(1) : $(2) : $(3) : $(4) : InstallRelSymLinkAdapter ; 192} 193 194 195rule UnarchiveObjects 196{ 197 # UnarchiveObjects <target objects> : <static object> 198 199 MakeLocateArch $(1) ; 200 Depends $(1) : $(2) ; 201 SEARCH on $(2) = $(SEARCH_SOURCE) ; 202} 203 204actions UnarchiveObjects 205{ 206 ( cd $(1[1]:D) && $(TARGET_AR_$(TARGET_PACKAGING_ARCH)) \ 207 $(TARGET_UNARFLAGS_$(TARGET_PACKAGING_ARCH)) "$(2)" $(1:BS) ) 208} 209 210 211rule ExtractArchive directory : entries : archiveFile : grist 212{ 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". 230 231 grist ?= extracted ; 232 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 } 240 241 LOCATE on $(targets) = $(directory:G=) ; 242 Depends $(targets) : $(directory) $(archiveFile) ; 243 NoUpdate $(targets) ; 244 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) ; 251 252 NoUpdate $(directory) ; 253 Depends $(directory) : $(archiveFile) ; 254 switch $(archiveFile:S) 255 { 256 case .zip : 257 ExtractZipArchive1 $(directory) : $(archiveFile) ; 258 259 case .tgz : 260 ExtractTarArchive1 $(directory) : $(archiveFile) ; 261 262 case .hpkg : 263 Depends $(directory) : <build>package ; 264 ExtractHPKGArchive1 $(directory) 265 : <build>package $(archiveFile) ; 266 267 case "" : 268 Exit "ExtractArchive: No archive passed" ; 269 270 case * : 271 Exit "ExtractArchive: Unhandled archive extension:" 272 "$(archiveFile:S)" ; 273 } 274 INITIALIZED on $(directory) = 1 ; 275 } 276 277 return $(targets) ; 278} 279 280 281actions ExtractZipArchive1 282{ 283 mkdir -p $(1) 284 unzip -q -u -o -d $(1) $(2) 285} 286 287 288actions ExtractTarArchive1 289{ 290 mkdir -p $(1) 291 tar -C $(1) -xf $(2) 292} 293 294 295actions ExtractHPKGArchive1 296{ 297 mkdir -p "$(1)" 298 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) 299 $(2[1]) extract -C "$(1)" "$(2[2])" 300} 301 302 303rule ObjectReference 304{ 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. 309 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 } 316} 317 318rule ObjectReferences 319{ 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. 324 325 local source ; 326 for source in $(1) { 327 ObjectReference [ FGristFiles $(source) ] : $(source) ; 328 } 329} 330 331rule CopySetHaikuRevision target : source 332{ 333 # CopySetHaikuRevision <target> : <source> 334 # 335 # Copy <source> to <target>, writing the SVN revision of the working root 336 # directory into the haiku revision section of <target>. 337 # 338 # <target> - Output file target. Gristed and located target. 339 # <source> - ELF object to be copied. Gristed and located target. 340 341 # If existent, make the target depend on the .svn/entries file in the 342 # root directory, so it gets updated when the revision changes due to 343 # "svn up". 344 if [ Glob [ FDirName $(HAIKU_TOP) .svn ] : entries ] { 345 local svnEntries = <haiku-rootdir-svn>entries ; 346 SEARCH on $(svnEntries) = [ FDirName $(HAIKU_TOP) .svn ] ; 347 Depends $(target) : $(svnEntries) ; 348 } else if [ Glob [ FDirName $(HAIKU_TOP) .git ] : index ] { 349 local gitIndex = <haiku-rootdir-git>index ; 350 SEARCH on $(gitIndex) = [ FDirName $(HAIKU_TOP) .git ] ; 351 Depends $(target) : $(gitIndex) ; 352 } else if [ Glob [ FDirName $(HAIKU_TOP) .hg ] : store ] { 353 local hgStore = <haiku-rootdir-hg>store ; 354 SEARCH on $(hgStore) = [ FDirName $(HAIKU_TOP) .hg ] ; 355 Depends $(target) : $(hgStore) ; 356 } 357 358 PropagateContainerUpdateTargetFlags $(target) : $(source) ; 359 360 Depends $(target) : <build>copyattr <build>set_haiku_revision $(source) ; 361 CopySetHaikuRevision1 $(target) 362 : <build>copyattr <build>set_haiku_revision $(source) ; 363} 364 365actions CopySetHaikuRevision1 366{ 367 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) 368 369 . $(HAIKU_TOP)/build/scripts/determine_haiku_revision 370 determineHaikuRevision $(HAIKU_TOP) $(HAIKU_BUILD_OUTPUT_DIR) 371 372 $(2[1]) --data $(2[3]) $(1) && 373 $(2[2]) $(1) ${revision} 374} 375 376rule DataFileToSourceFile sourceFile : dataFile : dataVariable : sizeVariable 377{ 378 sourceFile = [ FGristFiles $(sourceFile) ] ; 379 MakeLocateCommonPlatform $(sourceFile) ; 380 381 sizeVariable ?= $(dataVariable)Size ; 382 383 DATA_VARIABLE on $(sourceFile) = $(dataVariable) ; 384 SIZE_VARIABLE on $(sourceFile) = $(sizeVariable) ; 385 386 Depends $(sourceFile) : <build>data_to_source $(dataFile) ; 387 DataFileToSourceFile1 $(sourceFile) : <build>data_to_source $(dataFile) ; 388 LocalClean clean : $(sourceFile) ; 389} 390 391actions DataFileToSourceFile1 392{ 393 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) 394 $(2[1]) $(DATA_VARIABLE) $(SIZE_VARIABLE) $(2[2]) $(1) 395} 396 397rule DownloadLocatedFile target : url : source 398{ 399 # DownloadLocatedFile <target> : <url> [ : <source> ] ; 400 # 401 # <source> is an optional target that <target> will be made dependent on. 402 # Its resolved path can be used in <url> via '$source'. 403 404 URL on $(target) = $(url) ; 405 406 if $(source) { 407 Depends $(target) : $(source) ; 408 } 409 410 DownloadLocatedFile1 $(target) : $(source) ; 411} 412 413actions DownloadLocatedFile1 414{ 415 source="$(2)" 416 wget -O "$(1)" $(URL) 417 touch "$(1)" 418} 419 420rule DownloadFile file : url : source 421{ 422 # DownloadFile <file> : <url> [ : <source> ] ; 423 # 424 # <source> is an optional target that the target will be made dependent on. 425 # Its resolved path can be used in <url> via '$source'. 426 427 file = $(file:G=download) ; 428 429 # Request the download only once. 430 if [ on $(file) return $(HAIKU_FILE_DOWNLOAD) ] { 431 return $(file) ; 432 } 433 434 HAIKU_FILE_DOWNLOAD on $(file) = 1 ; 435 436 MakeLocate $(file) : $(HAIKU_DOWNLOAD_DIR) ; 437 DownloadLocatedFile $(file) : $(url) : $(source) ; 438 439 return $(file) ; 440} 441 442 443actions ChecksumFileSHA256 444{ 445 $(HOST_SHA256) $(2) | sed -r 's,([^[:space:]]*).*,\1,' > $(1) 446 # The sed part is only necessary for sha256sum, but it doesn't harm for 447 # sha256 either. 448} 449