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