xref: /haiku/build/jam/ImageRules (revision b30304acc8c37e678a1bf66976d15bdab103f931)
1rule FSameTargetWithPrependedGrist
2{
3	# SameTargetWithPrependedGrist <target> : <grist to prepend> ;
4	#
5	local target = $(1) ;
6	local gristToPrepend = $(2) ;
7	local grist = $(target:G) ;
8
9	if $(grist) {
10		grist = $(gristToPrepend)!$(grist) ;
11	} else {
12		grist = $(gristToPrepend) ;
13	}
14
15	return $(target:G=$(grist)) ;
16}
17
18rule InitScript
19{
20	# Note: The script must have been LOCATEd before.
21	local script = $(1) ;
22	local initScript
23		= [ FSameTargetWithPrependedGrist $(script) : init-script ] ;
24
25	if ! [ on $(script) return $(__is_initialized) ] {
26		__is_initialized on $(script) = true ;
27
28		MakeLocate $(initScript) : [ on $(script) return $(LOCATE) ] ;
29		Always $(initScript) ;
30		Depends $(script) : $(initScript) ;
31
32		InitScript1 $(initScript) ;
33	}
34
35	return $(initScript) ;
36}
37
38actions InitScript1
39{
40	$(RM) $(1)
41	touch $(1)
42}
43
44rule AddVariableToScript script : variable : value
45{
46	# AddVariableToScript <script> : <variable> : <value> ;
47
48	# interpret an empty variable value as empty string
49	if ! $(value) {
50		value = "" ;
51	}
52
53	InitScript $(script) ;
54
55	VARIABLE_DEFS on $(script) += "echo $(variable)=\\\"$(value[1])\\\" >> " ;
56
57	# if the value is an array, add the other array elements
58	value = $(value[2-]) ;
59	while $(value) {
60		VARIABLE_DEFS on $(script)
61			+= "echo $(variable)=\\\" \\\$$(variable) $(value[1])\\\" >> " ;
62		value = $(value[2-]) ;
63	}
64
65	AddVariableToScript1 $(script) ;
66}
67
68actions together AddVariableToScript1
69{
70	$(VARIABLE_DEFS)$(1);
71}
72
73rule AddTargetVariableToScript
74{
75	# AddTargetVariableToScript <script> : <target> [ : <variable> ] ;
76	#
77	local script = $(1) ;
78	local target = $(2) ;
79	local variable = $(3:E=$(target:BS)) ;
80
81	InitScript $(script) ;
82
83	# That's not completely save, if one has more than on target with the
84	# same base name. A unique pseudo target would have to be introduced
85	# to do it more correctly.
86	VARIABLE_NAME($(target:BS)) on $(script) = $(variable) ;
87
88	Depends $(script) : $(target) ;
89	AddTargetVariableToScript1 $(script) : $(target) ;
90}
91
92actions AddTargetVariableToScript1
93{
94	echo "$(VARIABLE_NAME($(2:BS)))=\"$(2)\"" >> $(1)
95}
96
97
98#pragma mark -
99
100rule AddDirectoryToContainer container : directoryTokens
101{
102	# AddDirectoryToContainer <container> : <directoryTokens>
103
104	local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
105	local directory = [ FDirName $(directoryTokens) ] ;
106	directory = $(directory:G=$(containerGrist)) ;
107
108	if ! [ on $(directory) return $(__is_on_image) ] {
109		HAIKU_INSTALL_DIRECTORIES on $(container) += $(directory) ;
110		__is_on_image on $(directory) = true ;
111		DIRECTORY_TOKENS on $(directory) = $(directoryTokens) ;
112		NotFile $(directory) ;
113
114		# mark the parent dir as not to be created
115		local parent = [ FReverse $(directoryTokens) ] ;
116		parent = [ FReverse $(parent[2-]) ] ;
117		if $(parent) {
118			parent = [ FDirName $(parent) ] ;
119			parent = $(parent:G=$(containerGrist)) ;
120			DONT_CREATE on $(parent) = true ;
121		}
122	}
123
124	return $(directory) ;
125}
126
127rule FilterContainerUpdateTargets targets : filterVariable
128{
129	# FilterContainerUpdateTargets targets : filterVariable
130
131	local filteredTargets ;
132	local target ;
133	for target in $(targets) {
134		if [ on $(target) return $($(filterVariable)) ] {
135			filteredTargets += $(target) ;
136		}
137	}
138	return $(filteredTargets) ;
139}
140
141rule AddFilesToContainer container : directoryTokens : targets : destName
142{
143	# AddFilesToContainer <container> : <directoryTokens> : <targets>
144	#	[ : dest name ]
145	#
146	local directory = [ AddDirectoryToContainer $(container)
147		: $(directoryTokens) ] ;
148	local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
149
150	# If the image shall only be updated, we filter out all targets not marked
151	# accordingly.
152	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] {
153		local filterVar
154			= [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ;
155		if $(filterVar) {
156			targets = [ FilterContainerUpdateTargets $(targets)
157				: $(filterVar) ] ;
158		}
159	}
160
161	# We create a unique dummy target per target to install.
162	local installTargetsVar
163		= [ on $(container) return $(HAIKU_INSTALL_TARGETS_VAR) ] ;
164	local target ;
165	for target in $(targets) {
166		local name ;
167		if $(destName) {
168			name = $(destName) ;
169		} else {
170			name = $(target:G=:D=) ;
171		}
172
173		local destTarget = $(name:G=$(containerGrist)__$(directory:G=)) ;
174		TARGET on $(destTarget) = $(target) ;
175		INSTALL_DIR on $(destTarget) = $(directory) ;
176		$(installTargetsVar) on $(target) += $(destTarget) ;
177		TARGETS_TO_INSTALL on $(directory) += $(destTarget) ;
178	}
179}
180
181rule FFilesInContainerDirectory container : directoryTokens
182{
183	local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
184	local directory = [ FDirName $(directoryTokens) ] ;
185	directory = $(directory:G=$(containerGrist)) ;
186
187	if [ on $(directory) return $(__is_on_image) ] {
188		on $(directory) return $(TARGETS_TO_INSTALL) ;
189	}
190
191	return ;
192}
193
194rule AddSymlinkToContainer container : directoryTokens : linkTarget : linkName
195{
196	# AddSymlinkToContainer <container> : <directory> : <link target>
197	#	[ : <link name> ] ;
198	#
199
200	# If the image shall only be updated, we don't add any symlinks.
201	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] {
202		return ;
203	}
204
205	local directory = [ AddDirectoryToContainer $(container)
206		: $(directoryTokens) ] ;
207
208	if ! $(linkName) {
209		local path = [ FReverse [ FSplitPath $(linkTarget) ] ] ;
210		linkName = $(path[1]) ;
211	}
212
213	local link = $(directory)/$(linkName) ;
214	SYMLINK_TARGET on $(link) = $(linkTarget) ;
215	SYMLINKS_TO_INSTALL on $(directory) += $(link) ;
216}
217
218rule FSymlinksInContainerDirectory container : directoryTokens
219{
220	local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
221	local directory = [ FDirName $(directoryTokens) ] ;
222	directory = $(directory:G=$(containerGrist)) ;
223
224	if [ on $(directory) return $(__is_on_image) ] {
225		on $(directory) return $(SYMLINKS_TO_INSTALL) ;
226	}
227
228	return ;
229}
230
231rule CopyDirectoryToContainer container : directoryTokens : sourceDirectory
232	: targetDirectoryName : excludePatterns : alwaysUpdate
233{
234	# CopyDirectoryToContainer <container> : <directoryTokens>
235	#	: <sourceDirectory> : <targetDirectoryName> : <excludePatterns>
236	#	: <alwaysUpdate> ;
237	#
238
239	# If the image shall only be updated, we don't copy any directories
240	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
241			&& ! $(alwaysUpdate) {
242		return ;
243	}
244
245	if ! $(targetDirectoryName) {
246		local path = [ FReverse [ FSplitPath $(sourceDirectory) ] ] ;
247		targetDirectoryName = $(path[1]) ;
248	}
249
250	local directory = [ AddDirectoryToContainer $(container)
251		: $(directoryTokens) $(targetDirectoryName) ] ;
252
253	local targetDir = $(directory)/-/$(sourceDirectory) ;
254	EXCLUDE_PATTERNS on $(targetDir) = $(excludePatterns) ;
255	SOURCE_DIRECTORY on $(targetDir) = $(sourceDirectory) ;
256	TARGET_DIRECTORY on $(targetDir) = $(directory) ;
257	DIRECTORIES_TO_INSTALL on $(directory) += $(targetDir) ;
258}
259
260rule UnzipArchiveToContainer container : directoryTokens : zipFile
261{
262	# UnzipArchiveToContainer <container> : <directory> : <zipFile> ] ;
263	#
264
265	local directory = [ AddDirectoryToContainer $(container)
266		: $(directoryTokens) ] ;
267
268	ZIP_FILES_TO_INSTALL on $(directory) += $(zipFile) ;
269}
270
271rule AddDriversToContainer container : relativeDirectoryTokens : targets
272{
273	# AddDriversToContainer <container> : <relative directory> : <targets> ;
274	#
275	local directoryTokens = beos system add-ons kernel drivers dev
276		$(relativeDirectoryTokens) ;
277
278	AddFilesToContainer $(container) : beos system add-ons kernel drivers bin
279		: $(targets) ;
280
281	# If the image shall only be updated, we don't add any symlinks.
282	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] {
283		return ;
284	}
285
286	# get the relative symlink path prefix
287	local linkPrefix = ;
288	for i in $(relativeDirectoryTokens) {
289		linkPrefix += .. ;
290	}
291	linkPrefix += .. bin ;
292
293	# add the symlinks
294	local name ;
295	for name in $(targets:BS) {
296		AddSymlinkToContainer $(container) : $(directoryTokens)
297			: [ FDirName $(linkPrefix) $(name) ] : $(name) ;
298	}
299}
300
301rule AddDriverRegistrationToContainer container : relativeDirectoryTokens
302	: target : links
303{
304	# AddDriverRegistrationToContainer <container> : <directory>
305	#	: <link target> : <link names> ] ;
306	#
307	local directoryTokens = beos system add-ons kernel registration
308		$(relativeDirectoryTokens) ;
309
310	# get the relative symlink path prefix
311	local linkPrefix = ;
312	for i in $(relativeDirectoryTokens) {
313		linkPrefix += .. ;
314	}
315	linkPrefix += .. drivers bin ;
316
317	# add the symlink
318	AddSymlinkToContainer $(container) : $(directoryTokens)
319		: [ FDirName $(linkPrefix) $(target:BS) ] : $(links) ;
320}
321
322rule AddBootModuleSymlinksToContainer container : targets
323{
324	# AddBootModuleSymlinksToContainer <container> : <targets> ;
325	#
326
327	# If the image shall only be updated, we don't add any symlinks.
328	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] {
329		return ;
330	}
331
332	# add the symlinks
333	local installTargetsVar
334		= [ on $(container) return $(HAIKU_INSTALL_TARGETS_VAR) ] ;
335	local target ;
336	for target in $(targets) {
337		# Symlink to the first place where the target has been installed.
338		local destTarget = [ on $(target) return $($(installTargetsVar)[1]) ] ;
339		local installDir = [ on $(destTarget) return $(INSTALL_DIR) ] ;
340
341		if ! $(installDir) {
342			Echo "ERROR: AddBootModuleSymlinksToContainer: Can't create a "
343				"symlink to target" \"$(target)"\"." ;
344			Exit "ERROR: Add*ToContainer has not been invoked for it yet." ;
345		}
346
347		local name = $(target:BS) ;
348		local linkTarget = [ FDirName /boot $(installDir:G=) $(name) ] ;
349
350		AddSymlinkToContainer $(container) : beos system add-ons kernel boot
351			: $(linkTarget) : $(name) ;
352	}
353}
354
355
356rule CreateContainerMakeDirectoriesScript container : script
357{
358	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
359	Always $(script) ;
360
361	local initScript = [ InitScript $(script) ] ;
362
363	local scriptBody
364		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
365	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
366	Depends $(scriptBody) : $(initScript) ;
367	Depends $(script) : $(scriptBody) ;
368
369	# collect the directories to create
370	local dirsToCreate ;
371	local directories = [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] ;
372	local dir ;
373	for dir in $(directories) {
374		if ! [ on $(dir) return $(DONT_CREATE) ] {
375			dirsToCreate += $(dir) ;
376		}
377	}
378
379	# If the image shall only be updated, we don't create directories.
380	if $(dirsToCreate)
381		&& ! [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ] {
382		Depends $(scriptBody) : $(dirsToCreate) ;
383		CreateContainerMakeDirectoriesScript1 $(scriptBody) : $(dirsToCreate) ;
384
385		# For directories with attributes, we convert those the specified
386		# resource files to files with attributes and add commands to the script
387		# adding the attributes to the directories.
388		for dir in $(directories) {
389			local resourceFiles = [ on $(dir) return $(ATTRIBUTE_FILES) ] ;
390			if $(resourceFiles) {
391				local dirTokens = [ on $(dir) return $(DIRECTORY_TOKENS) ] ;
392
393				# translate resources file to file with attributes
394				local attributeFile = $(script)-attributes-$(dirTokens:J=-) ;
395				ResAttr $(attributeFile) : $(resourceFiles) ;
396
397				# use a unique dummy target for this file, on which we
398				# can define the TARGET_DIR variable
399				local dummyTarget = $(script)-attributes-dummy-$(dir:G=) ;
400				NotFile $(dummyTarget) ;
401				TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
402
403				Depends $(dummyTarget) : $(initScript) $(attributeFile) ;
404				Depends $(script) : $(dummyTarget) ;
405
406				AppendToContainerMakeDirectoriesScriptAttributes $(dummyTarget)
407					: $(initScript) $(attributeFile) ;
408			}
409		}
410	}
411}
412
413actions piecemeal CreateContainerMakeDirectoriesScript1
414{
415	echo \$mkdir -p "\"\${tPrefix}$(2:G=)\"" >> $(1)
416}
417
418actions AppendToContainerMakeDirectoriesScriptAttributes
419{
420	echo \$copyAttrs "\"\${sPrefix}$(2[2])\"" \
421		"\"\${tPrefix}$(TARGET_DIR)\"" >> $(2[1])
422}
423
424rule CreateContainerCopyFilesScript container : script
425{
426	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
427	Always $(script) ;
428
429	local initScript = [ InitScript $(script) ] ;
430
431	local scriptBody
432		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
433	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
434	Depends $(scriptBody) : $(initScript) ;
435	Depends $(script) : $(scriptBody) ;
436
437	local dir ;
438	for dir in [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] {
439		# filter the targets that shall be renamed; they have to be copied
440		# individually
441		local destTargets = [ on $(dir) return $(TARGETS_TO_INSTALL) ] ;
442		local remainingTargets ;
443		local destTarget ;
444		for destTarget in $(destTargets) {
445			local target = [ on $(destTarget) return $(TARGET) ] ;
446			local name = $(destTarget:BS) ;
447			if $(name) != $(target:BS) {
448				# use a unique dummy target for this file, on which we
449				# can define the TARGET_DIR variable
450				local dummyTarget = $(script)-dummy-$(dir:G=)-$(target) ;
451				NotFile $(dummyTarget) ;
452				TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
453				INSTALL_TARGET_NAME on $(dummyTarget) = $(name) ;
454
455				Depends $(dummyTarget) : $(initScript) $(target) ;
456				Depends $(script) : $(dummyTarget) ;
457
458				AppendToContainerCopyFilesScriptSingleFile $(dummyTarget)
459					: $(initScript) $(target) ;
460			} else {
461				remainingTargets += $(target) ;
462			}
463		}
464		targets = $(remainingTargets) ;
465
466		if $(targets) {
467			# use a unique dummy target for this directory, on which we
468			# can define the TARGET_DIR variable
469			local dummyTarget = $(script)-dummy-$(dir:G=) ;
470			NotFile $(dummyTarget) ;
471			TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
472
473			Depends $(dummyTarget) : $(initScript) $(targets) ;
474			Depends $(script) : $(dummyTarget) ;
475
476			OUTPUT_SCRIPT on $(dummyTarget) = $(initScript) ;
477			AppendToContainerCopyFilesScript $(dummyTarget) : $(targets) ;
478		}
479
480		local symlinks = [ on $(dir) return $(SYMLINKS_TO_INSTALL) ] ;
481		local symlink ;
482		for symlink in $(symlinks) {
483			NotFile $(symlink) ;
484
485			Depends $(script) : $(symlink) ;
486			Depends $(symlink) : $(initScript) ;
487
488			AddSymlinkToContainerCopyFilesScript $(symlink) : $(initScript) ;
489		}
490
491		local targetDirs = [ on $(dir) return $(DIRECTORIES_TO_INSTALL) ] ;
492		local targetDir ;
493		for targetDir in $(targetDirs) {
494			NotFile $(targetDir) ;
495
496			Depends $(script) : $(targetDir) ;
497			Depends $(targetDir) : $(initScript) ;
498
499			AddDirectoryToContainerCopyFilesScript $(targetDir) : $(initScript) ;
500		}
501	}
502}
503
504actions piecemeal AppendToContainerCopyFilesScript bind OUTPUT_SCRIPT
505{
506	echo \$cp "\"\${sPrefix}$(2)\"" "\"\${tPrefix}$(TARGET_DIR)\"" >> $(OUTPUT_SCRIPT)
507}
508
509actions AppendToContainerCopyFilesScriptSingleFile
510{
511	echo \$cp "\"\${sPrefix}$(2[2])\"" \
512		"\"\${tPrefix}$(TARGET_DIR)/$(INSTALL_TARGET_NAME)\"" >> $(2[1])
513}
514
515actions AddSymlinkToContainerCopyFilesScript
516{
517	echo \$ln -sfn "\"$(SYMLINK_TARGET)\"" "\"\${tPrefix}$(1:G=)\"" >> $(2[1])
518}
519
520actions AddDirectoryToContainerCopyFilesScript
521{
522	echo \$cp -r $(EXCLUDE_PATTERNS) "\"\${sPrefix}$(SOURCE_DIRECTORY)/.\"" \
523		"\"\${tPrefix}$(TARGET_DIRECTORY:G=)\"" >> $(2[1])
524}
525
526
527rule CreateContainerUnzipFilesScript container : script
528{
529	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
530	Always $(script) ;
531
532	local initScript = [ InitScript $(script) ] ;
533
534	local scriptBody
535		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
536	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
537	Depends $(scriptBody) : $(initScript) ;
538	Depends $(script) : $(scriptBody) ;
539
540	local dir ;
541	for dir in [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] {
542		local zipFiles = [ on $(dir) return $(ZIP_FILES_TO_INSTALL) ] ;
543		local zipFile ;
544		for zipFile in $(zipFiles) {
545			# use a unique dummy target for this file, on which we
546			# can define the TARGET_DIR variable
547			local dummyTarget = $(script)-dummy-$(dir:G=)-$(zipFile) ;
548			NotFile $(dummyTarget) ;
549			TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
550
551			Depends $(dummyTarget) : $(initScript) $(zipFile) ;
552			Depends $(script) : $(dummyTarget) ;
553
554			AddUnzipFileToContainerUnzipFilesScript $(dummyTarget)
555				: $(initScript) $(zipFile) ;
556		}
557	}
558}
559
560actions AddUnzipFileToContainerUnzipFilesScript
561{
562	echo unzipFile "\"$(2[2])\"" "\"$(TARGET_DIR)\"" >> $(2[1])
563}
564
565
566#pragma mark - Haiku Image rules
567
568rule SetUpdateHaikuImageOnly flag
569{
570	HAIKU_CONTAINER_UPDATE_ONLY on $(HAIKU_IMAGE_CONTAINER_NAME) = $(flag) ;
571}
572
573rule IsUpdateHaikuImageOnly
574{
575	on $(HAIKU_IMAGE_CONTAINER_NAME) return $(HAIKU_CONTAINER_UPDATE_ONLY) ;
576}
577
578rule AddDirectoryToHaikuImage directoryTokens : attributeFiles
579{
580	# AddDirectoryToHaikuImage <directoryTokens>
581
582	local dir = [ AddDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
583		: $(directoryTokens) ] ;
584
585	if $(attributeFiles) {
586		SEARCH on $(attributeFiles)
587			+= [ FDirName $(HAIKU_TOP) data image_directories ] ;
588		ATTRIBUTE_FILES on $(dir) += $(attributeFiles) ;
589	}
590
591	return $(dir) ;
592}
593
594rule AddFilesToHaikuImage directory : targets : destName
595{
596	# AddFilesToHaikuImage <directory> : <targets> [ : dest name ]
597
598	AddFilesToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directory)
599		: $(targets) : $(destName) ;
600}
601
602rule FFilesInHaikuImageDirectory directoryTokens
603{
604	return [ FFilesInContainerDirectory $(HAIKU_IMAGE_CONTAINER_NAME)
605		: $(directoryTokens) ] ;
606}
607
608rule AddSymlinkToHaikuImage directoryTokens : linkTarget : linkName
609{
610	# AddSymlinkToHaikuImage <directory> : <link target> [ : <link name> ] ;
611
612	AddSymlinkToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens)
613		: $(linkTarget) : $(linkName) ;
614}
615
616rule FSymlinksInHaikuImageDirectory directoryTokens
617{
618	return [ FSymlinksInContainerDirectory $(HAIKU_IMAGE_CONTAINER_NAME)
619		: $(directoryTokens) ] ;
620}
621
622rule CopyDirectoryToHaikuImage directoryTokens : sourceDirectory
623	: targetDirectoryName : excludePatterns : alwaysUpdate
624{
625	CopyDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens)
626		: $(sourceDirectory) : $(targetDirectoryName) : $(excludePatterns)
627		: $(alwaysUpdate) ;
628}
629
630rule AddSourceDirectoryToHaikuImage dirTokens : alwaysUpdate
631{
632	# AddSourceDirectoryToHaikuImage <dirTokens> : <alwaysUpdate> ;
633
634	CopyDirectoryToHaikuImage home HaikuSources
635		: [ FDirName $(HAIKU_TOP) $(dirTokens) ]
636		: : -x .svn : $(alwaysUpdate) ;
637}
638
639rule AddHeaderDirectoryToHaikuImage dirTokens : dirName : alwaysUpdate
640{
641	# AddHeaderDirectoryToHaikuImage <dirTokens> : [ <dirName> ]
642	#	: <alwaysUpdate> ;
643
644	CopyDirectoryToHaikuImage develop headers
645		: [ FDirName $(HAIKU_TOP) headers $(dirTokens) ]
646		: $(dirName) : -x .svn : $(alwaysUpdate) ;
647}
648
649rule UnzipArchiveToHaikuImage dirTokens : zipFile : alwaysUpdate
650{
651	# UnzipArchiveToHaikuImage <dirTokens> : <zipFile> : <alwaysUpdate> ;
652
653	# If the image shall only be updated, we unzip only, if explicitely
654	# requested.
655	if ! [ IsUpdateHaikuImageOnly ] || $(alwaysUpdate) {
656		UnzipArchiveToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(dirTokens)
657			: $(zipFile) ;
658	}
659}
660
661rule AddDriversToHaikuImage relativeDirectoryTokens : targets
662{
663	# AddDriversToHaikuImage <relative directory> : <targets> ;
664
665	AddDriversToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
666		: $(relativeDirectoryTokens) : $(targets) ;
667}
668
669rule AddDriverRegistrationToHaikuImage relativeDirectoryTokens : target : links
670{
671	# AddDriverRegistrationToHaikuImage <directory> : <link target> : <link names> ] ;
672
673	AddDriverRegistrationToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
674		: $(relativeDirectoryTokens) : $(target) : $(links) ;
675}
676
677rule AddBootModuleSymlinksToHaikuImage targets
678{
679	# AddBootModuleSymlinksToHaikuImage <targets> ;
680
681	AddBootModuleSymlinksToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
682		: $(targets) ;
683}
684
685rule AddOptionalHaikuImagePackages packages
686{
687	HAIKU_OPTIONAL_PACKAGE_ADDED on $(packages) = 1 ;
688}
689
690rule IsOptionalHaikuImagePackageAdded package
691{
692	if [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] {
693		return 1 ;
694	}
695
696	return $(HAIKU_ADD_ALL_OPTIONAL_PACKAGES) ;
697}
698
699rule OptionalPackageDependencies package : dependencies
700{
701	if [ IsOptionalHaikuImagePackageAdded $(package) ] {
702		AddOptionalHaikuImagePackages $(dependencies) ;
703	}
704}
705
706rule InstallOptionalHaikuImagePackage package : url : dirTokens
707{
708	# download zip file
709	local zipFile = $(package:G=download).zip ;
710	MakeLocate $(zipFile) : $(HAIKU_DOWNLOAD_DIR) ;
711	DownloadFile $(zipFile) : $(url) ;
712
713	# unzip onto image
714	UnzipArchiveToHaikuImage $(dirTokens) : $(zipFile) ;
715}
716
717rule AddEntryToHaikuImageUserGroupFile file : entry
718{
719	local allEntries = [ on $(file) return $(HAIKU_IMAGE_USER_GROUP_ENTRIES) ] ;
720
721	if $(allEntries) {
722		allEntries = $(allEntries)|$(entry) ;
723	} else {
724		allEntries = $(entry) ;
725
726		Always $(file) ;
727		MakeLocate $(file) : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ;
728		BuildHaikuImageUserGroupFile $(file) ;
729		AddFilesToHaikuImage beos etc : $(file) ;
730	}
731
732	HAIKU_IMAGE_USER_GROUP_ENTRIES on $(file) = $(allEntries) ;
733}
734
735actions BuildHaikuImageUserGroupFile
736{
737	echo "$(HAIKU_IMAGE_USER_GROUP_ENTRIES)" | tr '|' '\n' > $(1)
738}
739
740rule AddUserToHaikuImage user : uid : gid : home : shell : realName
741{
742	if ! $(user) || ! $(uid) || ! $(gid) || ! $(home) {
743		Exit "Invalid haiku user specification passed to AddUserToHaikuImage." ;
744	}
745
746	local entry
747		= $(user):x:$(uid):$(gid):$(realName:E=$(user)):$(home):$(shell:E="") ;
748
749	AddEntryToHaikuImageUserGroupFile <haiku-image>passwd : $(entry) ;
750}
751
752rule AddGroupToHaikuImage group : gid : members
753{
754	if ! $(group) || ! $(gid) {
755		Exit "Invalid haiku group specification passed to"
756			"AddGroupToHaikuImage." ;
757	}
758
759	local entry = $(group):x:$(gid):$(members:J=,:E) ;
760
761	AddEntryToHaikuImageUserGroupFile <haiku-image>group : $(entry) ;
762}
763
764rule AddOptionalPackageDescriptionToHaikuImage file : searchPath
765{
766	if $(searchPath) {
767		SEARCH on $(file) = [ FDirName $(searchPath) ] ;
768	}
769
770	HAIKU_IMAGE_OPTIONAL_PACKAGE_DESCRIPTIONS += $(file) ;
771}
772
773rule AddLicenseToHaikuImage file : name : searchPath
774{
775	if $(searchPath) {
776		SEARCH on $(file) = [ FDirName $(searchPath) ] ;
777	}
778
779	if $(name) && $(file:BS) = $(name) {
780		name = ;
781	}
782
783	AddFilesToHaikuImage beos etc licenses : $(file) : $(name) ;
784}
785
786
787rule CreateHaikuImageMakeDirectoriesScript script
788{
789	CreateContainerMakeDirectoriesScript $(HAIKU_IMAGE_CONTAINER_NAME)
790		: $(script) ;
791}
792
793rule CreateHaikuImageCopyFilesScript script
794{
795	CreateContainerCopyFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ;
796}
797
798rule CreateHaikuImageUnzipFilesScript script
799{
800	CreateContainerUnzipFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ;
801}
802
803rule BuildHaikuImage haikuImage : scripts : isImage : isVMwareImage
804{
805	# BuildHaikuImage <haiku image> : <scripts> : <is image> : <isVMwareImage> ;
806
807	if $(isImage) = 1 || $(isImage) = true {
808		IS_IMAGE on $(haikuImage) = 1 ;
809	} else {
810		IS_IMAGE on $(haikuImage) = "" ;
811	}
812
813	if $(isVMwareImage) = 1 || $(isVMwareImage) = true {
814		IS_VMWARE_IMAGE on $(haikuImage) = 1 ;
815	} else {
816		IS_VMWARE_IMAGE on $(haikuImage) = "" ;
817	}
818
819	local mainScript = build_haiku_image ;
820	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
821
822	Depends $(haikuImage) : $(mainScript) $(scripts) ;
823	BuildHaikuImage1 $(haikuImage) : $(mainScript) $(scripts) ;
824}
825
826actions BuildHaikuImage1
827{
828	export imagePath="$(1)"
829	export isImage="$(IS_IMAGE)"
830	export isVMwareImage="$(IS_VMWARE_IMAGE)"
831	$(2[1]) $(2[2-])
832}
833
834rule BuildVMWareImage vmwareImage : plainImage : imageSize
835{
836	# BuildVMWareImage <vmware image> : <plain image> : <image size in MB>
837
838	IMAGE_SIZE on $(vmwareImage) = $(imageSize) ;
839
840	Depends $(vmwareImage) : <build>vmdkheader $(plainImage) ;
841	BuildVMWareImage1 $(vmwareImage) : <build>vmdkheader $(plainImage) ;
842}
843
844actions BuildVMWareImage1
845{
846	$(RM) $(1)
847	$(2[1]) -h 64k -i$(IMAGE_SIZE)M $(1) &&
848	cat $(2[2]) >> $(1)
849}
850
851
852#pragma mark - Network Boot Archive rules
853
854rule AddDirectoryToNetBootArchive directoryTokens
855{
856	# AddDirectoryToNetBootArchive <directoryTokens>
857
858	return [ AddDirectoryToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
859		: $(directoryTokens) ] ;
860}
861
862rule AddFilesToNetBootArchive directory : targets : destName
863{
864	# AddFilesToNetBootArchive <directory> : <targets> [ : dest name ]
865
866	AddFilesToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(directory)
867		: $(targets) : $(destName) ;
868}
869
870rule AddSymlinkToNetBootArchive directoryTokens : linkTarget : linkName
871{
872	# AddSymlinkToNetBootArchive <directory> : <link target> [ : <link name> ] ;
873
874	AddSymlinkToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
875		: $(directoryTokens) : $(linkTarget) : $(linkName) ;
876}
877
878rule AddDriversToNetBootArchive relativeDirectoryTokens : targets
879{
880	# AddDriversToNetBootArchive <relative directory> : <targets> ;
881
882	AddDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
883		: $(relativeDirectoryTokens) : $(targets) ;
884}
885
886rule AddDriverRegistrationToNetBootArchive relativeDirectoryTokens : target
887	: links
888{
889	# AddDriverRegistrationToNetBootArchive <directory> : <link target>
890	#	: <link names> ] ;
891
892	AddDriverRegistrationToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
893		: $(relativeDirectoryTokens) : $(target) : $(links) ;
894}
895
896rule AddBootModuleSymlinksToNetBootArchive targets
897{
898	# AddBootModuleSymlinksToNetBootArchive <targets> ;
899
900	AddBootModuleSymlinksToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
901		: $(targets) ;
902}
903
904rule CreateNetBootArchiveMakeDirectoriesScript script
905{
906	CreateContainerMakeDirectoriesScript
907		$(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(script) ;
908}
909
910rule CreateNetBootArchiveCopyFilesScript script
911{
912	CreateContainerCopyFilesScript $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
913		: $(script) ;
914}
915
916rule BuildNetBootArchive archive : scripts
917{
918	# BuildHNetBootArchive <archive> : <scripts>  ;
919
920	local mainScript = build_tgz_archive ;
921	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
922
923	Depends $(archive) : $(mainScript) $(scripts) ;
924	BuildNetBootArchive1 $(archive) : $(mainScript) $(scripts) ;
925}
926
927actions BuildNetBootArchive1
928{
929	$(2[1]) $(1) $(2[2-])
930}
931
932
933#pragma mark - Floppy Boot Archive rules
934
935rule AddDirectoryToFloppyBootArchive directoryTokens
936{
937	# AddDirectoryToFloppyBootArchive <directoryTokens>
938
939	return [ AddDirectoryToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
940		: $(directoryTokens) ] ;
941}
942
943rule AddFilesToFloppyBootArchive directory : targets : destName
944{
945	# AddFilesToFloppyBootArchive <directory> : <targets> [ : dest name ]
946
947	AddFilesToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(directory)
948		: $(targets) : $(destName) ;
949}
950
951rule AddSymlinkToFloppyBootArchive directoryTokens : linkTarget : linkName
952{
953	# AddSymlinkToFloppyBootArchive <directory> : <link target> [ : <link name> ] ;
954
955	AddSymlinkToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
956		: $(directoryTokens) : $(linkTarget) : $(linkName) ;
957}
958
959rule AddDriversToFloppyBootArchive relativeDirectoryTokens : targets
960{
961	# AddDriversToFloppyBootArchive <relative directory> : <targets> ;
962
963	AddDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
964		: $(relativeDirectoryTokens) : $(targets) ;
965}
966
967rule AddDriverRegistrationToFloppyBootArchive relativeDirectoryTokens : target
968	: links
969{
970	# AddDriverRegistrationToFloppyBootArchive <directory> : <link target>
971	#	: <link names> ] ;
972
973	AddDriverRegistrationToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
974		: $(relativeDirectoryTokens) : $(target) : $(links) ;
975}
976
977rule AddBootModuleSymlinksToFloppyBootArchive targets
978{
979	# AddBootModuleSymlinksToFloppyBootArchive <targets> ;
980
981	AddBootModuleSymlinksToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
982		: $(targets) ;
983}
984
985rule CreateFloppyBootArchiveMakeDirectoriesScript script
986{
987	CreateContainerMakeDirectoriesScript
988		$(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(script) ;
989}
990
991rule CreateFloppyBootArchiveCopyFilesScript script
992{
993	CreateContainerCopyFilesScript $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
994		: $(script) ;
995}
996
997rule BuildFloppyBootArchive archive : scripts
998{
999	# BuildHFloppyBootArchive <archive> : <scripts>  ;
1000
1001	local mainScript = build_tgz_archive ;
1002	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
1003
1004	Depends $(archive) : $(mainScript) $(scripts) ;
1005	BuildFloppyBootArchive1 $(archive) : $(mainScript) $(scripts) ;
1006}
1007
1008actions BuildFloppyBootArchive1
1009{
1010	$(2[1]) $(1) $(2[2-])
1011}
1012
1013# warning: that is quite x86 dependant...
1014
1015rule BuildFloppyBootImage image : zbeos : archive
1016{
1017	Depends $(image) : $(zbeos) ;
1018	Depends $(image) : $(archive) ;
1019	#MakeLocateDebug $(image) ;
1020	BuildFloppyBootImage1 $(image) : $(zbeos) $(archive) ;
1021}
1022
1023actions BuildFloppyBootImage1
1024{
1025	$(RM) $(<)
1026	# make an empty image
1027	dd if=/dev/zero of=$(<) bs=1k count=1440
1028	# add zbeos
1029	dd if=$(>[1]) of=$(<) conv=notrunc
1030	# add the boot drivers tgz archive
1031	# keep the offset in sync with
1032	# src/system/boot/loader/file_systems/tarfs/tarfs.cpp:kFloppyArchiveOffset
1033	dd if=$(>[2]) of=$(<) bs=192k seek=1 conv=notrunc
1034}
1035
1036
1037#pragma mark - CD Boot Image rules
1038
1039rule BuildCDBootImage image : bootfloppy : extrafiles
1040{
1041	Depends $(image) : $(bootfloppy) ;
1042	Depends $(image) : $(extrafiles) ;
1043	BOOTIMG on $(image) = $(bootfloppy) ;
1044
1045	BuildCDBootImage1 $(image) : $(bootfloppy) $(extrafiles) ;
1046}
1047
1048actions BuildCDBootImage1
1049{
1050	$(RM) $(<)
1051	mkisofs -b $(BOOTIMG) -r -J -V bootimg -o $(<) $(>[1]) $(>[2-])
1052}
1053
1054
1055