xref: /haiku/build/jam/ImageRules (revision 204dee708a999d5a71d0cb9497650ee7cef85d0a)
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
73
74rule AddTargetVariableToScript script : targets : variable
75{
76	# AddTargetVariableToScript <script> : <targets> [ : <variable> ] ;
77	#
78	# If <targets> contains multiple targets, their paths must not contain
79	# whitespaces or other characters that need to be escaped in the shell.
80	#
81	variable ?= $(3:E=$(targets[1]:BS)) ;
82
83	local initScript = [ InitScript $(script) ] ;
84
85	serialization = [ on $(script) return $(HAIKU_SERIALIZATION) ] ;
86
87	local variableTarget = [ NewUniqueTarget ] ;
88	NotFile $(variableTarget) ;
89	Depends $(variableTarget) : $(initScript) $(targets) $(serialization) ;
90	Depends $(script) : $(variableTarget) ;
91
92	HAIKU_SERIALIZATION on $(script) = $(variableTarget) ;
93
94	HAIKU_VARIABLE_NAME on $(variableTarget) = $(variable) ;
95	AddTargetVariableToScript1 $(variableTarget) : $(initScript) $(targets) ;
96}
97
98
99actions AddTargetVariableToScript1
100{
101	script="$(2[1])"
102	echo "$(HAIKU_VARIABLE_NAME)=" >> "$script"
103
104	firstSeen=
105	for value in "$(2[2-])" ; do
106		if [ -z "$firstSeen" ]; then
107			echo "$(HAIKU_VARIABLE_NAME)=\"$value\"" >> "$script"
108			firstSeen=1
109		else
110			echo "$(HAIKU_VARIABLE_NAME)=\"\$$(HAIKU_VARIABLE_NAME) $value\"" \
111				>> "$script"
112		fi
113	done
114}
115
116
117#pragma mark -
118
119rule AddDirectoryToContainer container : directoryTokens : attributeFiles
120{
121	# AddDirectoryToContainer <container> : <directoryTokens> : <attributeFiles>
122
123	local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
124	local directory = [ FDirName $(directoryTokens) ] ;
125	directory = $(directory:G=$(containerGrist)) ;
126
127	if ! [ on $(directory) return $(__is_on_image) ] {
128		HAIKU_INSTALL_DIRECTORIES on $(container) += $(directory) ;
129		__is_on_image on $(directory) = true ;
130		DIRECTORY_TOKENS on $(directory) = $(directoryTokens) ;
131		NotFile $(directory) ;
132
133		# mark the parent dir as not to be created
134		local parent = [ FReverse $(directoryTokens) ] ;
135		parent = [ FReverse $(parent[2-]) ] ;
136		if $(parent) {
137			parent = [ FDirName $(parent) ] ;
138			parent = $(parent:G=$(containerGrist)) ;
139			DONT_CREATE on $(parent) = true ;
140		}
141	}
142
143	if $(attributeFiles) {
144		SEARCH on $(attributeFiles)
145			+= [ FDirName $(HAIKU_TOP) data image_directories ] ;
146		ATTRIBUTE_FILES on $(dir) += $(attributeFiles) ;
147	}
148
149	return $(directory) ;
150}
151
152rule FilterContainerUpdateTargets targets : filterVariable
153{
154	# FilterContainerUpdateTargets targets : filterVariable
155
156	local filteredTargets ;
157	local target ;
158	for target in $(targets) {
159		if [ on $(target) return $($(filterVariable)) ] {
160			filteredTargets += $(target) ;
161		}
162	}
163	return $(filteredTargets) ;
164}
165
166
167rule IncludeAllTargetsInContainer container
168{
169	local filterVar
170		= [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ;
171	if $(filterVar) {
172		return $($(filterVar)) ;
173	}
174
175	return ;
176}
177
178
179rule PropagateContainerUpdateTargetFlags toTarget : fromTarget
180{
181	if [ on $(fromTarget) return $(HAIKU_INCLUDE_IN_IMAGE) ] {
182		HAIKU_INCLUDE_IN_IMAGE on $(toTarget) = 1 ;
183	}
184
185	if [ on $(fromTarget) return $(HAIKU_INCLUDE_IN_PACKAGES) ] {
186		HAIKU_INCLUDE_IN_PACKAGES on $(toTarget) = 1 ;
187	}
188}
189
190
191rule AddFilesToContainer container : directoryTokens : targets : destName
192{
193	# AddFilesToContainer <container> : <directoryTokens> : <targets>
194	#	[ : dest name ]
195	#
196	local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
197	local systemDirTokens
198		= [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ;
199
200	targets = [ FFilterByBuildFeatures $(targets) ] ;
201
202	# If the image shall only be updated, we filter out all targets not marked
203	# accordingly.
204	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
205		&& ! [ IncludeAllTargetsInContainer $(container) ] {
206		local filterVar
207			= [ on $(container) return $(HAIKU_INCLUDE_IN_CONTAINER_VAR) ] ;
208		if $(filterVar) {
209			targets = [ FilterContainerUpdateTargets $(targets)
210				: $(filterVar) ] ;
211
212			# If there are any targets, mark the container as to be included in
213			# an update, too, if it has set the update inheritance variable.
214			# This makes updating a target that lives in a package on an image
215			# work.
216			if $(targets) {
217				local updateVariable = [ on $(container) return
218					$(HAIKU_CONTAINER_INHERIT_UPDATE_VARIABLE) ] ;
219				if $(updateVariable) {
220					$(updateVariable) on $(container) = 1 ;
221				}
222			}
223		}
224	}
225
226	if ! $(targets) {
227		return ;
228	}
229
230	local directory = [ AddDirectoryToContainer $(container)
231		: $(directoryTokens) ] ;
232
233	# We create a unique dummy target per target to install.
234	local installTargetsVar
235		= [ on $(container) return $(HAIKU_INSTALL_TARGETS_VAR) ] ;
236	local target ;
237	for target in $(targets) {
238		local name ;
239		if $(destName) {
240			name = $(destName) ;
241		} else {
242			name = $(target:G=:D=) ;
243		}
244
245		local destTarget = $(name:G=$(containerGrist)__$(directory:G=)) ;
246		TARGET on $(destTarget) = $(target) ;
247		INSTALL_DIR on $(destTarget) = $(directory) ;
248		$(installTargetsVar) on $(target) += $(destTarget) ;
249		TARGETS_TO_INSTALL on $(directory) += $(destTarget) ;
250
251		# If the target is associated with catalog files, add those, too.
252		local catalogs = [ on $(target) return $(HAIKU_CATALOG_FILES) ] ;
253		if $(catalogs) {
254			local signature
255				= [ on $(target) return $(HAIKU_CATALOG_SIGNATURE) ] ;
256			AddFilesToContainer $(container)
257				: $(systemDirTokens) data locale catalogs $(signature)
258				: $(catalogs) ;
259		}
260
261		# If the target is associated with MIME DB entries, add those, too.
262		local mimeDBEntries = [ on $(target) return $(HAIKU_MIME_DB_ENTRIES) ] ;
263		if $(mimeDBEntries) {
264			# Make sure we add the entries only once by tracking the containers
265			# we have already added it to.
266			local containers = [ on $(mimeDBEntries)
267				return $(HAIKU_MIME_DB_ENTRIES_IN_CONTAINERS) ] ;
268			if ! $(container) in $(containers) {
269				HAIKU_MIME_DB_ENTRIES_IN_CONTAINERS on $(mimeDBEntries)
270					= $(containers) $(container) ;
271	 			CopyDirectoryToContainer $(container) : data
272 					: $(mimeDBEntries) : mime_db : : alwaysUpdate isTarget ;
273 			}
274		}
275	}
276}
277
278rule FFilesInContainerDirectory container : directoryTokens
279{
280	local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
281	local directory = [ FDirName $(directoryTokens) ] ;
282	directory = $(directory:G=$(containerGrist)) ;
283
284	if [ on $(directory) return $(__is_on_image) ] {
285		on $(directory) return $(TARGETS_TO_INSTALL) ;
286	}
287
288	return ;
289}
290
291rule AddSymlinkToContainer container : directoryTokens : linkTarget : linkName
292{
293	# AddSymlinkToContainer <container> : <directory> : <link target>
294	#	[ : <link name> ] ;
295	#
296
297	# If the image shall only be updated, we don't add any symlinks.
298	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
299		&& ! [ IncludeAllTargetsInContainer $(container) ] {
300		return ;
301	}
302
303	local directory = [ AddDirectoryToContainer $(container)
304		: $(directoryTokens) ] ;
305
306	if ! $(linkName) {
307		local path = [ FReverse [ FSplitPath $(linkTarget) ] ] ;
308		linkName = $(path[1]) ;
309	}
310
311	local link = $(directory)/$(linkName) ;
312	SYMLINK_TARGET on $(link) = $(linkTarget) ;
313	SYMLINKS_TO_INSTALL on $(directory) += $(link) ;
314}
315
316rule FSymlinksInContainerDirectory container : directoryTokens
317{
318	local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
319	local directory = [ FDirName $(directoryTokens) ] ;
320	directory = $(directory:G=$(containerGrist)) ;
321
322	if [ on $(directory) return $(__is_on_image) ] {
323		on $(directory) return $(SYMLINKS_TO_INSTALL) ;
324	}
325
326	return ;
327}
328
329rule CopyDirectoryToContainer container : directoryTokens : sourceDirectory
330	: targetDirectoryName : excludePatterns : flags
331{
332	# CopyDirectoryToContainer <container> : <directoryTokens>
333	#	: <sourceDirectory> : <targetDirectoryName> : <excludePatterns>
334	#	[ : <flags> ] ;
335	#
336	# Supported flags: alwaysUpdate, isTarget
337	# isTarget: <sourceDirectory> is a target, not a path
338
339	# If the image shall only be updated, we don't copy any directories
340	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
341			&& ! [ IncludeAllTargetsInContainer $(container) ]
342			&& ! alwaysUpdate in $(flags) {
343		return ;
344	}
345
346	if ! $(targetDirectoryName) {
347		targetDirectoryName = $(sourceDirectory[1]:BS) ;
348	}
349
350	# If sourceDirectory is a path, not a target, make it a target, so we can
351	# treat both the same way.
352	if ! isTarget in $(flags) {
353		sourceDirectory = $(sourceDirectory:G=copy-directory-to-container) ;
354		SEARCH on $(sourceDirectory) = ;
355		TARGET on $(sourceDirectory) = ;
356	}
357
358	local directory = [ AddDirectoryToContainer $(container)
359		: $(directoryTokens) $(targetDirectoryName) ] ;
360
361	local targetDir = $(directory)/-/$(sourceDirectory) ;
362	Depends $(targetDir) : $(sourceDirectory) ;
363	EXCLUDE_PATTERNS on $(targetDir) = $(excludePatterns) ;
364	SOURCE_DIRECTORY on $(targetDir) = $(sourceDirectory) ;
365	TARGET_DIRECTORY on $(targetDir) = $(directory) ;
366	DIRECTORIES_TO_INSTALL on $(directory) += $(targetDir) ;
367}
368
369
370rule AddHeaderDirectoryToContainer container : dirTokens : dirName
371	: flags
372{
373	# AddHeaderDirectoryToContainer <container> : <dirTokens> : [ <dirName> ]
374	#	[ : <flags> ] ;
375	#
376	# Supported flags: alwaysUpdate
377
378	local systemDirTokens
379		= [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ;
380
381	CopyDirectoryToContainer $(container) : $(systemDirTokens) develop headers
382		: [ FDirName $(HAIKU_TOP) headers $(dirTokens) ]
383		: $(dirName) : -x .svn : $(flags) ;
384}
385
386
387rule AddWifiFirmwareToContainer container : driver : package : archive : extract
388{
389	# AddWifiFirmwareToContainer <container> : <driver> : <package> : <archive>
390	#	: <extract>
391
392	# complete location to wifi firmware archive
393	local firmwareArchive = [ FDirName
394		$(HAIKU_TOP) data system data firmware $(driver) $(archive) ] ;
395
396	local systemDirTokens
397		= [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ;
398
399	local dirTokens = $(systemDirTokens) data firmware $(driver) ;
400	if $(extract) = true || $(extract) = 1 {
401		ExtractArchiveToContainer $(container) : $(dirTokens)
402			: $(firmwareArchive) : : $(package) ;
403	} else {
404		AddFilesToContainer $(container) : $(dirTokens) : $(firmwareArchive)  ;
405	}
406}
407
408
409rule ExtractArchiveToContainer container : directoryTokens : archiveFile
410	: flags : extractedSubDir
411{
412	# ExtractArchiveToContainer <container> : <directory> : <archiveFile>
413	#	: [ <flags> ] : <extractedSubDir> ;
414	#
415	# Supported flags: alwaysUpdate, stripDebugSymbols
416
417	# If the container shall only be updated, we extract only, if explicitely
418	# requested.
419	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
420		&& ! alwaysUpdate in $(flags) {
421		return ;
422	}
423
424	local directory = [ AddDirectoryToContainer $(container)
425		: $(directoryTokens) ] ;
426	local stripDebugSymbols ;
427	if stripDebugSymbols in $(flags) {
428		stripDebugSymbols = 1 ;
429	}
430
431	ARCHIVE_FILES_TO_INSTALL on $(directory) += $(archiveFile) ;
432	ARCHIVE_SUBDIR_TO_INSTALL_FROM on $(archiveFile) = $(extractedSubDir) ;
433	ARCHIVE_FILES_TO_STRIP on $(archiveFile) = $(stripDebugSymbols) ;
434}
435
436rule AddDriversToContainer container : relativeDirectoryTokens : targets
437{
438	# AddDriversToContainer <container> : <relative directory> : <targets> ;
439	#
440	local systemDirTokens
441		= [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ;
442	local directoryTokens = $(systemDirTokens) add-ons kernel drivers dev
443		$(relativeDirectoryTokens) ;
444
445	targets = [ FFilterByBuildFeatures $(targets) ] ;
446
447	# A driver can be in multiple categories. Avoid adding it to the bin/
448	# directory more than once.
449	local binTargets ;
450	local target ;
451	for target in $(targets) {
452		local containers
453			= [ on $(target) return $(HAIKU_DRIVER_IN_CONTAINERS) ] ;
454		if ! $(container) in $(containers) {
455			HAIKU_DRIVER_IN_CONTAINERS on $(target)
456				= $(containers) $(container) ;
457			binTargets += $(target) ;
458		}
459	}
460
461	AddFilesToContainer $(container)
462		: $(systemDirTokens) add-ons kernel drivers bin
463		: $(binTargets) ;
464
465	# If the image shall only be updated, we don't add any symlinks.
466	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
467		&& ! [ IncludeAllTargetsInContainer $(container) ] {
468		return ;
469	}
470
471	# get the relative symlink path prefix
472	local linkPrefix = ;
473	for i in $(relativeDirectoryTokens) {
474		linkPrefix += .. ;
475	}
476	linkPrefix += .. bin ;
477
478	# add the symlinks
479	local name ;
480	for name in $(targets:BS) {
481		AddSymlinkToContainer $(container) : $(directoryTokens)
482			: [ FDirName $(linkPrefix) $(name) ] : $(name) ;
483	}
484}
485
486rule AddNewDriversToContainer container : relativeDirectoryTokens
487	: targets
488{
489	# AddNewDriversToContainer <container> : <directory> : <targets> ;
490	#
491	local systemDirTokens
492		= [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ;
493	local directoryTokens = $(systemDirTokens) add-ons kernel drivers
494		$(relativeDirectoryTokens) ;
495
496	targets = [ FFilterByBuildFeatures $(targets) ] ;
497
498	AddFilesToContainer $(container) : $(directoryTokens)
499		: $(targets) ;
500}
501
502rule AddBootModuleSymlinksToContainer container : targets
503{
504	# AddBootModuleSymlinksToContainer <container> : <targets> ;
505	#
506
507	# If the container shall only be updated, we don't add any symlinks.
508
509	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
510		&& ! [ IncludeAllTargetsInContainer $(container) ] {
511		return ;
512	}
513
514	local systemDirTokens
515		= [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ;
516	targets = [ FFilterByBuildFeatures $(targets) ] ;
517
518	# add the symlinks
519	local installTargetsVar
520		= [ on $(container) return $(HAIKU_INSTALL_TARGETS_VAR) ] ;
521	local target ;
522	for target in $(targets) {
523		# Symlink to the first place where the target has been installed.
524		local destTarget = [ on $(target) return $($(installTargetsVar)[1]) ] ;
525		local installDir = [ on $(destTarget) return $(INSTALL_DIR) ] ;
526
527		if ! $(installDir) {
528			Echo "ERROR: AddBootModuleSymlinksToContainer: Can't create a "
529				"symlink to target" \"$(target)"\"." ;
530			Exit "ERROR: Add*ToContainer has not been invoked for it yet." ;
531		}
532
533		local name = $(target:BS) ;
534		local linkTarget = [ FDirName ../../.. $(installDir:G=) $(name) ] ;
535
536		AddSymlinkToContainer $(container)
537			: $(systemDirTokens) add-ons kernel boot
538			: $(linkTarget) : $(name) ;
539	}
540}
541
542
543rule AddLibrariesToContainer container : directory : libs
544{
545	# AddLibrariesToContainer <container> : <directory> : <libs>
546	#
547	# Installs libraries with the appropriate links into the container.
548	#
549
550	local lib ;
551	for lib in $(libs) {
552		local abiVersion = [ on $(lib) return $(HAIKU_LIB_ABI_VERSION) ] ;
553		if $(abiVersion) {
554			local abiVersionedLib = $(lib).$(abiVersion) ;
555			AddFilesToContainer $(container) : $(directory) : $(lib)
556				: $(abiVersionedLib) ;
557			AddSymlinkToContainer $(container) : $(directory)
558				: $(abiVersionedLib) : $(lib) ;
559		} else {
560			AddFilesToContainer $(container) : $(directory) : $(lib) ;
561		}
562	}
563}
564
565
566rule CreateContainerMakeDirectoriesScript container : script
567{
568	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
569	Always $(script) ;
570
571	local initScript = [ InitScript $(script) ] ;
572
573	local scriptBody
574		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
575	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
576	Depends $(scriptBody) : $(initScript) ;
577	Depends $(script) : $(scriptBody) ;
578
579	# collect the directories to create
580	local dirsToCreate ;
581	local directories
582		= [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] ;
583	local dir ;
584	for dir in $(directories) {
585		if ! [ on $(dir) return $(DONT_CREATE) ] {
586			dirsToCreate += $(dir) ;
587		}
588	}
589
590	# If the image shall only be updated, we don't create directories.
591	if $(dirsToCreate)
592		&& ( ! [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
593			|| [ IncludeAllTargetsInContainer $(container) ]
594			|| [ on $(container) return
595				$(HAIKU_CONTAINER_ALWAYS_CREATE_DIRECTORIES) ] ) {
596		Depends $(scriptBody) : $(dirsToCreate) ;
597		CreateContainerMakeDirectoriesScript1 $(scriptBody) : $(dirsToCreate) ;
598
599		local serializationDependency = $(scriptBody) ;
600			# Used to create a dependency chain between the dummy targets.
601			# This forces jam to build them one after the other, thus preventing
602			# concurrent writes to the script file when building with multiple
603			# jobs.
604
605		# For directories with attributes, we convert those the specified
606		# resource files to files with attributes and add commands to the script
607		# adding the attributes to the directories.
608		for dir in $(directories) {
609			local resourceFiles = [ on $(dir) return $(ATTRIBUTE_FILES) ] ;
610			if $(resourceFiles) {
611				local dirTokens = [ on $(dir) return $(DIRECTORY_TOKENS) ] ;
612
613				# translate resources file to file with attributes
614				local attributeFile = $(script)-attributes-$(dirTokens:J=-) ;
615				ResAttr $(attributeFile) : $(resourceFiles) ;
616
617				# use a unique dummy target for this file, on which we
618				# can define the TARGET_DIR variable
619				local dummyTarget = $(script)-attributes-dummy-$(dir:G=) ;
620				NotFile $(dummyTarget) ;
621				TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
622
623				Depends $(dummyTarget) : $(initScript) $(attributeFile)
624					$(serializationDependency) ;
625				Depends $(script) : $(dummyTarget) ;
626				serializationDependency = $(dummyTarget) ;
627
628				AppendToContainerMakeDirectoriesScriptAttributes $(dummyTarget)
629					: $(initScript) $(attributeFile) ;
630			}
631		}
632	}
633}
634
635actions piecemeal CreateContainerMakeDirectoriesScript1
636{
637	echo \$mkdir -p "\"\${tPrefix}$(2:G=)\"" >> $(1)
638}
639
640actions AppendToContainerMakeDirectoriesScriptAttributes
641{
642	echo \$copyAttrs "\"\${sPrefix}$(2[2])\"" \
643		"\"\${tPrefix}$(TARGET_DIR)\"" >> $(2[1])
644}
645
646rule CreateContainerCopyFilesScript container : script
647{
648	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
649	Always $(script) ;
650
651	local initScript = [ InitScript $(script) ] ;
652
653	local scriptBody
654		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
655	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
656	Depends $(scriptBody) : $(initScript) ;
657	Depends $(script) : $(scriptBody) ;
658
659	local serializationDependency = $(scriptBody) ;
660		# Used to create a dependency chain between the dummy targets.
661		# This forces jam to build them one after the other, thus preventing
662		# concurrent writes to the script file when building with multiple
663		# jobs.
664
665	local dir ;
666	for dir in [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] {
667		# filter the targets that shall be renamed; they have to be copied
668		# individually
669		local destTargets = [ on $(dir) return $(TARGETS_TO_INSTALL) ] ;
670		local remainingTargets ;
671		local destTarget ;
672		for destTarget in $(destTargets) {
673			local target = [ on $(destTarget) return $(TARGET) ] ;
674			local name = $(destTarget:BS) ;
675			if $(name) != $(target:BS) {
676				# use a unique dummy target for this file, on which we
677				# can define the TARGET_DIR variable
678				local dummyTarget = $(script)-dummy-$(dir:G=)-$(target) ;
679				NotFile $(dummyTarget) ;
680				TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
681				INSTALL_TARGET_NAME on $(dummyTarget) = $(name) ;
682
683				Depends $(dummyTarget) : $(initScript) $(target)
684					$(serializationDependency) ;
685				Depends $(script) : $(dummyTarget) ;
686				serializationDependency = $(dummyTarget) ;
687
688				AppendToContainerCopyFilesScriptSingleFile $(dummyTarget)
689					: $(initScript) $(target) ;
690			} else {
691				remainingTargets += $(target) ;
692			}
693		}
694		targets = $(remainingTargets) ;
695
696		if $(targets) {
697			# use a unique dummy target for this directory, on which we
698			# can define the TARGET_DIR variable
699			local dummyTarget = $(script)-dummy-$(dir:G=) ;
700			NotFile $(dummyTarget) ;
701			TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
702
703			Depends $(dummyTarget) : $(initScript) $(targets)
704				$(serializationDependency) ;
705			Depends $(script) : $(dummyTarget) ;
706			serializationDependency = $(dummyTarget) ;
707
708			OUTPUT_SCRIPT on $(dummyTarget) = $(initScript) ;
709			AppendToContainerCopyFilesScript $(dummyTarget) : $(targets) ;
710		}
711
712		local symlinks = [ on $(dir) return $(SYMLINKS_TO_INSTALL) ] ;
713		local symlink ;
714		for symlink in $(symlinks) {
715			NotFile $(symlink) ;
716
717			Depends $(script) : $(symlink) ;
718			Depends $(symlink) : $(initScript) $(serializationDependency) ;
719			serializationDependency = $(symlink) ;
720
721			AddSymlinkToContainerCopyFilesScript $(symlink) : $(initScript) ;
722		}
723
724		local targetDirs = [ on $(dir) return $(DIRECTORIES_TO_INSTALL) ] ;
725		local targetDir ;
726		for targetDir in $(targetDirs) {
727			NotFile $(targetDir) ;
728
729			Depends $(script) : $(targetDir) ;
730			Depends $(targetDir) : $(initScript) $(serializationDependency) ;
731			serializationDependency = $(targetDir) ;
732
733			AddDirectoryToContainerCopyFilesScript $(targetDir)
734				: $(initScript) ;
735		}
736	}
737}
738
739
740actions piecemeal AppendToContainerCopyFilesScript bind OUTPUT_SCRIPT
741{
742	echo \$cp "\"\${sPrefix}$(2)\"" "\"\${tPrefix}$(TARGET_DIR)\"" \
743		>> $(OUTPUT_SCRIPT)
744}
745
746
747actions AppendToContainerCopyFilesScriptSingleFile
748{
749	echo \$cp "\"\${sPrefix}$(2[2])\"" \
750		"\"\${tPrefix}$(TARGET_DIR)/$(INSTALL_TARGET_NAME)\"" >> $(2[1])
751}
752
753
754actions AddSymlinkToContainerCopyFilesScript
755{
756	echo \$ln -sfn "\"$(SYMLINK_TARGET)\"" "\"\${tPrefix}$(1:G=)\"" >> $(2[1])
757}
758
759
760actions AddDirectoryToContainerCopyFilesScript bind SOURCE_DIRECTORY
761{
762	echo \$cp -r $(EXCLUDE_PATTERNS) "\"\${sPrefix}$(SOURCE_DIRECTORY)/.\"" \
763		"\"\${tPrefix}$(TARGET_DIRECTORY:G=)\"" >> $(2[1])
764}
765
766
767rule CreateContainerExtractFilesScript container : script
768{
769	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
770	Always $(script) ;
771
772	local initScript = [ InitScript $(script) ] ;
773
774	local scriptBody
775		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
776	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
777	Depends $(scriptBody) : $(initScript) ;
778	Depends $(script) : $(scriptBody) ;
779
780	local serializationDependency = $(scriptBody) ;
781		# Used to create a dependency chain between the dummy targets.
782		# This forces jam to build them one after the other, thus preventing
783		# concurrent writes to the script file when building with multiple
784		# jobs.
785
786	local dir ;
787	for dir in [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] {
788		local archiveFiles = [ on $(dir) return $(ARCHIVE_FILES_TO_INSTALL) ] ;
789		local archiveFile ;
790		for archiveFile in $(archiveFiles) {
791			# use a unique dummy target for this file, on which we
792			# can define the TARGET_DIR variable
793			local dummyTarget = $(script)-dummy-$(dir:G=)-$(archiveFile) ;
794			NotFile $(dummyTarget) ;
795			TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
796
797			local extractedSubDir = [ on $(archiveFile)
798				return $(ARCHIVE_SUBDIR_TO_INSTALL_FROM) ] ;
799			ARCHIVE_SUBDIR_TO_INSTALL_FROM on $(dummyTarget) =
800				$(extractedSubDir:E=.) ;
801
802			local stripDebugSymbols = [ on $(archiveFile)
803				return $(ARCHIVE_FILES_TO_STRIP) ] ;
804			STRIP_DEBUG_SYMBOLS_FROM_ARCHIVE on $(dummyTarget) =
805				$(stripDebugSymbols) ;
806
807			Depends $(dummyTarget) : $(initScript) $(archiveFile)
808				$(serializationDependency) ;
809			Depends $(script) : $(dummyTarget) ;
810			serializationDependency = $(dummyTarget) ;
811
812			AddExtractFileToContainerExtractFilesScript $(dummyTarget)
813				: $(initScript) $(archiveFile) ;
814		}
815	}
816}
817
818
819actions AddExtractFileToContainerExtractFilesScript
820{
821	echo extractFile "\"$(2[2])\"" "\"$(TARGET_DIR)\"" \
822		"\"$(ARCHIVE_SUBDIR_TO_INSTALL_FROM)\"" \
823		"\"$(STRIP_DEBUG_SYMBOLS_FROM_ARCHIVE)\"" >> $(2[1])
824}
825
826
827#pragma mark - Haiku Image rules
828
829rule SetUpdateHaikuImageOnly flag
830{
831	HAIKU_CONTAINER_UPDATE_ONLY on $(HAIKU_IMAGE_CONTAINER_NAME) = $(flag) ;
832}
833
834rule IsUpdateHaikuImageOnly
835{
836	on $(HAIKU_IMAGE_CONTAINER_NAME) return $(HAIKU_CONTAINER_UPDATE_ONLY) ;
837}
838
839rule AddDirectoryToHaikuImage directoryTokens : attributeFiles
840{
841	# AddDirectoryToHaikuImage <directoryTokens> : <attributeFiles>
842
843	return [ AddDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
844		: $(directoryTokens) : $(attributeFiles) ] ;
845}
846
847rule AddFilesToHaikuImage directory : targets : destName
848{
849	# AddFilesToHaikuImage <directory> : <targets> [ : dest name ]
850
851	AddFilesToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directory)
852		: $(targets) : $(destName) ;
853}
854
855rule FFilesInHaikuImageDirectory directoryTokens
856{
857	return [ FFilesInContainerDirectory $(HAIKU_IMAGE_CONTAINER_NAME)
858		: $(directoryTokens) ] ;
859}
860
861rule AddSymlinkToHaikuImage directoryTokens : linkTarget : linkName
862{
863	# AddSymlinkToHaikuImage <directory> : <link target> [ : <link name> ] ;
864
865	linkTarget = $(linkTarget:J=/) ;
866
867	AddSymlinkToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens)
868		: $(linkTarget) : $(linkName) ;
869}
870
871rule FSymlinksInHaikuImageDirectory directoryTokens
872{
873	return [ FSymlinksInContainerDirectory $(HAIKU_IMAGE_CONTAINER_NAME)
874		: $(directoryTokens) ] ;
875}
876
877rule CopyDirectoryToHaikuImage directoryTokens : sourceDirectory
878	: targetDirectoryName : excludePatterns : flags
879{
880	CopyDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens)
881		: $(sourceDirectory) : $(targetDirectoryName) : $(excludePatterns)
882		: $(flags) ;
883}
884
885rule AddSourceDirectoryToHaikuImage dirTokens : flags
886{
887	# AddSourceDirectoryToHaikuImage <dirTokens> : <flags> ;
888
889	CopyDirectoryToHaikuImage home HaikuSources
890		: [ FDirName $(HAIKU_TOP) $(dirTokens) ]
891		: : : $(flags) ;
892}
893
894rule AddHeaderDirectoryToHaikuImage dirTokens : dirName : flags
895{
896	# AddHeaderDirectoryToHaikuImage <dirTokens> : [ <dirName> ]
897	#	: <flags> ;
898
899	AddHeaderDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(dirTokens)
900		: $(dirName) : $(flags) ;
901}
902
903rule AddWifiFirmwareToHaikuImage driver : package : archive : extract
904{
905	# AddWifiFirmwareToHaikuImage <driver> : <package> : <archive> : <extract>
906
907	AddWifiFirmwareToHaikuImage $(HAIKU_IMAGE_CONTAINER_NAME) : $(driver)
908		: $(package) : $(archive) : $(extract) ;
909}
910
911rule ExtractArchiveToHaikuImage dirTokens : archiveFile : flags
912	: extractedSubDir
913{
914	# ExtractArchiveToHaikuImage <dirTokens> : <archiveFile> : <flags>
915	#	: <extractedSubDir> ;
916
917	ExtractArchiveToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(dirTokens)
918		: $(archiveFile) : $(flags) : $(extractedSubDir) ;
919}
920
921rule AddDriversToHaikuImage relativeDirectoryTokens : targets
922{
923	# AddDriversToHaikuImage <relative directory> : <targets> ;
924
925	AddDriversToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
926		: $(relativeDirectoryTokens) : $(targets) ;
927}
928
929rule AddNewDriversToHaikuImage relativeDirectoryTokens : targets
930{
931	# AddNewDriversToHaikuImage <relative directory> : <targets> ;
932
933	AddNewDriversToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
934		: $(relativeDirectoryTokens) : $(targets) ;
935}
936
937rule AddBootModuleSymlinksToHaikuImage targets
938{
939	# AddBootModuleSymlinksToHaikuImage <targets> ;
940
941	AddBootModuleSymlinksToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
942		: $(targets) ;
943}
944
945rule AddPackageFilesToHaikuImage location : packages
946{
947	HAIKU_PACKAGES_IN_IMAGE on $(HAIKU_IMAGE_CONTAINER_NAME)
948		= [ on $(HAIKU_IMAGE_CONTAINER_NAME) return $(HAIKU_PACKAGES_IN_IMAGE) ]
949			$(packages) ;
950	AddFilesToHaikuImage $(location) packages : $(packages) ;
951}
952
953rule AddOptionalHaikuImagePackages packages
954{
955	local package ;
956	for package in $(packages) {
957		if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] {
958			HAIKU_OPTIONAL_PACKAGE_ADDED on $(package) = 1 ;
959			HAIKU_ADDED_OPTIONAL_PACKAGES += $(package) ;
960		}
961		local dependencies = [ on $(package)
962			return $(HAIKU_OPTIONAL_PACKAGE_DEPENDENCIES) ] ;
963		AddOptionalHaikuImagePackages $(dependencies) ;
964	}
965}
966
967rule SuppressOptionalHaikuImagePackages packages
968{
969	local package ;
970	for package in $(packages) {
971		if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_SUPPRESSED) ] {
972			HAIKU_OPTIONAL_PACKAGE_SUPPRESSED on $(package) = 1 ;
973		}
974	}
975}
976
977rule IsOptionalHaikuImagePackageAdded package
978{
979	if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_EXISTS) ] {
980		HAIKU_OPTIONAL_PACKAGE_EXISTS on $(package) = 1 ;
981		HAIKU_EXISTING_OPTIONAL_PACKAGES += $(package) ;
982	}
983
984	if [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] &&
985			! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_SUPPRESSED) ] {
986		return 1 ;
987	}
988
989	return ;
990}
991
992rule OptionalPackageDependencies package : dependencies
993{
994	HAIKU_OPTIONAL_PACKAGE_DEPENDENCIES on $(package) = $(dependencies) ;
995	if [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] {
996		AddOptionalHaikuImagePackages $(dependencies) ;
997	}
998}
999
1000rule InstallSourceArchive file : url
1001{
1002	if $(HAIKU_INCLUDE_SOURCES) = 1 {
1003		# download archive file
1004		local archiveFile = [ DownloadFile $(file) : $(url) ] ;
1005
1006		# copy directly into image
1007		AddFilesToHaikuImage _sources_ : $(archiveFile) ;
1008	}
1009}
1010
1011rule InstallOptionalHaikuImagePackage url : dirTokens : flags
1012{
1013	# TODO: Remove the non-hpkg cases!
1014	# Currently the semantics differs depending on whether the  cdPackage flag
1015	# has been specified and the type of the package file:
1016	# * For a hpkg <dirTokens> is "common" (default) or "system" and specifies
1017	#   the installation location of the package (will be copied to the
1018	#   packages/ subdirectory).
1019	# * For a regular archive and cdPackage, <dirTokens> is ignored and
1020	#   the package will be copied to the _package_ directory of the CD image.
1021	# * For a regular archive and without cdPackage, <dirTokens> specifies the
1022	#   directory relative to the image's root directory where the content of
1023	#   the archive will be extracted to.
1024	#
1025	# Supported flags: cdPackage, stripDebugSymbols/!stripDebugSymbols
1026
1027	local package = $(url:BS) ;
1028
1029	# download archive file
1030	local archiveFile = [ DownloadFile $(package) : $(url) ] ;
1031
1032	if $(package:S) = .hpkg {
1033		local location = $(dirTokens:E=common) ;
1034		if $(HAIKU_UPDATE_ALL_PACKAGES) {
1035			HAIKU_INCLUDE_IN_IMAGE on $(archiveFile) = 1 ;
1036		}
1037		AddPackageFilesToHaikuImage $(location) : $(archiveFile) ;
1038	} else if cdPackage in $(flags) && $(HAIKU_CD_NAME) {
1039		# TODO: If HAIKU_CD_NAME is set, that doesn't mean we're building a CD
1040		# image!
1041		# copy onto image
1042		AddFilesToHaikuImage _packages_ : $(archiveFile) ;
1043	} else {
1044		if $(HAIKU_STRIP_DEBUG_FROM_OPTIONAL_PACKAGES) = 1
1045			&& ! stripDebugSymbols in $(flags)
1046			&& ! !stripDebugSymbols in $(flags) {
1047			flags += stripDebugSymbols ;
1048		}
1049		# extract onto image
1050		ExtractArchiveToHaikuImage $(dirTokens) : $(archiveFile) : $(flags) ;
1051	}
1052}
1053
1054rule AddEntryToHaikuImageUserGroupFile file : entry
1055{
1056	local allEntries = [ on $(file) return $(HAIKU_IMAGE_USER_GROUP_ENTRIES) ] ;
1057
1058	if $(allEntries) {
1059		allEntries = $(allEntries)|$(entry) ;
1060	} else {
1061		allEntries = $(entry) ;
1062
1063		Always $(file) ;
1064		MakeLocate $(file) : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ;
1065		BuildHaikuImageUserGroupFile $(file) ;
1066		AddFilesToHaikuImage common settings etc : $(file) ;
1067	}
1068
1069	HAIKU_IMAGE_USER_GROUP_ENTRIES on $(file) = $(allEntries) ;
1070}
1071
1072actions BuildHaikuImageUserGroupFile
1073{
1074	echo "$(HAIKU_IMAGE_USER_GROUP_ENTRIES)" | tr '|' '\n' > $(1)
1075}
1076
1077rule AddUserToHaikuImage user : uid : gid : home : shell : realName
1078{
1079	if ! $(user) || ! $(uid) || ! $(gid) || ! $(home) {
1080		Exit "Invalid haiku user specification passed to AddUserToHaikuImage." ;
1081	}
1082
1083	local entry
1084		= $(user):x:$(uid):$(gid):$(realName:E=$(user)):$(home):$(shell:E="") ;
1085
1086	AddEntryToHaikuImageUserGroupFile <haiku-image>passwd : $(entry) ;
1087}
1088
1089rule AddGroupToHaikuImage group : gid : members
1090{
1091	if ! $(group) || ! $(gid) {
1092		Exit "Invalid haiku group specification passed to"
1093			"AddGroupToHaikuImage." ;
1094	}
1095
1096	local entry = $(group):x:$(gid):$(members:J=,:E) ;
1097
1098	AddEntryToHaikuImageUserGroupFile <haiku-image>group : $(entry) ;
1099}
1100
1101rule AddEntryToHaikuImageExpanderRuleFile file : entry
1102{
1103	local allEntries
1104		= [ on $(file) return $(HAIKU_IMAGE_EXPANDER_RULES_ENTRIES) ] ;
1105
1106	if $(allEntries) {
1107		allEntries = $(allEntries)!$(entry) ;
1108	} else {
1109		allEntries = $(entry) ;
1110
1111		Always $(file) ;
1112		MakeLocate $(file) : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ;
1113		BuildHaikuImageExpanderRules $(file) ;
1114		AddFilesToHaikuImage common data : $(file) ;
1115	}
1116
1117	HAIKU_IMAGE_EXPANDER_RULES_ENTRIES on $(file) = $(allEntries) ;
1118}
1119
1120actions BuildHaikuImageExpanderRules
1121{
1122	echo -e "$(HAIKU_IMAGE_EXPANDER_RULES_ENTRIES)" | tr '!' '\n' > $(1)
1123}
1124
1125rule AddExpanderRuleToHaikuImage mimetype : extension : list : extract
1126{
1127	#AddExpanderRuleToHaikuImage <mimetype> : <extension> : <list> : <extract>
1128
1129	if ! $(mimetype) || ! $(extension) || ! $(list) || ! $(extract) {
1130		Exit "Invalid expander rule specification passed to AddExpanderRule." ;
1131	}
1132
1133	local entry
1134		= "\\\"$(mimetype)\\\"\\\t$(extension)\\\t\\\"$(list)\\\"\\\t\\\"$(extract)\\\"" ;
1135	AddEntryToHaikuImageExpanderRuleFile <haiku-image>expander.rules
1136		: $(entry) ;
1137}
1138
1139rule AddOptionalPackageDescriptionToHaikuImage file : searchPath
1140{
1141	if $(searchPath) {
1142		SEARCH on $(file) = [ FDirName $(searchPath) ] ;
1143	}
1144
1145	HAIKU_IMAGE_OPTIONAL_PACKAGE_DESCRIPTIONS += $(file) ;
1146}
1147
1148rule AddLicenseToHaikuImage file : name : searchPath
1149{
1150	if $(searchPath) {
1151		SEARCH on $(file) = [ FDirName $(searchPath) ] ;
1152	}
1153
1154	if $(name) && $(file:BS) = $(name) {
1155		name = ;
1156	}
1157
1158	local systemDirTokens
1159		= [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ;
1160
1161	AddFilesToHaikuImage $(systemDirTokens) data licenses : $(file) : $(name) ;
1162}
1163
1164
1165rule AddLibrariesToHaikuImage directory : libs
1166{
1167	# AddLibraryToHaikuImage <directory> : <libs>
1168	#
1169	# Installs libraries with the appropriate links onto the image.
1170	#
1171
1172	AddLibrariesToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directory)
1173		: $(libs) ;
1174}
1175
1176
1177rule CreateHaikuImageMakeDirectoriesScript script
1178{
1179	CreateContainerMakeDirectoriesScript $(HAIKU_IMAGE_CONTAINER_NAME)
1180		: $(script) ;
1181}
1182
1183rule CreateHaikuImageCopyFilesScript script
1184{
1185	CreateContainerCopyFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ;
1186}
1187
1188rule CreateHaikuImageExtractFilesScript script
1189{
1190	CreateContainerExtractFilesScript $(HAIKU_IMAGE_CONTAINER_NAME)
1191		: $(script) ;
1192}
1193
1194rule BuildHaikuImage haikuImage : scripts : isImage : isVMwareImage
1195{
1196	# BuildHaikuImage <haiku image> : <scripts> : <is image> : <isVMwareImage> ;
1197
1198	if $(isImage) = 1 || $(isImage) = true {
1199		IS_IMAGE on $(haikuImage) = 1 ;
1200	} else {
1201		IS_IMAGE on $(haikuImage) = "" ;
1202	}
1203
1204	if $(isVMwareImage) = 1 || $(isVMwareImage) = true {
1205		IS_VMWARE_IMAGE on $(haikuImage) = 1 ;
1206	} else {
1207		IS_VMWARE_IMAGE on $(haikuImage) = "" ;
1208	}
1209
1210	local mainScript = build_haiku_image ;
1211	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
1212
1213	Depends $(haikuImage) : $(mainScript) $(scripts) ;
1214	BuildHaikuImage1 $(haikuImage) : $(mainScript) $(scripts) ;
1215}
1216
1217actions BuildHaikuImage1
1218{
1219	export imagePath="$(1)"
1220	export isImage="$(IS_IMAGE)"
1221	export isVMwareImage="$(IS_VMWARE_IMAGE)"
1222	$(2[1]) $(2[2-])
1223}
1224
1225rule BuildVMWareImage vmwareImage : plainImage : imageSize
1226{
1227	# BuildVMWareImage <vmware image> : <plain image> : <image size in MB>
1228
1229	IMAGE_SIZE on $(vmwareImage) = $(imageSize) ;
1230
1231	Depends $(vmwareImage) : <build>vmdkheader $(plainImage) ;
1232	BuildVMWareImage1 $(vmwareImage) : <build>vmdkheader $(plainImage) ;
1233}
1234
1235actions BuildVMWareImage1
1236{
1237	$(RM) $(1)
1238	$(2[1]) -h 64k -i$(IMAGE_SIZE)M $(1) &&
1239	cat $(2[2]) >> $(1)
1240}
1241
1242
1243#pragma mark - Network Boot Archive rules
1244
1245rule AddDirectoryToNetBootArchive directoryTokens
1246{
1247	# AddDirectoryToNetBootArchive <directoryTokens>
1248
1249	return [ AddDirectoryToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1250		: $(directoryTokens) ] ;
1251}
1252
1253rule AddFilesToNetBootArchive directory : targets : destName
1254{
1255	# AddFilesToNetBootArchive <directory> : <targets> [ : dest name ]
1256
1257	AddFilesToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(directory)
1258		: $(targets) : $(destName) ;
1259}
1260
1261rule AddSymlinkToNetBootArchive directoryTokens : linkTarget : linkName
1262{
1263	# AddSymlinkToNetBootArchive <directory> : <link target> [ : <link name> ] ;
1264
1265	AddSymlinkToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1266		: $(directoryTokens) : $(linkTarget) : $(linkName) ;
1267}
1268
1269rule AddDriversToNetBootArchive relativeDirectoryTokens : targets
1270{
1271	# AddDriversToNetBootArchive <relative directory> : <targets> ;
1272
1273	AddDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1274		: $(relativeDirectoryTokens) : $(targets) ;
1275}
1276
1277rule AddNewDriversToNetBootArchive relativeDirectoryTokens : targets
1278{
1279	# AddNewDriversToNetBootArchive <relative directory> : <targets> ;
1280
1281	AddNewDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1282		: $(relativeDirectoryTokens) : $(targets) ;
1283}
1284
1285rule AddDriverRegistrationToNetBootArchive relativeDirectoryTokens : target
1286	: links
1287{
1288	# AddDriverRegistrationToNetBootArchive <directory> : <link target>
1289	#	: <link names> ] ;
1290
1291	AddDriverRegistrationToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1292		: $(relativeDirectoryTokens) : $(target) : $(links) ;
1293}
1294
1295rule AddBootModuleSymlinksToNetBootArchive targets
1296{
1297	# AddBootModuleSymlinksToNetBootArchive <targets> ;
1298
1299	AddBootModuleSymlinksToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1300		: $(targets) ;
1301}
1302
1303rule CreateNetBootArchiveMakeDirectoriesScript script
1304{
1305	CreateContainerMakeDirectoriesScript
1306		$(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(script) ;
1307}
1308
1309rule CreateNetBootArchiveCopyFilesScript script
1310{
1311	CreateContainerCopyFilesScript $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1312		: $(script) ;
1313}
1314
1315rule BuildNetBootArchive archive : scripts
1316{
1317	# BuildNetBootArchive <archive> : <scripts>  ;
1318
1319	local mainScript = build_archive ;
1320	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
1321
1322	Depends $(archive) : $(mainScript) $(scripts) ;
1323	BuildNetBootArchive1 $(archive) : $(mainScript) $(scripts) ;
1324}
1325
1326actions BuildNetBootArchive1
1327{
1328	$(2[1]) $(1) $(2[2-])
1329}
1330
1331
1332#pragma mark - Floppy Boot Archive rules
1333
1334
1335rule AddDirectoryToFloppyBootArchive directoryTokens
1336{
1337	# AddDirectoryToFloppyBootArchive <directoryTokens>
1338
1339	return [ AddDirectoryToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1340		: $(directoryTokens) ] ;
1341}
1342
1343rule AddFilesToFloppyBootArchive directory : targets : destName
1344{
1345	# AddFilesToFloppyBootArchive <directory> : <targets> [ : dest name ]
1346
1347	AddFilesToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(directory)
1348		: $(targets) : $(destName) ;
1349}
1350
1351rule AddSymlinkToFloppyBootArchive directoryTokens : linkTarget : linkName
1352{
1353	# AddSymlinkToFloppyBootArchive <directory> : <link target>
1354	#	[ : <link name> ] ;
1355
1356	AddSymlinkToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1357		: $(directoryTokens) : $(linkTarget) : $(linkName) ;
1358}
1359
1360rule AddDriversToFloppyBootArchive relativeDirectoryTokens : targets
1361{
1362	# AddDriversToFloppyBootArchive <relative directory> : <targets> ;
1363
1364	AddDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1365		: $(relativeDirectoryTokens) : $(targets) ;
1366}
1367
1368rule AddNewDriversToFloppyBootArchive relativeDirectoryTokens : targets
1369{
1370	# AddNewDriversToFloppyBootArchive <relative directory> : <targets> ;
1371
1372	AddNewDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1373		: $(relativeDirectoryTokens) : $(targets) ;
1374}
1375
1376rule AddDriverRegistrationToFloppyBootArchive relativeDirectoryTokens : target
1377	: links
1378{
1379	# AddDriverRegistrationToFloppyBootArchive <directory> : <link target>
1380	#	: <link names> ] ;
1381
1382	AddDriverRegistrationToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1383		: $(relativeDirectoryTokens) : $(target) : $(links) ;
1384}
1385
1386rule AddBootModuleSymlinksToFloppyBootArchive targets
1387{
1388	# AddBootModuleSymlinksToFloppyBootArchive <targets> ;
1389
1390	AddBootModuleSymlinksToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1391		: $(targets) ;
1392}
1393
1394rule CreateFloppyBootArchiveMakeDirectoriesScript script
1395{
1396	CreateContainerMakeDirectoriesScript
1397		$(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(script) ;
1398}
1399
1400rule CreateFloppyBootArchiveCopyFilesScript script
1401{
1402	CreateContainerCopyFilesScript $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1403		: $(script) ;
1404}
1405
1406rule BuildFloppyBootArchive archive : scripts
1407{
1408	# BuildHFloppyBootArchive <archive> : <scripts>  ;
1409
1410	local mainScript = build_archive ;
1411	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
1412
1413	Depends $(archive) : $(mainScript) $(scripts) ;
1414	BuildFloppyBootArchive1 $(archive) : $(mainScript) $(scripts) ;
1415}
1416
1417actions BuildFloppyBootArchive1
1418{
1419	$(2[1]) $(1) $(2[2-])
1420}
1421
1422# warning: that is quite x86 dependant...
1423
1424rule BuildFloppyBootImage image : haikuLoader : archive
1425{
1426	Depends $(image) : $(haikuLoader) ;
1427	Depends $(image) : $(archive) ;
1428	#MakeLocateDebug $(image) ;
1429	FLOPPY_IMAGE_SIZE on $(image) = $(HAIKU_BOOT_FLOPPY_IMAGE_SIZE) ;
1430	ARCHIVE_IMAGE_OFFSET on $(image) = $(HAIKU_BOOT_ARCHIVE_IMAGE_OFFSET) ;
1431	BuildFloppyBootImage1 $(image) : $(haikuLoader) $(archive) ;
1432	if $(HAIKU_BOOT_PLATFORM) = atari_m68k {
1433		Depends $(image) : <build>fixup_tos_boot_checksum ;
1434		BuildFloppyBootImageFixupM68K $(image)
1435			: <build>fixup_tos_boot_checksum ;
1436	}
1437	if $(HAIKU_BOOT_PLATFORM) = amiga_m68k {
1438		Depends $(image) : <build>fixup_amiga_boot_checksum ;
1439		BuildFloppyBootImageFixupM68K $(image)
1440			: <build>fixup_amiga_boot_checksum ;
1441	}
1442}
1443
1444actions BuildFloppyBootImage1
1445{
1446	haiku_loader_size=`stat -c %s "$(>[1])"`
1447	if [ $? -ne 0 ] ; then
1448		# FreeBSD's stat command don't support -c/--format option
1449		# and use %z specifier for file size
1450		haiku_loader_size=`stat -f %z "$(>[1])"`
1451	fi
1452	archive_image_offset=`echo "$(ARCHIVE_IMAGE_OFFSET) * 1024" | bc`
1453	if [ $haiku_loader_size -gt $archive_image_offset ] ; then
1454		echo "Error: $(>[1]) is too big ($haiku_loader_size) to fit "
1455		echo "       before the boot archive starting at $archive_image_offset!"
1456		exit 1
1457	fi
1458	$(RM) $(<)
1459	# make an empty image
1460	dd if=/dev/zero of=$(<) bs=1k count=$(FLOPPY_IMAGE_SIZE)
1461	# add haiku_loader
1462	dd if=$(>[1]) of=$(<) conv=notrunc
1463	# add the boot drivers tgz archive
1464	dd if=$(>[2]) of=$(<) bs=$(ARCHIVE_IMAGE_OFFSET)k seek=1 conv=notrunc
1465}
1466
1467actions BuildFloppyBootImageFixupM68K
1468{
1469	# fixup the boot sector checksum
1470	$(>[1]) $(<)
1471}
1472
1473#pragma mark - CD Boot Image rules
1474
1475rule BuildCDBootImage image : bootfloppy : extrafiles
1476{
1477	Depends $(image) : $(bootfloppy) ;
1478	Depends $(image) : $(extrafiles) ;
1479	BOOTIMG on $(image) = $(bootfloppy) ;
1480
1481	BuildCDBootImage1 $(image) : $(bootfloppy) $(extrafiles) ;
1482}
1483
1484actions BuildCDBootImage1
1485{
1486	$(RM) $(<)
1487	mkisofs -b $(BOOTIMG) -r -J -V bootimg -o $(<) $(>[1]) $(>[2-])
1488}
1489
1490
1491#pragma mark - CD Boot PPC Image rules
1492
1493rule BuildCDBootPPCImage image : hfsmaps : elfloader : coffloader : chrpscript
1494	: extrafiles
1495{
1496	Depends $(image) : $(elfloader) ;
1497	Depends $(image) : $(coffloader) ;
1498	Depends $(image) : $(chrpscript) ;
1499	Depends $(image) : $(extrafiles) ;
1500	Depends $(image) : $(hfsmaps) ;
1501	MAPS on $(image) = $(hfsmaps) ;
1502
1503	BuildCDBootPPCImage1 $(image) : $(elfloader) $(coffloader) $(chrpscript)
1504		$(extrafiles) ;
1505}
1506
1507actions BuildCDBootPPCImage1 bind MAPS
1508{
1509	$(RM) $(<)
1510	mkdir -p $(HAIKU_OUTPUT_DIR)/cd/ppc
1511	cp $(>) $(HAIKU_OUTPUT_DIR)/cd/ppc/
1512	cp $(>[3]) $(HAIKU_OUTPUT_DIR)/cd/ppc/bootinfo.txt
1513	cp $(>[1]) $(HAIKU_OUTPUT_DIR)/cd/ofwboot.elf
1514	cp $(>[2]) $(HAIKU_OUTPUT_DIR)/cd/ofwboot.xcf
1515	#mkisofs -r -U -chrp-boot -V bootimg -o $(<) $(>[1]) $(>[2-])
1516	#mkisofs -hfs -r -U -chrp-boot -part -map $(MAPS) -no-desktop \
1517	#	-hfs-volid bootimg -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1])
1518	#	- $(>[2-])
1519	#mkisofs -v -hfs -part -map $(MAPS) -no-desktop -hfs-volid bootimg \
1520	#	-V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/ppc -r -o $(<) $(>[1]) \
1521	#	$(>[2-]) $(HAIKU_OUTPUT_DIR)/cd
1522	#mkisofs -r -U -chrp-boot -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) \
1523	#	$(>[2-])
1524	#mkisofs -r -U -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) $(>[2-])
1525	# $(HAIKU_OUTPUT_DIR)/cd
1526	# -hfs -hfs-bless .
1527	mkisofs -v -hfs -part -map $(MAPS) -no-desktop -hfs-volid bootimg \
1528		-V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/ppc -prep-boot \
1529		ppc/$(>[2]:D=) -r -o $(<) $(HAIKU_OUTPUT_DIR)/cd \
1530	|| \
1531	genisoimage -v -hfs -part -map $(MAPS) -no-desktop -hfs-volid bootimg \
1532		-V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/ppc -prep-boot \
1533		ppc/$(>[2]:D=) -r -o $(<) $(HAIKU_OUTPUT_DIR)/cd
1534	#$(RM) -R $(HAIKU_OUTPUT_DIR)/cd
1535}
1536
1537
1538