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