1#pragma mark - Private
2
3# default value for the build profile that defines the set of source packages
4# that will be put onto the bootstrap image
5HAIKU_BOOTSTRAP_SOURCES_PROFILE ?= @minimum-raw ;
6
7rule PackageFamily packageBaseName
8{
9	return $(packageBaseName:G=package-family) ;
10}
11
12
13rule SetRepositoryMethod repository : methodName : method
14{
15	HAIKU_REPOSITORY_METHOD_$(methodName) on $(repository) = $(method) ;
16}
17
18rule InvokeRepositoryMethod repository : methodName : arg1 : arg2 : arg3 : arg4
19	: arg5 : arg6 : arg7
20{
21	local method
22		= [ on $(repository) return $(HAIKU_REPOSITORY_METHOD_$(methodName)) ] ;
23	if ! $(method) {
24		Exit "Method" $(methodName) " not defined for repository"
25			$(repository) ;
26	}
27
28	return [ $(method) $(repository) : $(arg1) : $(arg2) : $(arg3) : $(arg4)
29		: $(arg5) : $(arg6) : $(arg7) ] ;
30}
31
32
33rule AddRepositoryPackage repository : architecture : baseName : version
34{
35	local package = $(baseName)-$(version) ;
36	package = $(package:E=$(baseName):G=package-in-$(repository:G=)) ;
37	HAIKU_PACKAGE_REPOSITORY on $(package) = $(repository) ;
38	HAIKU_PACKAGE_ARCHITECTURE on $(package) = $(architecture) ;
39	local packageFileName = $(package:G=)-$(architecture).hpkg ;
40	HAIKU_PACKAGE_FILE_NAME on $(package) = $(packageFileName) ;
41
42	local packageFamily = [ InvokeRepositoryMethod $(repository) : PackageFamily
43		: $(baseName) ] ;
44	baseName = $(packageFamily:G=) ;
45
46	if $(HAIKU_NO_DOWNLOADS) = 1 && $(HAIKU_IS_BOOTSTRAP) != 1 {
47		# Only add packages to repository that already exist in download
48		# directory.
49		if ! [ Glob $(HAIKU_DOWNLOAD_DIR) : $(packageFileName) ] {
50			return ;
51		}
52	}
53
54	if ! $(baseName) in $(HAIKU_AVAILABLE_PACKAGES) {
55		HAIKU_AVAILABLE_PACKAGES += $(baseName) ;
56	}
57
58	HAIKU_PACKAGE_VERSIONS on $(packageFamily) += $(package) ;
59	HAIKU_REPOSITORY_PACKAGES on $(repository) += $(package) ;
60
61	return $(package) ;
62}
63
64
65rule AddRepositoryPackages repository : architecture : packages : sourcePackages
66	: debugInfoPackages
67{
68	local packageTargets ;
69	local package ;
70	for package in $(packages) {
71		local splitName = [ Match "([^-]*)-(.*)" : $(package) ] ;
72		local baseName = $(splitName[1]:E=$(package)) ;
73		local version = $(splitName[2]) ;
74		packageTargets += [ AddRepositoryPackage $(repository) : $(architecture)
75			: $(baseName) : $(version) ] ;
76		if $(baseName) in $(sourcePackages) {
77			AddRepositoryPackage $(repository) : source : $(baseName)_source
78				: $(version) ;
79		}
80		if $(baseName) in $(debugInfoPackages) {
81			packageTargets += [ AddRepositoryPackage $(repository)
82				: $(architecture) : $(baseName)_debuginfo : $(version) ] ;
83		}
84	}
85
86	return $(packageTargets) ;
87}
88
89
90rule PackageRepository repository : architecture : anyPackages : packages
91	: sourcePackages : debugInfoPackages
92{
93	if $(architecture) != $(HAIKU_PACKAGING_ARCHS[1]) {
94		return ;
95	}
96
97	HAIKU_REPOSITORIES += $(repository) ;
98	HAIKU_REPOSITORY_DEFINITION_FILE on $(repository)
99		= $(HAIKU_REPOSITORY_JAMFILE) ;
100
101	return [ AddRepositoryPackages $(repository) : any : $(anyPackages)
102			: $(sourcePackages) : $(debugInfoPackages) ]
103		[ AddRepositoryPackages $(repository) : $(architecture) : $(packages)
104			: $(sourcePackages) : $(debugInfoPackages) ] ;
105}
106
107
108#pragma mark - Remote Repository
109
110
111rule RemoteRepositoryPackageFamily repository : packageBaseName
112{
113	return [ PackageFamily $(packageBaseName) ] ;
114}
115
116
117rule RemoteRepositoryFetchPackage repository : package : fileName
118{
119	local baseUrl = [ on $(repository) return $(HAIKU_REPOSITORY_URL) ] ;
120	local packagesChecksumFile
121		= [ on $(repository)
122			return $(HAIKU_REPOSITORY_PACKAGES_CHECKSUM_FILE) ] ;
123
124	local downloadedFile = [ DownloadFile $(fileName)
125		: "$(baseUrl)/`cat $source`/packages/$(fileName)"
126		: $(packagesChecksumFile) ] ;
127	NoUpdate $(downloadedFile) ;
128		# Don't download the file again when something in the repository
129		# changes. It is (supposed to be) still the same file.
130	return $(downloadedFile) ;
131}
132
133
134rule RemotePackageRepository repository : architecture : repositoryUrl
135	: anyPackages : packages : sourcePackages : debugInfoPackages
136{
137	repository = $(repository:G=repository) ;
138
139	if ! $(HOST_EXTENDED_REGEX_SED) {
140		ECHO "Variable HOST_EXTENDED_REGEX_SED not set. Please run ./configure or" ;
141		EXIT "specify it manually." ;
142	}
143
144	SetRepositoryMethod $(repository) : PackageFamily
145		: RemoteRepositoryPackageFamily ;
146	SetRepositoryMethod $(repository) : FetchPackage
147		: RemoteRepositoryFetchPackage ;
148
149	HAIKU_REPOSITORY_URL on $(repository) = $(repositoryUrl) ;
150
151	PackageRepository $(repository) : $(architecture) : $(anyPackages)
152		: $(packages) : $(sourcePackages) : $(debugInfoPackages) ;
153
154	# build package list file
155	local packageListFile = $(repository:G=repository-package-list)-packages ;
156	local repositoriesDir = $(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture)) ;
157	MakeLocate $(packageListFile) : $(repositoriesDir) ;
158	GeneratedRepositoryPackageList $(packageListFile) : $(repository) ;
159
160	# build package list checksum file
161	local packagesChecksumFile
162		= $(repository:G=repository-package-checksum)-checksum ;
163	local thisPackageRepositoryFile = [ Glob [ FDirName
164		$(HAIKU_BUILD_RULES_DIR) repositories HaikuPorts ] :
165			$(HAIKU_PACKAGING_ARCH) ] ;
166	MakeLocate $(packagesChecksumFile) : $(repositoriesDir) ;
167	Depends $(packagesChecksumFile) : $(thisPackageRepositoryFile) ;
168	ChecksumFileSHA256 $(packagesChecksumFile) : $(thisPackageRepositoryFile) ;
169
170	local repositoryInfo = $(repository:G=repository-info)-info ;
171	local repositoryFile = $(repository:G=repository-cache) ;
172	local repositoryConfig = $(repository:G=repository-config)-config ;
173	MakeLocate $(repositoryInfo) $(repositoryFile) $(repositoryConfig)
174		: $(repositoriesDir) ;
175	# Use a locally created dummy repository if downloads have been disabled.
176	# This is useful when trying to build everything locally from source.
177	if $(HAIKU_NO_DOWNLOADS) = 1 {
178		# build repository file
179		local packageFileNames = [
180			on $(packageListFile) return $(HAIKU_REPOSITORY_PACKAGE_FILE_NAMES)
181		] ;
182		local packageFiles ;
183		local packageFile ;
184		for packageFile in $(packageFileNames) {
185			MakeLocate $(packageFile) : $(HAIKU_DOWNLOAD_DIR) ;
186			packageFiles += $(packageFile) ;
187		}
188		RepositoryCache $(repositoryFile) : $(repositoryInfo)
189			: $(packageFiles) ;
190	} else {
191		# download repository file
192		local repoUrl = [ on $(repository) return $(HAIKU_REPOSITORY_URL) ] ;
193		DownloadLocatedFile $(repositoryFile)
194			: "$(repoUrl)/`cat $source`/repo"
195			: $(packagesChecksumFile) ;
196	}
197
198	# build the repository info file
199	local repositoryInfoTemplate = <repository-info-template>haikuports ;
200	SEARCH on $(repositoryInfoTemplate)
201		= $(HAIKU_TOP)/src/data/repository_infos ;
202	PreprocessPackageOrRepositoryInfo $(repositoryInfo)
203		: $(repositoryInfoTemplate) : $(architecture) ;
204
205	# build repository config file
206	RepositoryConfig $(repositoryConfig) : $(repositoryInfo)
207		: $(packagesChecksumFile) ;
208
209	HAIKU_REPOSITORY_CACHE_FILE on $(repository) = $(repositoryFile) ;
210	HAIKU_REPOSITORY_CONFIG_FILE on $(repository) = $(repositoryConfig) ;
211	HAIKU_REPOSITORY_PACKAGES_CHECKSUM_FILE on $(repository)
212		= $(packagesChecksumFile) ;
213}
214
215
216rule GeneratedRepositoryPackageList target : repository
217{
218	repository = $(repository:G=repository) ;
219
220	# construct a list of file names
221	local fileNames ;
222	local package ;
223	for package in [ on $(repository) return $(HAIKU_REPOSITORY_PACKAGES) ] {
224		fileNames += [ on $(package) return $(HAIKU_PACKAGE_FILE_NAME) ] ;
225	}
226
227	local definitionFile
228		= [ on $(repository) return $(HAIKU_REPOSITORY_DEFINITION_FILE) ] ;
229	Depends $(target) : $(definitionFile) ;
230
231	HAIKU_REPOSITORY_PACKAGE_FILE_NAMES on $(target) = $(fileNames) ;
232	GeneratedRepositoryPackageList1 $(target) ;
233}
234
235
236actions GeneratedRepositoryPackageList1
237{
238	(for file in $(HAIKU_REPOSITORY_PACKAGE_FILE_NAMES) ; do
239		echo $file
240	done) | LC_ALL=C sort -u > $(1)
241}
242
243
244rule RepositoryConfig repoConfig : repoInfo : checksumFile
245{
246	Depends $(repoConfig)
247		: <build>create_repository_config $(repoInfo) $(checksumFile) ;
248	RepositoryConfig1 $(repoConfig)
249		: <build>create_repository_config $(repoInfo) $(checksumFile) ;
250}
251
252
253actions RepositoryConfig1
254{
255	version=
256	if [ -n "$(2[3]:E)" ]; then
257		version=`cat "$(2[3]:E)"`
258	fi
259	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) \
260	$(2[1]) $(2[2]) $(1)
261}
262
263
264rule RepositoryCache repoCache : repoInfo : packageFiles
265{
266	Depends $(repoCache)
267		: <build>package_repo $(repoInfo) $(packageFiles) ;
268	RepositoryCache1 $(repoCache)
269		: <build>package_repo $(repoInfo) $(packageFiles) ;
270}
271
272
273actions RepositoryCache1
274{
275	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) \
276	$(2[1]) create -q $(2[2-])
277	mv $(1:B=repo) $(1)
278}
279
280
281#pragma mark - Bootstrap Repository
282
283
284rule BootstrapRepositoryPackageFamily repository : packageBaseName
285{
286	local splitBaseName = [ Match "(.*)_bootstrap(.*)" : $(packageBaseName) ] ;
287	if $(splitBaseName) {
288		packageBaseName = $(splitBaseName[1])$(splitBaseName[2]) ;
289	}
290
291	return [ PackageFamily $(packageBaseName) ] ;
292}
293
294
295rule BootstrapRepositoryFetchPackage repository : package : fileName
296{
297	local outputDir
298		= [ on $(repository) return $(HAIKU_REPOSITORY_BUILD_DIRECTORY) ] ;
299	local configFile
300		= [ on $(repository) return $(HAIKU_REPOSITORY_BUILD_CONFIG_FILE) ] ;
301	local haikuCrossDevelPackages = [ on $(package)
302		return $(HAIKU_REPOSITORY_HAIKU_CROSS_DEVEL_PACKAGES) ] ;
303
304	local packageFile = <cross-built>$(fileName) ;
305	if [ on $(packageFile) return $(HAIKU_REPOSITORY_BUILD_DIRECTORY) ] {
306		# rule already called for this package
307		return $(packageFile) ;
308	}
309
310	HAIKU_REPOSITORY_BUILD_DIRECTORY on $(packageFile) = $(outputDir) ;
311
312	MakeLocate $(packageFile) : [ FDirName $(outputDir) packages ] ;
313	NoUpdate $(packageFile) ;
314		# Don't rebuild the file. Since the haiku cross devel package is
315		# a dependency and is updated always, this package would otherwise be
316		# rebuilt always as well.
317
318	Depends $(packageFile) : $(haikuCrossDevelPackages) $(configFile) ;
319	BootstrapRepositoryFetchPackage1 $(packageFile)
320		: $(haikuCrossDevelPackages) ;
321
322	return $(packageFile) ;
323}
324
325
326actions BootstrapRepositoryFetchPackage1
327{
328	# don't rebuild existing package
329	package="$(1)"
330	if [ -e "$package" ]; then
331		exit 0
332	fi
333
334	# make Haiku cross devel package path absolute
335	haikuCrossDevelPackage="$(2[1])"
336	if [ "x$haikuCrossDevelPackage" = "x" ]; then
337		echo "$package does not have a cross-devel package defined!"
338		exit 1
339	fi
340
341	if [ "x$haikuCrossDevelPackage" = "x${haikuCrossDevelPackage#/}" ]; then
342		haikuCrossDevelPackage="`pwd`/$haikuCrossDevelPackage"
343	fi
344
345	# make secondary Haiku cross devel packages path absolute
346	secondaryCrossDevelPackages=
347	if [ -n "$(2[2-]:J)" ]; then
348		for secondaryCrossDevelPackage in "$(2[2-])" ; do
349			if [ "x$secondaryCrossDevelPackage" = "x${secondaryCrossDevelPackage#/}" ]; then
350				secondaryCrossDevelPackage="`pwd`/$secondaryCrossDevelPackage"
351			fi
352			if [ -n "$secondaryCrossDevelPackages" ]; then
353				secondaryCrossDevelPackages="$secondaryCrossDevelPackages,$secondaryCrossDevelPackage"
354			else
355				secondaryCrossDevelPackages="--secondary-cross-devel-package=$secondaryCrossDevelPackage"
356			fi
357		done
358	fi
359
360	# determine the port-specification from the package name
361	portSpec=`basename "$package" | sed 's@-.*@@'`
362
363	cd $(HAIKU_REPOSITORY_BUILD_DIRECTORY)
364
365	export $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
366	if [ -n "$secondaryCrossDevelPackages" ]; then
367		$(HOST_HAIKU_PORTER) -j$(HAIKU_PORTER_CONCURRENT_JOBS) \
368			--all-dependencies $(HAIKU_PORTER_EXTRA_OPTIONS) \
369			--cross-devel-package "$haikuCrossDevelPackage" \
370			"$secondaryCrossDevelPackages" $portSpec
371	else
372		$(HOST_HAIKU_PORTER) -j$(HAIKU_PORTER_CONCURRENT_JOBS) \
373			--all-dependencies $(HAIKU_PORTER_EXTRA_OPTIONS) \
374			--cross-devel-package "$haikuCrossDevelPackage" $portSpec
375	fi
376
377	if [ ! -e "$package" ]; then
378		echo "Supposedly built package $package does not exist; version mismatch?"
379		exit 1
380	fi
381}
382
383
384actions BuildBootstrapRepositoryConfig
385{
386cat > $(1) << EOF
387PACKAGER="The Haiku build system <build-system@haiku-os.org>"
388TREE_PATH="$(HAIKU_REPOSITORY_TREE_PATH)"
389TARGET_ARCHITECTURE="$(HAIKU_PACKAGING_ARCH)"
390
391DOWNLOAD_IN_PORT_DIRECTORY="yes"
392PACKAGE_COMMAND="$(PWD)/$(2[1])"
393MIMESET_COMMAND="$(PWD)/$(2[2])"
394SYSTEM_MIME_DB="$(PWD)/$(2[3])"
395LICENSES_DIRECTORY="$(HAIKU_ABSOLUTE_TOP)/data/system/data/licenses"
396OUTPUT_DIRECTORY="$(HAIKU_REPOSITORY_BUILD_DIRECTORY)"
397EOF
398
399	# If we have cross tools, add the cross tools directory.
400	gcc=$(HAIKU_CC_$(HAIKU_PACKAGING_ARCH))
401	if [ "x$gcc" != "x${gcc#/}" ]; then
402		if [ `basename $gcc` = \
403				$(HAIKU_GCC_MACHINE_$(HAIKU_PACKAGING_ARCH))-gcc ]; then
404			dir=`dirname $gcc`
405			dir=`dirname $dir`
406			echo CROSS_TOOLS=\"$dir\" >> $(1)
407		fi
408	fi
409
410	# Add secondary architectures and cross tools.
411	secondaryArchs="$(HAIKU_PACKAGING_ARCHS[2-]:E=)"
412	if [ -n "$secondaryArchs" ]; then
413		echo SECONDARY_TARGET_ARCHITECTURES=\" >> $(1)
414		for arch in $secondaryArchs; do
415			echo "  $arch" >> $(1)
416		done
417		echo \" >> $(1)
418
419		echo SECONDARY_CROSS_TOOLS=\" >> $(1)
420		for gcc in $(HAIKU_CC_$(HAIKU_PACKAGING_ARCHS[2-])) ; do
421			dir=`dirname $gcc`
422			dir=`dirname $dir`
423			echo "  $dir" >> $(1)
424		done
425		echo \" >> $(1)
426	fi
427}
428
429
430rule BootstrapPackageRepository repository : architecture
431	: anyPackages : packagesStage0 : packagesStage1 : packagesStage2
432	: sourcePackages : debugInfoPackages
433{
434	repository = $(repository:G=repository) ;
435	packagesStage0 = [ FFilterByBuildFeatures $(packagesStage0) ] ;
436	packagesStage1 = [ FFilterByBuildFeatures $(packagesStage1) ] ;
437	packagesStage2 = [ FFilterByBuildFeatures $(packagesStage2) ] ;
438	sourcePackages = [ FFilterByBuildFeatures $(sourcePackages) ] ;
439	debugInfoPackages = [ FFilterByBuildFeatures $(debugInfoPackages) ] ;
440
441	SetRepositoryMethod $(repository) : PackageFamily
442		: BootstrapRepositoryPackageFamily ;
443	SetRepositoryMethod $(repository) : FetchPackage
444		: BootstrapRepositoryFetchPackage ;
445
446	# register repository with stage 0 packages
447	local stage0PackageTargets = [ PackageRepository $(repository)
448		: $(architecture) : $(anyPackages) : $(packagesStage0)
449		: $(sourcePackages) : $(debugInfoPackages) ] ;
450	if ! $(stage0PackageTargets) {
451		return ;
452	}
453	local crossDevelPackageSuffixes = $(architecture)
454		$(architecture)_$(HAIKU_PACKAGING_ARCHS[2-]) ;
455	HAIKU_REPOSITORY_HAIKU_CROSS_DEVEL_PACKAGES on $(stage0PackageTargets)
456		= haiku_cross_devel_sysroot_stage0_$(crossDevelPackageSuffixes).hpkg ;
457
458	# register repository with stage 1 packages
459	local stage1PackageTargets = [ PackageRepository $(repository)
460		: $(architecture) : $(anyPackages) : $(packagesStage1)
461		: $(sourcePackages) : $(debugInfoPackages) ] ;
462	if ! $(stage1PackageTargets) {
463		return ;
464	}
465	HAIKU_REPOSITORY_HAIKU_CROSS_DEVEL_PACKAGES on $(stage1PackageTargets)
466		= haiku_cross_devel_sysroot_stage1_$(crossDevelPackageSuffixes).hpkg ;
467
468	# add stage 2 packages
469	local stage2PackageTargets = [ AddRepositoryPackages $(repository)
470		: $(architecture) : $(packagesStage2) : $(sourcePackages)
471		: $(debugInfoPackages) ] ;
472	HAIKU_REPOSITORY_HAIKU_CROSS_DEVEL_PACKAGES on $(stage2PackageTargets)
473		= haiku_cross_devel_sysroot_$(crossDevelPackageSuffixes).hpkg ;
474
475	# prepare the config file for the HaikuPorts cross build
476	# This path needs to be absolute due to haikuporter's cwd
477	local outputDir = [ FDirName
478		$(PWD)
479		$(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture))
480		$(repository:G=)-build ] ;
481	local configFile = haikuports.conf ;
482	configFile = $(configFile:G=repository-config-$(repository:G=)) ;
483	MakeLocate $(configFile) : $(outputDir) ;
484	NoUpdate $(configFile) ;
485	Depends $(configFile) : <build>package <build>mimeset <mimedb>mime_db ;
486	HAIKU_REPOSITORY_BUILD_DIRECTORY on $(configFile) = $(outputDir) ;
487	HAIKU_PACKAGING_ARCH on $(configFile) = $(architecture) ;
488	HAIKU_REPOSITORY_TREE_PATH on $(configFile) = $(HAIKU_PORTS_CROSS) ;
489	BuildBootstrapRepositoryConfig $(configFile)
490		: <build>package <build>mimeset <mimedb>mime_db ;
491
492	HAIKU_REPOSITORY_BUILD_CONFIG_FILE on $(repository) = $(configFile) ;
493	HAIKU_REPOSITORY_BUILD_DIRECTORY on $(repository) = $(outputDir) ;
494
495	# Serialize all package file targets. We need to do this, since
496	# haikuporter uses a common directory for building the ports, so building
497	# two ports concurrently isn't possible.
498	local previousPackageFile ;
499	local package ;
500	for package in $(stage1PackageTargets) $(stage2PackageTargets) {
501		local fileName = [ on $(package) return $(HAIKU_PACKAGE_FILE_NAME) ] ;
502		local packageFile = [ BootstrapRepositoryFetchPackage $(repository)
503			: $(package) : $(fileName) ] ;
504		Depends $(packageFile) : $(previousPackageFile) ;
505
506		previousPackageFile = $(packageFile) ;
507	}
508}
509
510
511#pragma mark - Public
512
513
514rule FSplitPackageName packageName
515{
516	local splitName = [ Match "(.*)_([^_]*)" : $(packageName) ] ;
517	local knownPackageSuffixes = devel doc source debuginfo ;
518	if $(splitName[2]) && $(splitName[2]) in $(knownPackageSuffixes) {
519		return $(splitName) ;
520	}
521
522	return $(packageName) ;
523}
524
525
526rule IsPackageAvailable packageName : flags
527{
528	# for a secondary architecture adjust the package name
529	if $(TARGET_PACKAGING_ARCH) != $(TARGET_PACKAGING_ARCHS[1])
530		&& ! nameResolved in $(flags) {
531		# The position of the secondary architecture within the package name
532		# is not well defined, so we scan for it starting from the back.
533		local packageNameHead = $(packageName) ;
534		local packageNameTail = ;
535		while $(packageNameHead) {
536			local splitName = [ FSplitPackageName $(packageNameHead) ] ;
537			splitName = $(splitName[1]) $(TARGET_PACKAGING_ARCH) $(splitName[2])
538				$(packageNameTail) ;
539			packageName = $(splitName:J=_) ;
540			if $(packageName) in $(HAIKU_AVAILABLE_PACKAGES) {
541				return $(packageName) ;
542			}
543			local splitHead = [ Match "(.*)_([^_]*)" : $(packageNameHead) ] ;
544			packageNameHead = $(splitHead[1]) ;
545			packageNameTail = $(splitHead[2]) $(packageNameTail) ;
546		}
547	}
548
549	if $(packageName) in $(HAIKU_AVAILABLE_PACKAGES) {
550		return $(packageName) ;
551	}
552
553	return ;
554}
555
556
557rule FetchPackage packageName : flags
558{
559	local foundPackageName = [ IsPackageAvailable $(packageName) : $(flags) ] ;
560	if ! $(foundPackageName) {
561		Exit "FetchPackage: package" $(packageName) "not available!" ;
562		return ;
563	}
564	packageName = $(foundPackageName) ;
565
566	# TODO: We should support explicitly specified versions (or partial/minimum
567	# versions like gcc-2 or gcc-4).
568
569	local packageFamily = [ PackageFamily $(packageName) ] ;
570	local package
571		= [ on $(packageFamily) return $(HAIKU_PACKAGE_VERSIONS[1]) ] ;
572	local fileName = [ on $(package) return $(HAIKU_PACKAGE_FILE_NAME) ] ;
573	local repository = [ on $(package) return $(HAIKU_PACKAGE_REPOSITORY) ] ;
574
575	if $(HAIKU_DONT_FETCH_PACKAGES) {
576		Exit "FetchPackage: file" $(fileName) "not found and fetching"
577			"disabled!" ;
578		return ;
579	}
580
581	return [ InvokeRepositoryMethod $(repository) : FetchPackage : $(package)
582		: $(fileName) ] ;
583}
584
585
586rule BuildHaikuPortsSourcePackageDirectory
587{
588	local architecture = $(TARGET_PACKAGING_ARCH) ;
589	local outputDir = [ FDirName
590		$(PWD)
591		$(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture))
592		HaikuPorts-sources-build ] ;
593
594	local sourcePackageDir = <HaikuPorts-repository-source-packages>packages ;
595	MakeLocate $(sourcePackageDir) : $(outputDir) ;
596
597	# build the package list file
598	local packageList
599		= <repository-package-list-HaikuPorts-sources>package_list ;
600	MakeLocate $(packageList) : $(outputDir) ;
601	Depends $(packageList) :
602		[ FDirName $(HAIKU_BUILD_RULES_DIR) repositories HaikuPorts
603			$(architecture) ] ;
604	BuildHaikuPortsPackageList $(packageList) ;
605
606	# prepare the config file for the HaikuPorts build
607	local configFile = <repository-config-HaikuPorts-sources>haikuports.conf ;
608	MakeLocate $(configFile) : $(outputDir) ;
609	NoUpdate $(configFile) ;
610	Depends $(configFile) : <build>package <build>mimeset <mimedb>mime_db ;
611	HAIKU_REPOSITORY_BUILD_DIRECTORY on $(configFile) = $(outputDir) ;
612	HAIKU_PACKAGING_ARCH on $(configFile) = $(architecture) ;
613	HAIKU_REPOSITORY_TREE_PATH on $(configFile) = $(HAIKU_PORTS) ;
614	BuildBootstrapRepositoryConfig $(configFile)
615		: <build>package <build>mimeset <mimedb>mime_db ;
616
617	# get Haiku cross-devel packages and build the sources
618	local crossDevelPackageSuffixes = $(architecture)
619		$(architecture)_$(HAIKU_PACKAGING_ARCHS[2-]) ;
620	local haikuCrossDevelPackages
621		= haiku_cross_devel_sysroot_stage1_$(crossDevelPackageSuffixes).hpkg ;
622
623	HAIKU_REPOSITORY_BUILD_DIRECTORY on $(sourcePackageDir) = $(outputDir) ;
624
625	Depends $(sourcePackageDir) : $(packageList) $(haikuCrossDevelPackages)
626		$(configFile) ;
627	BuildHaikuPortsSourcePackageDirectory1 $(sourcePackageDir)
628		: $(packageList) $(haikuCrossDevelPackages) ;
629
630	return $(sourcePackageDir) ;
631}
632
633
634actions BuildHaikuPortsPackageList
635{
636	$(JAM:E=jam) $(HAIKU_BOOTSTRAP_SOURCES_PROFILE) build-package-list $(1) \
637		$(HAIKU_REPOSITORY_BUILD_ADDITIONAL_PACKAGES)
638}
639
640
641actions BuildHaikuPortsSourcePackageDirectory1
642{
643	packageList="$(2[1])"
644
645	# make Haiku cross devel package path absolute
646	haikuCrossDevelPackage="$(2[2])"
647	if [ "x$haikuCrossDevelPackage" = "x${haikuCrossDevelPackage#/}" ]; then
648		haikuCrossDevelPackage="`pwd`/$haikuCrossDevelPackage"
649	fi
650
651	# make secondary Haiku cross devel packages path absolute
652	secondaryCrossDevelPackages=
653	if [ -n "$(2[3-]:J)" ]; then
654		for secondaryCrossDevelPackage in "$(2[3-])" ; do
655			if [ "x$secondaryCrossDevelPackage" = "x${secondaryCrossDevelPackage#/}" ]; then
656				secondaryCrossDevelPackage="`pwd`/$secondaryCrossDevelPackage"
657			fi
658			if [ -n "$secondaryCrossDevelPackages" ]; then
659				secondaryCrossDevelPackages="$secondaryCrossDevelPackages,$secondaryCrossDevelPackage"
660			else
661				secondaryCrossDevelPackages="--secondary-cross-devel-package=$secondaryCrossDevelPackage"
662			fi
663		done
664	fi
665
666	cd $(HAIKU_REPOSITORY_BUILD_DIRECTORY)
667
668	export $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
669	if [ -n "$secondaryCrossDevelPackages" ]; then
670		$(HOST_HAIKU_PORTER) --cross-devel-package "$haikuCrossDevelPackage" \
671			"$secondaryCrossDevelPackages" \
672			--all-dependencies $(HAIKU_PORTER_EXTRA_OPTIONS) \
673			--create-source-packages-for-bootstrap --portsfile $packageList
674	else
675		$(HOST_HAIKU_PORTER) --cross-devel-package "$haikuCrossDevelPackage" \
676			--all-dependencies $(HAIKU_PORTER_EXTRA_OPTIONS) \
677			--create-source-packages-for-bootstrap --portsfile $packageList
678	fi
679}
680
681
682rule BuildHaikuPortsRepositoryConfig treePath
683{
684	local architecture = $(TARGET_PACKAGING_ARCH) ;
685	local outputDir = [ FDirName
686		$(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture))
687		HaikuPorts-bootstrap ] ;
688
689	local configFile = <repository-config-HaikuPorts-bootstrap>haikuports.conf ;
690	MakeLocate $(configFile) : $(outputDir) ;
691	NoUpdate $(configFile) ;
692
693	HAIKU_REPOSITORY_TREE_PATH on $(configFile) = $(treePath) ;
694	BuildHaikuPortsRepositoryConfig1 $(configFile) ;
695
696	return $(configFile) ;
697}
698
699
700actions BuildHaikuPortsRepositoryConfig1
701{
702	# use a specific packager for continuous integration builds (buildbot)
703	if [ "$(HAIKU_CONTINUOUS_INTEGRATION_BUILD)" = "1" ]; then
704		echo 'PACKAGER="Haiku buildmaster <buildmaster@haiku-os.org>"' > $(1)
705	else
706		echo '#PACKAGER="Joe Hacker <user@host.com>"' > $(1)
707	fi
708	cat >> $(1) << EOF
709TREE_PATH="$(HAIKU_REPOSITORY_TREE_PATH)"
710TARGET_ARCHITECTURE="$(HAIKU_PACKAGING_ARCH)"
711EOF
712}
713
714
715rule HaikuRepository repository : repoInfoTemplate : packages
716{
717	# HaikuRepository <repository> : <repoInfoTemplate> : <packages>
718	#	[ : <url> [ : <versionFile> ] ] ;
719	# Builds the Haiku repository from the given packages and repository info
720	# template. <repository> must already be located.
721	#
722	# <repository> - The repository target. Resolves to a directory that will be
723	#	(removed,) created and populated with the package files and repository
724	#	meta data files.
725	# <repoInfoTemplate> - The repository info template file to be used.
726	# <packages> - The packages to be added to the repository.
727
728	local architecture = $(HAIKU_PACKAGING_ARCH) ;
729	local secondaryArchitecture ;
730	if $(TARGET_PACKAGING_ARCH) != $(architecture) {
731		secondaryArchitecture = $(TARGET_PACKAGING_ARCH) ;
732	}
733
734	local repositoriesDir = $(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture)) ;
735
736	# build the repository info
737	local repositoryInfo = $(repository:G=repository-info)-info ;
738	MakeLocate $(repositoryInfo) : $(repositoriesDir) ;
739	PreprocessPackageOrRepositoryInfo $(repositoryInfo) : $(repoInfoTemplate)
740		: $(architecture) : $(secondaryArchitecture) ;
741
742	# build the respository config
743	local repositoryConfig = $(repository:G=repository-config)-config ;
744	MakeLocate $(repositoryConfig) : $(repositoriesDir) ;
745	RepositoryConfig $(repositoryConfig) : $(repositoryInfo) ;
746	HAIKU_REPOSITORY_CONFIG_FILE on $(repository) = $(repositoryConfig) ;
747
748	# setup the repository cache file
749	local repositoryCache = $(repository:B=repo:G=repository-cache) ;
750	MakeLocate $(repositoryCache)
751		: [ FDirName $(repositoriesDir) $(repository:G=) ] ;
752	Depends $(repositoryCache) : $(repository) ;
753	HAIKU_REPOSITORY_CACHE_FILE on $(repository) = $(repositoryCache) ;
754
755	# add the repository to the list of known package repositories
756	HAIKU_REPOSITORIES += $(repository) ;
757
758	# prepare the script that initializes the shell variables
759	local initVariablesScript = $(repository)-repository-init-vars ;
760	MakeLocate $(initVariablesScript)
761		: $(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture)) ;
762	Always $(initVariablesScript) ;
763
764	local script = $(initVariablesScript) ;
765	AddVariableToScript $(script) : addBuildCompatibilityLibDir
766		: "export $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)" ;
767	AddVariableToScript $(script) : sha256 : $(HOST_SHA256) ;
768	AddVariableToScript $(script) : sedExtendedRegex
769		: $(HOST_EXTENDED_REGEX_SED) ;
770	AddTargetVariableToScript $(script) : <build>package ;
771	AddTargetVariableToScript $(script) : <build>package_repo : packageRepo ;
772
773	# call the build actions
774	local mainScript = build_haiku_repository ;
775	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
776
777	Depends $(repository) : $(mainScript) $(initVariablesScript)
778		$(repositoryInfo) $(packages) ;
779	HaikuRepository1 $(repository) : $(mainScript) $(initVariablesScript)
780		$(repositoryInfo) $(packages) ;
781	Always $(repository) ;
782
783	RmTemps $(repository) : $(initVariablesScript) ;
784}
785
786
787actions HaikuRepository1
788{
789	$(2[1]) "$(2[2])" "$(1)" "$(2[3-])"
790}
791