xref: /haiku/build/jam/RepositoryRules (revision 0754c319592cd8a523959d85fb06ab23c64a98a6)
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 {
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	MakeLocate $(packagesChecksumFile) : $(repositoriesDir) ;
164	Depends $(packagesChecksumFile) : $(packageListFile) ;
165	ChecksumFileSHA256 $(packagesChecksumFile) : $(packageListFile) ;
166
167	local repositoryInfo = $(repository:G=repository-info)-info ;
168	local repositoryFile = $(repository:G=repository-cache) ;
169	local repositoryConfig = $(repository:G=repository-config)-config ;
170	MakeLocate $(repositoryInfo) $(repositoryFile) $(repositoryConfig)
171		: $(repositoriesDir) ;
172	# Use a locally created dummy repository if downloads have been disabled.
173	# This is useful when trying to build everything locally from source.
174	if $(HAIKU_NO_DOWNLOADS) = 1 {
175		# build the dummy repository info file
176		local repositoryInfoTemplate = <repository-info-template>haikuports ;
177		SEARCH on $(repositoryInfoTemplate)
178			= $(HAIKU_TOP)/src/data/repository_infos ;
179		PreprocessPackageOrRepositoryInfo $(repositoryInfo)
180			: $(repositoryInfoTemplate) : $(architecture) ;
181
182		# build repository file
183		local packageFileNames = [
184			on $(packageListFile) return $(HAIKU_REPOSITORY_PACKAGE_FILE_NAMES)
185		] ;
186		local packageFiles ;
187		for packageFile in $(packageFileNames) {
188			MakeLocate $(packageFile) : $(HAIKU_DOWNLOAD_DIR) ;
189			packageFiles += $(packageFile) ;
190		}
191		RepositoryCache $(repositoryFile) : $(repositoryInfo)
192			: $(packageFiles) ;
193	} else {
194		# download repository info file
195		local repoUrl = [ on $(repository) return $(HAIKU_REPOSITORY_URL) ] ;
196		DownloadLocatedFile $(repositoryInfo)
197			: "$(repoUrl)/`cat $source`/repo.info"
198			: $(packagesChecksumFile) ;
199
200		# download repository file
201		DownloadLocatedFile $(repositoryFile)
202			: "$(repoUrl)/`cat $source`/repo"
203			: $(packagesChecksumFile) ;
204	}
205
206	# build repository config file
207	RepositoryConfig $(repositoryConfig) : $(repositoryInfo)
208		: $(repositoryUrl)/$version : $(packagesChecksumFile) ;
209
210	HAIKU_REPOSITORY_CACHE_FILE on $(repository) = $(repositoryFile) ;
211	HAIKU_REPOSITORY_CONFIG_FILE on $(repository) = $(repositoryConfig) ;
212	HAIKU_REPOSITORY_PACKAGES_CHECKSUM_FILE on $(repository)
213		= $(packagesChecksumFile) ;
214}
215
216
217rule GeneratedRepositoryPackageList target : repository
218{
219	repository = $(repository:G=repository) ;
220
221	# construct a list of file names
222	local fileNames ;
223	local package ;
224	for package in [ on $(repository) return $(HAIKU_REPOSITORY_PACKAGES) ] {
225		fileNames += [ on $(package) return $(HAIKU_PACKAGE_FILE_NAME) ] ;
226	}
227
228	local definitionFile
229		= [ on $(repository) return $(HAIKU_REPOSITORY_DEFINITION_FILE) ] ;
230	Depends $(target) : $(definitionFile) ;
231
232	HAIKU_REPOSITORY_PACKAGE_FILE_NAMES on $(target) = $(fileNames) ;
233	GeneratedRepositoryPackageList1 $(target) ;
234}
235
236
237actions GeneratedRepositoryPackageList1
238{
239	(for file in $(HAIKU_REPOSITORY_PACKAGE_FILE_NAMES) ; do
240		echo $file
241	done) | LC_ALL=C sort -u > $(1)
242}
243
244
245rule RepositoryConfig repoConfig : repoInfo : url : versionFile
246{
247	HAIKU_REPOSITORY_URL on $(repoConfig) = $(url) ;
248	Depends $(repoConfig)
249		: <build>create_repository_config $(repoInfo) $(versionFile) ;
250	RepositoryConfig1 $(repoConfig)
251		: <build>create_repository_config $(repoInfo) $(versionFile) ;
252}
253
254
255actions RepositoryConfig1
256{
257	version=
258	if [ -n "$(2[3]:E)" ]; then
259		version=`cat "$(2[3]:E)"`
260	fi
261	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
262	$(2[1]) $(HAIKU_REPOSITORY_URL) $(2[2]) $(1)
263}
264
265
266rule RepositoryCache repoCache : repoInfo : packageFiles
267{
268	Depends $(repoCache)
269		: <build>package_repo $(repoInfo) $(packageFiles) ;
270	RepositoryCache1 $(repoCache)
271		: <build>package_repo $(repoInfo) $(packageFiles) ;
272}
273
274
275actions RepositoryCache1
276{
277	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
278	$(2[1]) create -q $(2[2-])
279	mv $(1:B=repo) $(1)
280}
281
282
283#pragma mark - Bootstrap Repository
284
285
286rule BootstrapRepositoryPackageFamily repository : packageBaseName
287{
288	local splitBaseName = [ Match "(.*)_bootstrap(.*)" : $(packageBaseName) ] ;
289	if $(splitBaseName) {
290		packageBaseName = $(splitBaseName[1])$(splitBaseName[2]) ;
291	}
292
293	return [ PackageFamily $(packageBaseName) ] ;
294}
295
296
297rule BootstrapRepositoryFetchPackage repository : package : fileName
298{
299	local outputDir
300		= [ on $(repository) return $(HAIKU_REPOSITORY_BUILD_DIRECTORY) ] ;
301	local configFile
302		= [ on $(repository) return $(HAIKU_REPOSITORY_BUILD_CONFIG_FILE) ] ;
303	local haikuCrossDevelPackages = [ on $(package)
304		return $(HAIKU_REPOSITORY_HAIKU_CROSS_DEVEL_PACKAGES) ] ;
305
306	local packageFile = <cross-built>$(fileName) ;
307	if [ on $(packageFile) return $(HAIKU_REPOSITORY_BUILD_DIRECTORY) ] {
308		# rule already called for this package
309		return $(packageFile) ;
310	}
311
312	HAIKU_REPOSITORY_BUILD_DIRECTORY on $(packageFile) = $(outputDir) ;
313
314	MakeLocate $(packageFile) : [ FDirName $(outputDir) packages ] ;
315	NoUpdate $(packageFile) ;
316		# Don't rebuild the file. Since the haiku cross devel package is
317		# a dependency and is updated always, this package would otherwise be
318		# rebuilt always as well.
319
320	Depends $(packageFile) : $(haikuCrossDevelPackages) $(configFile) ;
321	BootstrapRepositoryFetchPackage1 $(packageFile)
322		: $(haikuCrossDevelPackages) ;
323
324	return $(packageFile) ;
325}
326
327
328actions BootstrapRepositoryFetchPackage1
329{
330	# don't rebuild existing package
331	package="$(1)"
332	if [ -e "$package" ]; then
333		exit 0
334	fi
335
336	# make Haiku cross devel package path absolute
337	haikuCrossDevelPackage="$(2[1])"
338	if [ "x$haikuCrossDevelPackage" = "x${haikuCrossDevelPackage#/}" ]; then
339		haikuCrossDevelPackage="`pwd`/$haikuCrossDevelPackage"
340	fi
341
342	# make secondary Haiku cross devel packages path absolute
343	secondaryCrossDevelPackages=
344	if [ -n "$(2[2-]:J)" ]; then
345		for secondaryCrossDevelPackage in "$(2[2-])" ; do
346			if [ "x$secondaryCrossDevelPackage" = "x${secondaryCrossDevelPackage#/}" ]; then
347				secondaryCrossDevelPackage="`pwd`/$secondaryCrossDevelPackage"
348			fi
349			if [ -n "$secondaryCrossDevelPackages" ]; then
350				secondaryCrossDevelPackages="secondaryCrossDevelPackages,$secondaryCrossDevelPackage"
351			else
352				secondaryCrossDevelPackages="--secondary-cross-devel-package=$secondaryCrossDevelPackage"
353			fi
354		done
355	fi
356
357	# determine the portName
358	portName=`basename "$package" | sed 's@-.*@@'`
359	case $portName in
360		*_devel|*_doc|*_source|*_debuginfo)
361			portName=`echo $portName | sed 's@_[^_]*$@@'`
362			;;
363		*_source_rigged)
364			portName=`echo $portName | sed 's@_source_rigged$@@'`
365			;;
366	esac
367
368	cd $(HAIKU_REPOSITORY_BUILD_DIRECTORY)
369
370	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
371	if [ -n "$secondaryCrossDevelPackages" ]; then
372		$(HOST_HAIKU_PORTER) -j$(HAIKU_PORTER_CONCURRENT_JOBS) \
373			$(HAIKU_PORTER_EXTRA_OPTIONS) \
374			--cross-devel-package "$haikuCrossDevelPackage" \
375			"$secondaryCrossDevelPackages" $portName
376	else
377		$(HOST_HAIKU_PORTER) -j$(HAIKU_PORTER_CONCURRENT_JOBS) \
378			$(HAIKU_PORTER_EXTRA_OPTIONS) \
379			--cross-devel-package "$haikuCrossDevelPackage" $portName
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="$(2[1])"
393MIMESET_COMMAND="$(2[2])"
394SYSTEM_MIME_DB="$(2[3])"
395LICENSES_DIRECTORY="$(HAIKU_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 : packagesStage1 : packagesStage2 : sourcePackages
432	: debugInfoPackages
433{
434	repository = $(repository:G=repository) ;
435	packagesStage1 = [ FFilterByBuildFeatures $(packagesStage1) ] ;
436	packagesStage2 = [ FFilterByBuildFeatures $(packagesStage2) ] ;
437	sourcePackages = [ FFilterByBuildFeatures $(sourcePackages) ] ;
438	debugInfoPackages = [ FFilterByBuildFeatures $(debugInfoPackages) ] ;
439
440	SetRepositoryMethod $(repository) : PackageFamily
441		: BootstrapRepositoryPackageFamily ;
442	SetRepositoryMethod $(repository) : FetchPackage
443		: BootstrapRepositoryFetchPackage ;
444
445	# register repository with stage 1 packages
446	local stage1PackageTargets = [ PackageRepository $(repository)
447		: $(architecture) : $(anyPackages) : $(packagesStage1)
448		: $(sourcePackages) : $(debugInfoPackages) ] ;
449	if ! $(stage1PackageTargets) {
450		return ;
451	}
452	local crossDevelPackageSuffixes = $(architecture)
453		$(architecture)_$(HAIKU_PACKAGING_ARCHS[2-]) ;
454	HAIKU_REPOSITORY_HAIKU_CROSS_DEVEL_PACKAGES on $(stage1PackageTargets)
455		= haiku_cross_devel_sysroot_stage1_$(crossDevelPackageSuffixes).hpkg ;
456
457	# add stage 2 packages
458	local stage2PackageTargets = [ AddRepositoryPackages $(repository)
459		: $(architecture) : $(packagesStage2) : $(sourcePackages)
460		: $(debugInfoPackages) ] ;
461	HAIKU_REPOSITORY_HAIKU_CROSS_DEVEL_PACKAGES on $(stage2PackageTargets)
462		= haiku_cross_devel_sysroot_$(crossDevelPackageSuffixes).hpkg ;
463
464	# prepare the config file for the HaikuPorts cross build
465	local outputDir = [ FDirName
466		$(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture))
467		$(repository:G=)-build ] ;
468	local configFile = haikuports.conf ;
469	configFile = $(configFile:G=repository-config-$(repository:G=)) ;
470	MakeLocate $(configFile) : $(outputDir) ;
471	NoUpdate $(configFile) ;
472	Depends $(configFile) : <build>package <build>mimeset <mimedb>mime_db ;
473	HAIKU_REPOSITORY_BUILD_DIRECTORY on $(configFile) = $(outputDir) ;
474	HAIKU_PACKAGING_ARCH on $(configFile) = $(architecture) ;
475	HAIKU_REPOSITORY_TREE_PATH on $(configFile) = $(HAIKU_PORTS_CROSS) ;
476	BuildBootstrapRepositoryConfig $(configFile)
477		: <build>package <build>mimeset <mimedb>mime_db ;
478
479	HAIKU_REPOSITORY_BUILD_CONFIG_FILE on $(repository) = $(configFile) ;
480	HAIKU_REPOSITORY_BUILD_DIRECTORY on $(repository) = $(outputDir) ;
481
482	# Serialize all package file targets. We need to do this, since
483	# haikuporter uses a common directory for building the ports, so building
484	# two ports concurrently isn't possible.
485	local previousPackageFile ;
486	local package ;
487	for package in $(stage1PackageTargets) $(stage2PackageTargets) {
488		local fileName = [ on $(package) return $(HAIKU_PACKAGE_FILE_NAME) ] ;
489		local packageFile = [ BootstrapRepositoryFetchPackage $(repository)
490			: $(package) : $(fileName) ] ;
491		Depends $(packageFile) : $(previousPackageFile) ;
492
493		previousPackageFile = $(packageFile) ;
494	}
495}
496
497
498#pragma mark - Public
499
500
501rule FSplitPackageName packageName
502{
503	local splitName = [ Match "(.*)_([^_]*)" : $(packageName) ] ;
504	local knownPackageSuffixes = devel doc source debuginfo ;
505	if $(splitName[2]) && $(splitName[2]) in $(knownPackageSuffixes) {
506		return $(splitName) ;
507	}
508
509	return $(packageName) ;
510}
511
512
513rule IsPackageAvailable package : flags
514{
515	# for a secondary architecture adjust the package name
516	if $(TARGET_PACKAGING_ARCH) != $(TARGET_PACKAGING_ARCHS[1])
517		&& ! nameResolved in $(flags) {
518		local splitName = [ FSplitPackageName $(package) ] ;
519		splitName = $(splitName[1]) $(TARGET_PACKAGING_ARCH) $(splitName[2-]) ;
520		package = $(splitName:J=_) ;
521	}
522
523	if $(package) in $(HAIKU_AVAILABLE_PACKAGES) {
524		return $(package) ;
525	}
526
527	return ;
528}
529
530
531rule FetchPackage packageName : flags
532{
533	local foundPackageName = [ IsPackageAvailable $(packageName) : $(flags) ] ;
534	if ! $(foundPackageName) {
535		Exit "FetchPackage: package" $(packageName) "not available!" ;
536		return ;
537	}
538	packageName = $(foundPackageName) ;
539
540	# TODO: We should support explicitly specified versions (or partial/minimum
541	# versions like gcc-2 or gcc-4).
542
543	local packageFamily = [ PackageFamily $(packageName) ] ;
544	local package
545		= [ on $(packageFamily) return $(HAIKU_PACKAGE_VERSIONS[1]) ] ;
546	local fileName = [ on $(package) return $(HAIKU_PACKAGE_FILE_NAME) ] ;
547	local repository = [ on $(package) return $(HAIKU_PACKAGE_REPOSITORY) ] ;
548
549	if $(HAIKU_DONT_FETCH_PACKAGES) {
550		Exit "FetchPackage: file" $(fileName) "not found and fetching"
551			"disabled!" ;
552		return ;
553	}
554
555	return [ InvokeRepositoryMethod $(repository) : FetchPackage : $(package)
556		: $(fileName) ] ;
557}
558
559
560rule BuildHaikuPortsSourcePackageDirectory
561{
562	local architecture = $(TARGET_PACKAGING_ARCH) ;
563	local outputDir = [ FDirName
564		$(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture))
565		HaikuPorts-sources-build ] ;
566
567	local sourcePackageDir = <HaikuPorts-repository-source-packages>packages ;
568	MakeLocate $(sourcePackageDir) : $(outputDir) ;
569
570	# build the package list file
571	local packageList
572		= <repository-package-list-HaikuPorts-sources>package_list ;
573	MakeLocate $(packageList) : $(outputDir) ;
574	Depends $(packageList) :
575		[ FDirName $(HAIKU_BUILD_RULES_DIR) repositories HaikuPorts
576			$(architecture) ] ;
577	BuildHaikuPortsPackageList $(packageList) ;
578
579	# prepare the config file for the HaikuPorts build
580	local configFile = <repository-config-HaikuPorts-sources>haikuports.conf ;
581	MakeLocate $(configFile) : $(outputDir) ;
582	NoUpdate $(configFile) ;
583	Depends $(configFile) : <build>package <build>mimeset <mimedb>mime_db ;
584	HAIKU_REPOSITORY_BUILD_DIRECTORY on $(configFile) = $(outputDir) ;
585	HAIKU_PACKAGING_ARCH on $(configFile) = $(architecture) ;
586	HAIKU_REPOSITORY_TREE_PATH on $(configFile) = $(HAIKU_PORTS) ;
587	BuildBootstrapRepositoryConfig $(configFile)
588		: <build>package <build>mimeset <mimedb>mime_db ;
589
590	# get Haiku cross-devel packages and build the sources
591	local crossDevelPackageSuffixes = $(architecture)
592		$(architecture)_$(HAIKU_PACKAGING_ARCHS[2-]) ;
593	local haikuCrossDevelPackages
594		= haiku_cross_devel_sysroot_stage1_$(crossDevelPackageSuffixes).hpkg ;
595
596	HAIKU_REPOSITORY_BUILD_DIRECTORY on $(sourcePackageDir) = $(outputDir) ;
597
598	Depends $(sourcePackageDir) : $(packageList) $(haikuCrossDevelPackages)
599		$(configFile) ;
600	BuildHaikuPortsSourcePackageDirectory1 $(sourcePackageDir)
601		: $(packageList) $(haikuCrossDevelPackages) ;
602
603	return $(sourcePackageDir) ;
604}
605
606
607actions BuildHaikuPortsPackageList
608{
609	$(JAM:E=jam) $(HAIKU_BOOTSTRAP_SOURCES_PROFILE) build-package-list $(1) \
610		$(HAIKU_REPOSITORY_BUILD_ADDITIONAL_PACKAGES)
611}
612
613
614actions BuildHaikuPortsSourcePackageDirectory1
615{
616	packageList="$(2[1])"
617
618	# make Haiku cross devel package path absolute
619	haikuCrossDevelPackage="$(2[2])"
620	if [ "x$haikuCrossDevelPackage" = "x${haikuCrossDevelPackage#/}" ]; then
621		haikuCrossDevelPackage="`pwd`/$haikuCrossDevelPackage"
622	fi
623
624	# make secondary Haiku cross devel packages path absolute
625	secondaryCrossDevelPackages=
626	if [ -n "$(2[3-]:J)" ]; then
627		for secondaryCrossDevelPackage in "$(2[3-])" ; do
628			if [ "x$secondaryCrossDevelPackage" = "x${secondaryCrossDevelPackage#/}" ]; then
629				secondaryCrossDevelPackage="`pwd`/$secondaryCrossDevelPackage"
630			fi
631			if [ -n "$secondaryCrossDevelPackages" ]; then
632				secondaryCrossDevelPackages="secondaryCrossDevelPackages,$secondaryCrossDevelPackage"
633			else
634				secondaryCrossDevelPackages="--secondary-cross-devel-package=$secondaryCrossDevelPackage"
635			fi
636		done
637	fi
638
639	cd $(HAIKU_REPOSITORY_BUILD_DIRECTORY)
640
641	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
642	if [ -n "$secondaryCrossDevelPackages" ]; then
643		$(HOST_HAIKU_PORTER) --cross-devel-package "$haikuCrossDevelPackage" \
644			"$secondaryCrossDevelPackages" \
645			$(HAIKU_PORTER_EXTRA_OPTIONS) \
646			--create-source-packages-for-bootstrap --portsfile $packageList
647	else
648		$(HOST_HAIKU_PORTER) --cross-devel-package "$haikuCrossDevelPackage" \
649			$(HAIKU_PORTER_EXTRA_OPTIONS) \
650			--create-source-packages-for-bootstrap --portsfile $packageList
651	fi
652}
653
654
655rule BuildHaikuPortsRepositoryConfig treePath
656{
657	local architecture = $(TARGET_PACKAGING_ARCH) ;
658	local outputDir = [ FDirName
659		$(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture))
660		HaikuPorts-bootstrap ] ;
661
662	local configFile = <repository-config-HaikuPorts-bootstrap>haikuports.conf ;
663	MakeLocate $(configFile) : $(outputDir) ;
664	NoUpdate $(configFile) ;
665
666	HAIKU_REPOSITORY_TREE_PATH on $(configFile) = $(treePath) ;
667	BuildHaikuPortsRepositoryConfig1 $(configFile) ;
668
669	return $(configFile) ;
670}
671
672
673actions BuildHaikuPortsRepositoryConfig1
674{
675	# use a specific packager for continuous integration builds (buildbot)
676	if [ "$(HAIKU_CONTINUOUS_INTEGRATION_BUILD)" = "1" ]; then
677		echo 'PACKAGER="Haiku buildmaster <buildmaster@haiku-os.org>"' > $(1)
678	else
679		echo '#PACKAGER="Joe Hacker <user@host.com>"' > $(1)
680	fi
681	cat >> $(1) << EOF
682TREE_PATH="$(HAIKU_REPOSITORY_TREE_PATH)"
683TARGET_ARCHITECTURE="$(HAIKU_PACKAGING_ARCH)"
684EOF
685}
686
687
688rule UploadPackages target : packages
689{
690	local packageListFile = <repository-package-list>HaikuPorts-packages ;
691	Depends $(target) : $(packageListFile) ;
692
693	HAIKU_REMOTE_REPOSITORY_PACKAGES on $(target) = $(packages) ;
694	UploadPackages1 $(target) : $(packageListFile) ;
695}
696
697
698actions UploadPackages1
699{
700	remote=git.haiku-os.org
701	remoteUser=$(HAIKU_REMOTE_USER)
702	if [ -n "$remoteUser" ]; then
703		remote="$remoteUser@$remote"
704	fi
705
706	if [ -n "$(HAIKU_REMOTE_REPOSITORY_PACKAGES:E=:J)" ]; then
707		for package in $(HAIKU_REMOTE_REPOSITORY_PACKAGES) ; do
708			file=`basename $package`
709			if ! grep -q $file $(2); then
710				echo "Error: $file is not being referenced in $(2)"
711				exit 1
712			fi
713		done
714		ssh $remote mkdir -p 'hpkg-upload'
715		scp $(HAIKU_REMOTE_REPOSITORY_PACKAGES) $remote:hpkg-upload/
716	fi
717}
718
719
720rule BuildRemoteHaikuPortsRepository target : packages
721{
722	UploadPackages $(target) : $(packages) ;
723
724	local packageListFile = <repository-package-list>HaikuPorts-packages ;
725	BuildRemoteHaikuPortsRepository1 $(target) : $(packageListFile) ;
726}
727
728
729actions BuildRemoteHaikuPortsRepository1
730{
731	remote=git.haiku-os.org
732	remoteUser=$(HAIKU_REMOTE_USER)
733	if [ -n "$remoteUser" ]; then
734		remote="$remoteUser@$remote"
735	fi
736
737	repoArch=$(TARGET_PACKAGING_ARCH)
738	scp $(2) $remote:hpkg-upload/$repoArch
739
740	cd $(HAIKU_TOP)
741	branch=`git branch | cut -c3-`
742
743	ssh $remote "build_repository_for_testing.sh $branch $repoArch"
744}
745
746
747rule HaikuRepository repository : repoInfoTemplate : packages : url
748	: versionFile
749{
750	# HaikuRepository <repository> : <repoInfoTemplate> : <packages>
751	#	[ : <url> [ : <versionFile> ] ] ;
752	# Builds the Haiku repository from the given packages and repository info
753	# template. <repository> must already be located.
754	#
755	# <repository> - The repository target. Resolves to a directory that will be
756	#	(removed,) created and populated with the package files and repository
757	#	meta data files.
758	# <repoInfoTemplate> - The repository info template file to be used.
759	# <packages> - The packages to be added to the repository.
760	# <url> - Optional repository URL for the repository config file to be
761	#	created. If not specified the one from the repository info is used.
762	# <versionFile> - Optional file containing the version string that shall
763	#	replace the "$version" placeholder in <url> (if any).
764
765	local architecture = $(HAIKU_PACKAGING_ARCH) ;
766	local secondaryArchitecture ;
767	if $(TARGET_PACKAGING_ARCH) != $(architecture) {
768		secondaryArchitecture = $(TARGET_PACKAGING_ARCH) ;
769	}
770
771	local repositoriesDir = $(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture)) ;
772
773	# build the repository info
774	local repoInfo = $(repository:G=repository-info)-info ;
775	MakeLocate $(repoInfo) : $(repositoriesDir) ;
776	PreprocessPackageOrRepositoryInfo $(repoInfo) : $(repoInfoTemplate)
777		: $(architecture) : $(secondaryArchitecture) ;
778
779	# build the respository config
780	local repositoryConfig = $(repository:G=repository-config)-config ;
781	MakeLocate $(repositoryConfig) : $(repositoriesDir) ;
782	RepositoryConfig $(repositoryConfig) : $(repoInfo) : $(url)
783		: $(versionFile) ;
784	HAIKU_REPOSITORY_CONFIG_FILE on $(repository) = $(repositoryConfig) ;
785
786	# prepare the script that initializes the shell variables
787	local initVariablesScript = $(repository)-repository-init-vars ;
788	MakeLocate $(initVariablesScript)
789		: $(HAIKU_PACKAGE_REPOSITORIES_DIR_$(architecture)) ;
790	Always $(initVariablesScript) ;
791
792	local script = $(initVariablesScript) ;
793	AddVariableToScript $(script) : addBuildCompatibilityLibDir
794		: $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) ;
795	AddVariableToScript $(script) : sha256 : $(HOST_SHA256) ;
796	AddVariableToScript $(script) : sedExtendedRegex
797		: $(HOST_EXTENDED_REGEX_SED) ;
798	AddTargetVariableToScript $(script) : <build>package ;
799	AddTargetVariableToScript $(script) : <build>package_repo : packageRepo ;
800
801	# call the build actions
802	local mainScript = build_haiku_repository ;
803	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
804
805	Depends $(repository) : $(mainScript) $(initVariablesScript) $(repoInfo)
806		$(packages) ;
807	HaikuRepository1 $(repository) : $(mainScript) $(initVariablesScript)
808		$(repoInfo) $(packages) ;
809	Always $(repository) ;
810
811	RmTemps $(repository) : $(initVariablesScript) ;
812}
813
814
815actions HaikuRepository1
816{
817	$(2[1]) "$(2[2])" "$(1)" "$(2[3-])"
818}
819