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