1rule SymLink 2{ 3 # SymLink <target> : <source> : <makeDefaultDependencies> ; 4 # Links <target> to <source>. 5 # <source> is the exact link contents. No binding is done. 6 # <makeDefaultDependencies> If true, <target> will be made a dependency 7 # of the `all' pseudo target, i.e. it will be made by default, and removed 8 # on `jam clean'. 9 10 local target = $(1) ; 11 local source = $(2) ; 12 local makeDefaultDependencies = $(3) ; 13 if ! $(makeDefaultDependencies) { 14 makeDefaultDependencies = true ; 15 } 16 LINKCONTENTS on $(target) = $(source) ; 17 SymLink1 $(target) ; 18 if $(makeDefaultDependencies) = true { 19 LocalDepends files : $(target) ; 20 LocalClean clean : $(target) ; 21 } 22} 23 24actions SymLink1 25{ 26 $(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)" 27} 28 29rule RelSymLink 30{ 31 # RelSymLink <link> : <link target> : <makeDefaultDependencies> ; 32 # Creates a relative symbolic link from <link> to <link target>. 33 # <link> and <link target> can be usual targets. They may have a grist 34 # and don't need to have any dirname. Their LOCATE variables are used to 35 # find their locations. 36 # <makeDefaultDependencies> If true (which is the default), <link> will be 37 # made a dependency of the `files' pseudo target, i.e. it will be made by 38 # default, and removed on `jam clean'. 39 40 local target = $(1) ; 41 local source = $(2) ; 42 local makeDefaultDependencies = $(3) ; 43 local targetDir = [ on $(target) FDirName $(LOCATE[1]) $(target:D) ] ; 44 local sourceDir = [ on $(source) FDirName $(LOCATE[1]) $(source:D) ] ; 45 local sourcePath = $(source:G=) ; 46 sourcePath = $(sourcePath:D=$(sourceDir)) ; 47 local targetDirComponents = [ FSplitPath $(targetDir) ] ; 48 local sourceComponents = [ FSplitPath $(sourcePath) ] ; 49 50 SymLink $(target) 51 : [ FRelPath $(targetDirComponents) : $(sourceComponents) ] 52 : $(makeDefaultDependencies) ; 53 NOUPDATE $(target) ; 54 Depends $(target) : $(source) ; 55} 56 57rule AbsSymLink 58{ 59 # AbsSymLink <link> : <link target> : <link dir> 60 # : <makeDefaultDependencies> ; 61 # Creates an absolute symbolic link from <link> to <link target>. 62 # <link> and <link target> must be usual targets. If <link dir> is 63 # given, then it is set as LOCATE directory on <link>. 64 # <makeDefaultDependencies> If true (which is the default), <link> will be 65 # made a dependency of the `files' pseudo target, i.e. it will be made by 66 # default, and removed on `jam clean'. 67 68 local makeDefaultDependencies = $(4) ; 69 if ! $(makeDefaultDependencies) { 70 makeDefaultDependencies = true ; 71 } 72 73 Depends $(1) : $(2) ; 74 if $(3) { 75 MakeLocate $(1) : $(3) ; 76 } 77 SEARCH on $(2) += $(SEARCH_SOURCE) ; 78 if $(makeDefaultDependencies) = true { 79 LocalDepends files : $(1) ; 80 LocalClean clean : $(1) ; 81 } 82} 83 84actions AbsSymLink 85{ 86 target="$(2)" 87 case "$target" in 88 /*) ;; 89 *) target=`pwd`/"$target";; 90 esac 91 $(RM) "$(1)" && $(LN) -s "$target" "$(1)" 92} 93 94rule HaikuInstall 95{ 96 # Usage: HaikuInstall <[ install [ and uninstall ] pseudotarget ]> 97 # : <directory> : <sources to install> 98 # : [ <installgrist> ] : [ <install rule> ] ; 99 local install = $(1[1]) ; 100 install ?= install ; 101 local uninstall = $(1[2]) ; 102 uninstall ?= un$(install) ; 103 local dir = $(2) ; 104 local sources = $(3) ; 105 local installgrist = $(4) ; 106 installgrist ?= $(INSTALLGRIST) ; 107 local installRule = $(5) ; 108 installRule ?= Install ; 109 local targets = $(sources:G=$(installgrist)) ; 110 111 NotFile $(install) ; 112 NotFile $(uninstall) ; 113 Depends $(install) : $(targets) ; 114 Clean $(uninstall) : $(targets) ; 115 116 SEARCH on $(sources) += $(SEARCH_SOURCE) ; 117 MakeLocate $(targets) : $(dir) ; 118 119 local source ; 120 for source in $(sources) { 121 local target = $(source:G=$(installgrist)) ; 122 123 Depends $(target) : $(source) ; 124 $(installRule) $(target) : $(source) ; 125 126 if [ on $(target) return $(MODE) ] { 127 Chmod $(target) ; 128 } 129 130 if $(OWNER) && $(CHOWN) { 131 Chown $(target) ; 132 OWNER on $(target) = $(OWNER) ; 133 } 134 135 if $(GROUP) && $(CHGRP) { 136 Chgrp $(target) ; 137 GROUP on $(target) = $(GROUP) ; 138 } 139 } 140} 141 142rule InstallAbsSymLinkAdapter 143{ 144 # InstallAbsSymLinkAdapter <link> : <link target> 145 if ! [ on $(2) return $(TARGET) ] { 146 TARGET on $(2) = [ on $(2) return $(SEARCH) ] ; 147 } 148 AbsSymLink $(1) : $(2) : : false ; 149} 150 151rule HaikuInstallAbsSymLink 152{ 153 # Usage: HaikuInstallAbsSymLink <[ install [ and uninstall ] pseudotarget ]> 154 # : <directory> : <sources to install> 155 # : [ <installgrist> ] ; 156 HaikuInstall $(1) : $(2) : $(3) : $(4) : InstallAbsSymLinkAdapter ; 157} 158 159rule InstallRelSymLinkAdapter 160{ 161 # InstallRelSymLinkAdapter <link> : <link target> 162 if ! [ on $(2) return $(TARGET) ] { 163 TARGET on $(2) = [ on $(2) return $(SEARCH) ] ; 164 } 165 RelSymLink $(1) : $(2) : false ; 166} 167 168rule HaikuInstallRelSymLink 169{ 170 # Usage: HaikuInstallRelSymLink <[ install [ and uninstall ] pseudotarget ]> 171 # : <directory> : <sources to install> 172 # : [ <installgrist> ] ; 173 HaikuInstall $(1) : $(2) : $(3) : $(4) : InstallRelSymLinkAdapter ; 174} 175 176 177rule UnarchiveObjects 178{ 179 # UnarchiveObjects <target objects> : <static object> 180 181 MakeLocateArch $(1) ; 182 Depends $(1) : $(2) ; 183 SEARCH on $(2) = $(SEARCH_SOURCE) ; 184} 185 186actions UnarchiveObjects 187{ 188 ( cd $(1[1]:D) && $(TARGET_AR) $(TARGET_UNARFLAGS) "$(2)" $(1:BS) ) 189} 190 191 192rule UnzipArchive directory : entries : zipFile : grist 193{ 194 # UnzipArchive <directory> : <entries> : <zipFile> [ : <grist> ] 195 # 196 # Unzips the zip file target <zipFile> to directory <directory>. The rule 197 # can be called multiple times for different <entries> for the same 198 # <directory> and <zipFile> combo. 199 # 200 # <directory> - The directory into which to unzip the zip file. The 201 # directory is created is by this rule and it is the target 202 # that the unzip action is associated with. 203 # <entries> - The entries of the zip file one is interested in. The rule 204 # always unzips the complete zip file, from the given entries 205 # the rule creates targets (using <grist>) representing the 206 # unzipped entries. Those targets are returned by the rule. 207 # <zipFile> - The zip file target to unzip. 208 # <grist> - The grist used to create targets from <entries>. Defaults to 209 # "unzipped". 210 211 grist ?= unzipped ; 212 213 # Turn the entries into targets to build. 214 local targets ; 215 local entry ; 216 for entry in $(entries) { 217 local target = $(entry:G=$(grist)) ; 218 targets += $(target) ; 219 } 220 221 LOCATE on $(targets) = $(directory) ; 222 Depends $(targets) : $(directory) ; 223 NoUpdate $(targets) ; 224 225 # one-time initialization for the main target (the directory) 226 if ! [ on $(directory) return $(INITIALIZED) ] { 227 # make sure the parent dir exists 228 local parentDir = $(directory:PG=dir) ; 229 Depends $(directory) : $(parentDir) ; 230 MkDir $(parentDir) ; 231 232 NoUpdate $(directory) ; 233 Depends $(directory) : $(zipFile) ; 234 UnzipArchive1 $(directory) : $(zipFile) ; 235 INITIALIZED on $(directory) = 1 ; 236 } 237 238 # Use a dummy rule so that it looks to jam like the targets are actually 239 # built from the directory target. 240 UnzipArchiveDummy $(targets) : $(directory) ; 241 242 return $(targets) ; 243} 244 245actions UnzipArchive1 246{ 247 mkdir -p $(1[1]) 248 unzip -q -u -o -d $(1[1]) $(2) 249} 250 251actions UnzipArchiveDummy 252{ 253} 254 255 256rule ObjectReference 257{ 258 # ObjectReference <reference object> : <source object> 259 # Makes <reference object> refer to the same file as <source object>. 260 # The filenames must of course be identical. 261 # <source object> must have already been LOCATEd. 262 263 local ref = $(1) ; 264 local source = $(2) ; 265 if $(ref) != $(source) { 266 Depends $(ref) : $(source) ; 267 LOCATE on $(ref) = [ on $(source) return $(LOCATE) ] ; 268 } 269} 270 271rule ObjectReferences 272{ 273 # ObjectReferences <source objects> 274 # Creates local references to <source objects>, i.e. identifiers with the 275 # current grist referring to the same files. <source objects> must have 276 # already been LOCATEd. 277 278 local source ; 279 for source in $(1) { 280 ObjectReference [ FGristFiles $(source) ] : $(source) ; 281 } 282} 283 284rule CopySetHaikuRevision target : source 285{ 286 # CopySetHaikuRevision <target> : <source> 287 # 288 # Copy <source> to <target>, writing the SVN revision of the working root 289 # directory into the haiku revision section of <target>. 290 # 291 # <target> - Output file target. Gristed and located target. 292 # <source> - ELF object to be copied. Gristed and located target. 293 294 # If existent, make the target depend on the .svn/entries file in the 295 # root directory, so it gets updated when the revision changes due to 296 # "svn up". 297 if [ Glob [ FDirName $(HAIKU_TOP) .svn ] : entries ] { 298 local svnEntries = <haiku-rootdir-svn>entries ; 299 SEARCH on $(svnEntries) = [ FDirName $(HAIKU_TOP) .svn ] ; 300 Depends $(target) : $(svnEntries) ; 301 } else if [ Glob [ FDirName $(HAIKU_TOP) .git ] : index ] { 302 local gitIndex = <haiku-rootdir-git>index ; 303 SEARCH on $(gitIndex) = [ FDirName $(HAIKU_TOP) .git ] ; 304 Depends $(target) : $(gitIndex) ; 305 } 306 307 HAIKU_INCLUDE_IN_IMAGE on $(target) 308 = [ on $(source) return $(HAIKU_INCLUDE_IN_IMAGE) ] ; 309 310 Depends $(target) : <build>copyattr <build>set_haiku_revision $(source) ; 311 CopySetHaikuRevision1 $(target) 312 : <build>copyattr <build>set_haiku_revision $(source) ; 313} 314 315actions CopySetHaikuRevision1 316{ 317 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) 318 revision=`LC_ALL=C LANG=C svn info $(HAIKU_TOP) 2> /dev/null | 319 grep Revision | awk '{printf $2}'` 320 if [ "$revision" = 0 -o "$revision" = "" ]; then 321 revision=`(cd $(HAIKU_TOP) && LC_ALL=C LANG=C git svn info) 322 2> /dev/null || 323 (git log --max-count=1 --grep="git-svn-id:" 2> /dev/null | 324 grep git-svn-id: | cut -d '@' -f 2 | 325 awk '{printf $1}') 2> /dev/null` 326 fi 327 if [ "$revision" = "" ]; then 328 revision=0 329 fi 330 $(2[1]) --data $(2[3]) $(1) && 331 $(2[2]) $(1) ${revision} 332} 333 334rule DataFileToSourceFile sourceFile : dataFile : dataVariable : sizeVariable 335{ 336 sourceFile = [ FGristFiles $(sourceFile) ] ; 337 MakeLocateCommonPlatform $(sourceFile) ; 338 339 sizeVariable ?= $(dataVariable)Size ; 340 341 DATA_VARIABLE on $(sourceFile) = $(dataVariable) ; 342 SIZE_VARIABLE on $(sourceFile) = $(sizeVariable) ; 343 344 Depends $(sourceFile) : <build>data_to_source $(dataFile) ; 345 DataFileToSourceFile1 $(sourceFile) : <build>data_to_source $(dataFile) ; 346 LocalClean clean : $(sourceFile) ; 347} 348 349actions DataFileToSourceFile1 350{ 351 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) 352 $(2[1]) $(DATA_VARIABLE) $(SIZE_VARIABLE) $(2[2]) $(1) 353} 354 355rule DownloadFile target : url 356{ 357 URL on $(target) = $(url) ; 358 359 DownloadFile1 $(target) ; 360} 361 362actions DownloadFile1 363{ 364 wget -O $(1) $(URL) 365} 366 367rule DownloadOptionalPackage package : url 368{ 369 # download zip file 370 local zipFile = $(package:G=download).zip ; 371 372 # Request the download only once. 373 if [ on $(zipFile) return $(HAIKU_OPTIONAL_PACKAGE_DOWNLOAD) ] { 374 return $(zipFile) ; 375 } 376 377 HAIKU_OPTIONAL_PACKAGE_DOWNLOAD on $(zipFile) = 1 ; 378 379 MakeLocate $(zipFile) : $(HAIKU_DOWNLOAD_DIR) ; 380 DownloadFile $(zipFile) : $(url) ; 381 382 return $(zipFile) ; 383} 384