1#pragma mark - Private 2 3 4rule PackageFamily packageBaseName 5{ 6 return $(packageBaseName:G=package-family) ; 7} 8 9 10rule SetRepositoryMethod repository : methodName : method 11{ 12 HAIKU_REPOSITORY_METHOD_$(methodName) on $(repository) = $(method) ; 13} 14 15rule InvokeRepositoryMethod repository : methodName : arg1 : arg2 : arg3 : arg4 16 : arg5 : arg6 : arg7 17{ 18 local method 19 = [ on $(repository) return $(HAIKU_REPOSITORY_METHOD_$(methodName)) ] ; 20 if ! $(method) { 21 Exit "Method" $(methodName) " not defined for repository" 22 $(repository) ; 23 } 24 25 return [ $(method) $(repository) : $(arg1) : $(arg2) : $(arg3) : $(arg4) 26 : $(arg5) : $(arg6) : $(arg7) ] ; 27} 28 29 30rule AddRepositoryPackage repository : architecture : baseName : version 31{ 32 local package = $(baseName)-$(version) ; 33 package = $(package:E=$(baseName):G=package-in-$(repository:G=)) ; 34 HAIKU_PACKAGE_REPOSITORY on $(package) = $(repository) ; 35 HAIKU_PACKAGE_ARCHITECTURE on $(package) = $(architecture) ; 36 HAIKU_PACKAGE_FILE_NAME on $(package) = $(package:G=)-$(architecture).hpkg ; 37 38 local packageFamily = [ InvokeRepositoryMethod $(repository) : PackageFamily 39 : $(baseName) ] ; 40 baseName = $(packageFamily:G=) ; 41 42 if ! $(baseName) in $(HAIKU_AVAILABLE_PACKAGES) { 43 HAIKU_AVAILABLE_PACKAGES += $(baseName) ; 44 } 45 46 HAIKU_PACKAGE_VERSIONS on $(packageFamily) += $(package) ; 47 HAIKU_REPOSITORY_PACKAGES on $(repository) += $(package) ; 48 49 return $(package) ; 50} 51 52 53rule AddRepositoryPackages repository : architecture : packages : sourcePackages 54 : debugInfoPackages 55{ 56 local packageTargets ; 57 local package ; 58 for package in $(packages) { 59 local splitName = [ Match "([^-]*)-(.*)" : $(package) ] ; 60 local baseName = $(splitName[1]:E=$(package)) ; 61 local version = $(splitName[2]) ; 62 packageTargets += [ AddRepositoryPackage $(repository) : $(architecture) 63 : $(baseName) : $(version) ] ; 64 if $(baseName) in $(sourcePackages) { 65 AddRepositoryPackage $(repository) : source : $(baseName)_source 66 : $(version) ; 67 } 68 if $(baseName) in $(debugInfoPackages) { 69 packageTargets += [ AddRepositoryPackage $(repository) 70 : $(architecture) : $(baseName)_debuginfo : $(version) ] ; 71 } 72 } 73 74 return $(packageTargets) ; 75} 76 77 78rule PackageRepository repository : architecture : anyPackages : packages 79 : sourcePackages : debugInfoPackages 80{ 81 if $(architecture) != $(HAIKU_PACKAGING_ARCHS[1]) { 82 return ; 83 } 84 85 HAIKU_REPOSITORIES += $(repository) ; 86 HAIKU_REPOSITORY_DEFINITION_FILE on $(repository) 87 = $(HAIKU_REPOSITORY_JAMFILE) ; 88 89 return [ AddRepositoryPackages $(repository) : any : $(anyPackages) 90 : $(sourcePackages) : $(debugInfoPackages) ] 91 [ AddRepositoryPackages $(repository) : $(architecture) : $(packages) 92 : $(sourcePackages) : $(debugInfoPackages) ] ; 93} 94 95 96#pragma mark - Remote Repository 97 98 99rule RemoteRepositoryPackageFamily repository : packageBaseName 100{ 101 return [ PackageFamily $(packageBaseName) ] ; 102} 103 104 105rule RemoteRepositoryFetchPackage repository : package : fileName 106{ 107 local baseUrl = [ on $(repository) return $(HAIKU_REPOSITORY_URL) ] ; 108 local packagesChecksumFile 109 = [ on $(repository) 110 return $(HAIKU_REPOSITORY_PACKAGES_CHECKSUM_FILE) ] ; 111 112 local downloadedFile = [ DownloadFile $(fileName) 113 : "$(baseUrl)/`cat $source`/packages/$(fileName)" 114 : $(packagesChecksumFile) ] ; 115 NoUpdate $(downloadedFile) ; 116 # Don't download the file again when something in the repository 117 # changes. It is (supposed to be) still the same file. 118 return $(downloadedFile) ; 119} 120 121 122rule RemotePackageRepository repository : architecture : repositoryUrl 123 : anyPackages : packages : sourcePackages : debugInfoPackages 124{ 125 repository = $(repository:G=repository) ; 126 127 SetRepositoryMethod $(repository) : PackageFamily 128 : RemoteRepositoryPackageFamily ; 129 SetRepositoryMethod $(repository) : FetchPackage 130 : RemoteRepositoryFetchPackage ; 131 132 HAIKU_REPOSITORY_URL on $(repository) = $(repositoryUrl) ; 133 134 PackageRepository $(repository) : $(architecture) : $(anyPackages) 135 : $(packages) : $(sourcePackages) : $(debugInfoPackages) ; 136 137 # build package list file 138 local packageListFile = $(repository:G=repository-package-list)-packages ; 139 local repositoriesDir = $(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture)) ; 140 MakeLocate $(packageListFile) : $(repositoriesDir) ; 141 GeneratedRepositoryPackageList $(packageListFile) : $(repository) ; 142 143 # build package list checksum file 144 local packagesChecksumFile 145 = $(repository:G=repository-package-checksum)-checksum ; 146 MakeLocate $(packagesChecksumFile) : $(repositoriesDir) ; 147 Depends $(packagesChecksumFile) : $(packageListFile) ; 148 ChecksumFileSHA256 $(packagesChecksumFile) : $(packageListFile) ; 149 150 # download repository info file 151 local repositoryInfo = $(repository:G=repository-info)-info ; 152 MakeLocate $(repositoryInfo) : $(repositoriesDir) ; 153 local repoUrl = [ on $(repository) return $(HAIKU_REPOSITORY_URL) ] ; 154 DownloadLocatedFile $(repositoryInfo) 155 : "$(repoUrl)/`cat $source`/repo.info" 156 : $(packagesChecksumFile) ; 157 158 # download repository file 159 local repositoryFile = $(repository:G=repository-cache) ; 160 MakeLocate $(repositoryFile) : $(repositoriesDir) ; 161 local repoUrl = [ on $(repository) return $(HAIKU_REPOSITORY_URL) ] ; 162 DownloadLocatedFile $(repositoryFile) 163 : "$(repoUrl)/`cat $source`/repo" 164 : $(packagesChecksumFile) ; 165 166 # build repository config file 167 local repositoryConfig = $(repository:G=repository-config)-config ; 168 MakeLocate $(repositoryConfig) : $(repositoriesDir) ; 169 RepositoryConfig $(repositoryConfig) : $(repositoryInfo) 170 : $(packagesChecksumFile) : $(repository) ; 171 172 HAIKU_REPOSITORY_CACHE_FILE on $(repository) = $(repositoryFile) ; 173 HAIKU_REPOSITORY_CONFIG_FILE on $(repository) = $(repositoryConfig) ; 174 HAIKU_REPOSITORY_PACKAGES_CHECKSUM_FILE on $(repository) 175 = $(packagesChecksumFile) ; 176} 177 178 179rule GeneratedRepositoryPackageList target : repository 180{ 181 repository = $(repository:G=repository) ; 182 183 # construct a list of file names 184 local fileNames ; 185 local package ; 186 for package in [ on $(repository) return $(HAIKU_REPOSITORY_PACKAGES) ] { 187 fileNames += [ on $(package) return $(HAIKU_PACKAGE_FILE_NAME) ] ; 188 } 189 190 local definitionFile 191 = [ on $(repository) return $(HAIKU_REPOSITORY_DEFINITION_FILE) ] ; 192 Depends $(target) : $(definitionFile) ; 193 194 HAIKU_REPOSITORY_PACKAGE_FILE_NAMES on $(target) = $(fileNames) ; 195 GeneratedRepositoryPackageList1 $(target) ; 196} 197 198 199actions GeneratedRepositoryPackageList1 200{ 201 (for file in $(HAIKU_REPOSITORY_PACKAGE_FILE_NAMES) ; do 202 echo $file 203 done) | LC_ALL=C sort -u > $(1) 204} 205 206 207rule RepositoryConfig repoConfig : repoInfo : packagesChecksumFile : repository 208{ 209 repository = $(repository:G=repository) ; 210 211 HAIKU_REPOSITORY_URL on $(repoConfig) 212 = [ on $(repository) return $(HAIKU_REPOSITORY_URL) ] ; 213 Depends $(repoConfig) 214 : <build>create_repository_config $(repoInfo) $(packagesChecksumFile) ; 215 RepositoryConfig1 $(repoConfig) 216 : <build>create_repository_config $(repoInfo) $(packagesChecksumFile) ; 217} 218 219 220actions RepositoryConfig1 221{ 222 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) 223 $(2[1]) $(HAIKU_REPOSITORY_URL)/`cat $(2[3])` $(2[2]) $(1) 224} 225 226 227#pragma mark - Bootstrap Repository 228 229 230rule BootstrapRepositoryPackageFamily repository : packageBaseName 231{ 232 local splitBaseName = [ Match "(.*)_bootstrap(.*)" : $(packageBaseName) ] ; 233 if $(splitBaseName) { 234 packageBaseName = $(splitBaseName[1])$(splitBaseName[2]) ; 235 } 236 237 return [ PackageFamily $(packageBaseName) ] ; 238} 239 240 241rule BootstrapRepositoryFetchPackage repository : package : fileName 242{ 243 local outputDir 244 = [ on $(repository) return $(HAIKU_REPOSITORY_BUILD_DIRECTORY) ] ; 245 local configFile 246 = [ on $(repository) return $(HAIKU_REPOSITORY_BUILD_CONFIG_FILE) ] ; 247 local haikuCrossDevelPackages = [ on $(package) 248 return $(HAIKU_REPOSITORY_HAIKU_CROSS_DEVEL_PACKAGES) ] ; 249 250 local packageFile = <cross-built>$(fileName) ; 251 if [ on $(packageFile) return $(HAIKU_REPOSITORY_BUILD_DIRECTORY) ] { 252 # rule already called for this package 253 return $(packageFile) ; 254 } 255 256 HAIKU_REPOSITORY_BUILD_DIRECTORY on $(packageFile) = $(outputDir) ; 257 258 MakeLocate $(packageFile) : [ FDirName $(outputDir) packages ] ; 259 NoUpdate $(packageFile) ; 260 # Don't rebuild the file. Since the haiku cross devel package is 261 # a dependency and is updated always, this package would otherwise be 262 # rebuilt always as well. 263 264 Depends $(packageFile) : $(haikuCrossDevelPackages) $(configFile) ; 265 BootstrapRepositoryFetchPackage1 $(packageFile) 266 : $(haikuCrossDevelPackages) ; 267 268 return $(packageFile) ; 269} 270 271 272actions BootstrapRepositoryFetchPackage1 273{ 274 # don't rebuild existing package 275 package="$(1)" 276 if [ -e "$package" ]; then 277 exit 0 278 fi 279 280 # make Haiku cross devel package path absolute 281 haikuCrossDevelPackage="$(2[1])" 282 if [[ "$haikuCrossDevelPackage" != /* ]]; then 283 haikuCrossDevelPackage="`pwd`/$haikuCrossDevelPackage" 284 fi 285 286 # make secondary Haiku cross devel packages path absolute 287 secondaryCrossDevelPackages= 288 if [ -n "$(2[2-]:J)" ]; then 289 for secondaryCrossDevelPackage in "$(2[2-])" ; do 290 if [[ "$secondaryCrossDevelPackage" != /* ]]; then 291 secondaryCrossDevelPackage="`pwd`/$secondaryCrossDevelPackage" 292 fi 293 if [ -n "$secondaryCrossDevelPackages" ]; then 294 secondaryCrossDevelPackages="secondaryCrossDevelPackages,$secondaryCrossDevelPackage" 295 else 296 secondaryCrossDevelPackages="--secondary-cross-devel-package=$secondaryCrossDevelPackage" 297 fi 298 done 299 fi 300 301 # determine the portName 302 portName=`basename "$package" | sed 's@-.*@@'` 303 case $portName in 304 *_devel|*_doc|*_source|*_debuginfo) 305 portName=`echo $portName | sed 's@_[^_]*$@@'` 306 ;; 307 esac 308 309 cd $(HAIKU_REPOSITORY_BUILD_DIRECTORY) 310 311 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) 312 if [ -n "$secondaryCrossDevelPackages" ]; then 313 $(HOST_HAIKU_PORTER) --cross-devel-package "$haikuCrossDevelPackage" \ 314 "$secondaryCrossDevelPackages" $portName 315 else 316 $(HOST_HAIKU_PORTER) --cross-devel-package "$haikuCrossDevelPackage" \ 317 $portName 318 fi 319} 320 321 322actions BuildBootstrapRepositoryConfig 323{ 324cat > $(1) << EOF 325PACKAGER="The Haiku build system <build-system@haiku-os.org>" 326TREE_PATH="$(HAIKU_PORTS_CROSS)" 327TARGET_ARCHITECTURE="$(HAIKU_PACKAGING_ARCH)" 328 329DOWNLOAD_IN_PORT_DIRECTORY="yes" 330PACKAGE_COMMAND="$(2[1])" 331MIMESET_COMMAND="$(2[2])" 332SYSTEM_MIME_DB="$(2[3])" 333LICENSES_DIRECTORY="$(HAIKU_TOP)/data/system/data/licenses" 334OUTPUT_DIRECTORY="$(HAIKU_REPOSITORY_BUILD_DIRECTORY)" 335EOF 336 337 # If we have cross tools, add the cross tools directory. 338 gcc=$(HAIKU_CC_$(HAIKU_PACKAGING_ARCH)) 339 if [[ "$gcc" = /* ]]; then 340 if [ `basename $gcc` = \ 341 $(HAIKU_GCC_MACHINE_$(HAIKU_PACKAGING_ARCH))-gcc ]; then 342 dir=`dirname $gcc` 343 dir=`dirname $dir` 344 echo CROSS_TOOLS=\"$dir\" >> $(1) 345 fi 346 fi 347 348 # Add secondary architectures and cross tools. 349 secondaryArchs="$(HAIKU_PACKAGING_ARCHS[2-]:E=)" 350 if [ -n "$secondaryArchs" ]; then 351 echo SECONDARY_TARGET_ARCHITECTURES=\" >> $(1) 352 for arch in $secondaryArchs; do 353 echo " $arch" >> $(1) 354 done 355 echo \" >> $(1) 356 357 echo SECONDARY_CROSS_TOOLS=\" >> $(1) 358 for gcc in $(HAIKU_CC_$(HAIKU_PACKAGING_ARCHS[2-])) ; do 359 dir=`dirname $gcc` 360 dir=`dirname $dir` 361 echo " $dir" >> $(1) 362 done 363 echo \" >> $(1) 364 fi 365} 366 367 368rule BootstrapPackageRepository repository : architecture 369 : anyPackages : packagesStage1 : packagesStage2 : sourcePackages 370 : debugInfoPackages 371{ 372 repository = $(repository:G=repository) ; 373 packagesStage1 = [ FFilterByBuildFeatures $(packagesStage1) ] ; 374 packagesStage2 = [ FFilterByBuildFeatures $(packagesStage2) ] ; 375 sourcePackages = [ FFilterByBuildFeatures $(sourcePackages) ] ; 376 debugInfoPackages = [ FFilterByBuildFeatures $(debugInfoPackages) ] ; 377 378 SetRepositoryMethod $(repository) : PackageFamily 379 : BootstrapRepositoryPackageFamily ; 380 SetRepositoryMethod $(repository) : FetchPackage 381 : BootstrapRepositoryFetchPackage ; 382 383 # register repository with stage 1 packages 384 local stage1PackageTargets = [ PackageRepository $(repository) 385 : $(architecture) : $(anyPackages) : $(packagesStage1) 386 : $(sourcePackages) : $(debugInfoPackages) ] ; 387 if ! $(stage1PackageTargets) { 388 return ; 389 } 390 local crossDevelPackageSuffixes = $(architecture) 391 $(architecture)_$(HAIKU_PACKAGING_ARCHS[2-]) ; 392 HAIKU_REPOSITORY_HAIKU_CROSS_DEVEL_PACKAGES on $(stage1PackageTargets) 393 = haiku_cross_devel_sysroot_stage1_$(crossDevelPackageSuffixes).hpkg ; 394 395 # add stage 2 packages 396 local stage2PackageTargets = [ AddRepositoryPackages $(repository) 397 : $(architecture) : $(packagesStage2) : $(sourcePackages) 398 : $(debugInfoPackages) ] ; 399 HAIKU_REPOSITORY_HAIKU_CROSS_DEVEL_PACKAGES on $(stage2PackageTargets) 400 = haiku_cross_devel_sysroot_$(crossDevelPackageSuffixes).hpkg ; 401 402 # prepare the config file for the HaikuPorts cross build 403 local outputDir = [ FDirName 404 $(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture)) 405 $(repository:G=)-build ] ; 406 local configFile = haikuports.conf ; 407 configFile = $(configFile:G=repository-config-$(repository:G=)) ; 408 MakeLocate $(configFile) : $(outputDir) ; 409 NoUpdate $(configFile) ; 410 Depends $(configFile) : <build>package <build>mimeset <mimedb>mime_db ; 411 HAIKU_REPOSITORY_BUILD_DIRECTORY on $(configFile) = $(outputDir) ; 412 HAIKU_PACKAGING_ARCH on $(configFile) = $(architecture) ; 413 BuildBootstrapRepositoryConfig $(configFile) 414 : <build>package <build>mimeset <mimedb>mime_db ; 415 416 HAIKU_REPOSITORY_BUILD_CONFIG_FILE on $(repository) = $(configFile) ; 417 HAIKU_REPOSITORY_BUILD_DIRECTORY on $(repository) = $(outputDir) ; 418 419 # Serialize all package file targets. We need to do this, since 420 # haikuporter uses a common directory for building the ports, so building 421 # two ports concurrently isn't possible. 422 local previousPackageFile ; 423 local package ; 424 for package in $(stage1PackageTargets) $(stage2PackageTargets) { 425 local fileName = [ on $(package) return $(HAIKU_PACKAGE_FILE_NAME) ] ; 426 local packageFile = [ BootstrapRepositoryFetchPackage $(repository) 427 : $(package) : $(fileName) ] ; 428 Depends $(packageFile) : $(previousPackageFile) ; 429 430 previousPackageFile = $(packageFile) ; 431 } 432} 433 434 435#pragma mark - Public 436 437 438rule FSplitPackageName packageName 439{ 440 local splitName = [ Match "(.*)_([^_]*)" : $(packageName) ] ; 441 local knownPackageSuffixes = devel doc source debuginfo ; 442 if $(splitName[2]) && $(splitName[2]) in $(knownPackageSuffixes) { 443 return $(splitName) ; 444 } 445 446 return $(packageName) ; 447} 448 449 450rule IsPackageAvailable package 451{ 452 # for a secondary architecture adjust the package name 453 if $(TARGET_PACKAGING_ARCH) != $(TARGET_PACKAGING_ARCHS[1]) { 454 local splitName = [ FSplitPackageName $(package) ] ; 455 splitName = $(splitName[1]) $(TARGET_PACKAGING_ARCH) $(splitName[2-]) ; 456 package = $(splitName:J=_) ; 457 } 458 459 if $(package) in $(HAIKU_AVAILABLE_PACKAGES) { 460 return $(package) ; 461 } 462 463 return ; 464} 465 466 467rule FetchPackage packageName 468{ 469 local foundPackageName = [ IsPackageAvailable $(packageName) ] ; 470 if ! $(foundPackageName) { 471 Exit "DownloadPackage: package" $(packageName) "not available!" ; 472 return ; 473 } 474 packageName = $(foundPackageName) ; 475 476 # TODO: We should support explicitly specified versions (or partial/minimum 477 # versions like gcc-2 or gcc-4). 478 479 local packageFamily = [ PackageFamily $(packageName) ] ; 480 local package 481 = [ on $(packageFamily) return $(HAIKU_PACKAGE_VERSIONS[1]) ] ; 482 local fileName = [ on $(package) return $(HAIKU_PACKAGE_FILE_NAME) ] ; 483 local repository = [ on $(package) return $(HAIKU_PACKAGE_REPOSITORY) ] ; 484 485 return [ InvokeRepositoryMethod $(repository) : FetchPackage : $(package) 486 : $(fileName) ] ; 487} 488