ImageRules revision dfa6888f
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 InstallOptionalHaikuImagePackage package : url : dirTokens : isCDPackage
890{
891	# download archive file
892	local archiveFile = [ DownloadFile $(package) : $(url) ] ;
893
894	if $(package:S) = .hpkg {
895		AddFilesToHaikuImage $(dirTokens) : $(archiveFile) ;
896	} else if ( $(isCDPackage) = true || $(isCDPackage) = 1 )
897		&& $(HAIKU_CD_NAME) {
898		# TODO: If HAIKU_CD_NAME is set, that doesn't mean we're building a CD
899		# image!
900		# copy onto image
901		AddFilesToHaikuImage _packages_ : $(archiveFile) ;
902	} else {
903		# extract onto image
904		ExtractArchiveToHaikuImage $(dirTokens) : $(archiveFile) ;
905	}
906}
907
908rule AddEntryToHaikuImageUserGroupFile file : entry
909{
910	local allEntries = [ on $(file) return $(HAIKU_IMAGE_USER_GROUP_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		BuildHaikuImageUserGroupFile $(file) ;
920		AddFilesToHaikuImage common settings etc : $(file) ;
921	}
922
923	HAIKU_IMAGE_USER_GROUP_ENTRIES on $(file) = $(allEntries) ;
924}
925
926actions BuildHaikuImageUserGroupFile
927{
928	echo "$(HAIKU_IMAGE_USER_GROUP_ENTRIES)" | tr '|' '\n' > $(1)
929}
930
931rule AddUserToHaikuImage user : uid : gid : home : shell : realName
932{
933	if ! $(user) || ! $(uid) || ! $(gid) || ! $(home) {
934		Exit "Invalid haiku user specification passed to AddUserToHaikuImage." ;
935	}
936
937	local entry
938		= $(user):x:$(uid):$(gid):$(realName:E=$(user)):$(home):$(shell:E="") ;
939
940	AddEntryToHaikuImageUserGroupFile <haiku-image>passwd : $(entry) ;
941}
942
943rule AddGroupToHaikuImage group : gid : members
944{
945	if ! $(group) || ! $(gid) {
946		Exit "Invalid haiku group specification passed to"
947			"AddGroupToHaikuImage." ;
948	}
949
950	local entry = $(group):x:$(gid):$(members:J=,:E) ;
951
952	AddEntryToHaikuImageUserGroupFile <haiku-image>group : $(entry) ;
953}
954
955rule AddEntryToHaikuImageExpanderRuleFile file : entry
956{
957	local allEntries
958		= [ on $(file) return $(HAIKU_IMAGE_EXPANDER_RULES_ENTRIES) ] ;
959
960	if $(allEntries) {
961		allEntries = $(allEntries)!$(entry) ;
962	} else {
963		allEntries = $(entry) ;
964
965		Always $(file) ;
966		MakeLocate $(file) : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ;
967		BuildHaikuImageExpanderRules $(file) ;
968		AddFilesToHaikuImage common data : $(file) ;
969	}
970
971	HAIKU_IMAGE_EXPANDER_RULES_ENTRIES on $(file) = $(allEntries) ;
972}
973
974actions BuildHaikuImageExpanderRules
975{
976	echo -e "$(HAIKU_IMAGE_EXPANDER_RULES_ENTRIES)" | tr '!' '\n' > $(1)
977}
978
979rule AddExpanderRuleToHaikuImage mimetype : extension : list : extract
980{
981	#AddExpanderRuleToHaikuImage <mimetype> : <extension> : <list> : <extract>
982
983	if ! $(mimetype) || ! $(extension) || ! $(list) || ! $(extract) {
984		Exit "Invalid expander rule specification passed to AddExpanderRule." ;
985	}
986
987	local entry
988		= "\\\"$(mimetype)\\\"\\\t$(extension)\\\t\\\"$(list)\\\"\\\t\\\"$(extract)\\\"" ;
989	AddEntryToHaikuImageExpanderRuleFile <haiku-image>expander.rules
990		: $(entry) ;
991}
992
993rule AddOptionalPackageDescriptionToHaikuImage file : searchPath
994{
995	if $(searchPath) {
996		SEARCH on $(file) = [ FDirName $(searchPath) ] ;
997	}
998
999	HAIKU_IMAGE_OPTIONAL_PACKAGE_DESCRIPTIONS += $(file) ;
1000}
1001
1002rule AddLicenseToHaikuImage file : name : searchPath
1003{
1004	if $(searchPath) {
1005		SEARCH on $(file) = [ FDirName $(searchPath) ] ;
1006	}
1007
1008	if $(name) && $(file:BS) = $(name) {
1009		name = ;
1010	}
1011
1012	local systemDirTokens
1013		= [ on $(container) return $(HAIKU_CONTAINER_SYSTEM_DIR_TOKENS) ] ;
1014
1015	AddFilesToHaikuImage $(systemDirTokens) data licenses : $(file) : $(name) ;
1016}
1017
1018
1019rule AddLibrariesToHaikuImage directory : libs
1020{
1021	# AddLibraryToHaikuImage <directory> : <libs>
1022	#
1023	# Installs libraries with the appropriate links onto the image.
1024	#
1025
1026	AddLibrariesToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directory)
1027		: $(libs) ;
1028}
1029
1030
1031rule CreateHaikuImageMakeDirectoriesScript script
1032{
1033	CreateContainerMakeDirectoriesScript $(HAIKU_IMAGE_CONTAINER_NAME)
1034		: $(script) ;
1035}
1036
1037rule CreateHaikuImageCopyFilesScript script
1038{
1039	CreateContainerCopyFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ;
1040}
1041
1042rule CreateHaikuImageExtractFilesScript script
1043{
1044	CreateContainerExtractFilesScript $(HAIKU_IMAGE_CONTAINER_NAME)
1045		: $(script) ;
1046}
1047
1048rule BuildHaikuImage haikuImage : scripts : isImage : isVMwareImage
1049{
1050	# BuildHaikuImage <haiku image> : <scripts> : <is image> : <isVMwareImage> ;
1051
1052	if $(isImage) = 1 || $(isImage) = true {
1053		IS_IMAGE on $(haikuImage) = 1 ;
1054	} else {
1055		IS_IMAGE on $(haikuImage) = "" ;
1056	}
1057
1058	if $(isVMwareImage) = 1 || $(isVMwareImage) = true {
1059		IS_VMWARE_IMAGE on $(haikuImage) = 1 ;
1060	} else {
1061		IS_VMWARE_IMAGE on $(haikuImage) = "" ;
1062	}
1063
1064	local mainScript = build_haiku_image ;
1065	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
1066
1067	Depends $(haikuImage) : $(mainScript) $(scripts) ;
1068	BuildHaikuImage1 $(haikuImage) : $(mainScript) $(scripts) ;
1069}
1070
1071actions BuildHaikuImage1
1072{
1073	export imagePath="$(1)"
1074	export isImage="$(IS_IMAGE)"
1075	export isVMwareImage="$(IS_VMWARE_IMAGE)"
1076	$(2[1]) $(2[2-])
1077}
1078
1079rule BuildVMWareImage vmwareImage : plainImage : imageSize
1080{
1081	# BuildVMWareImage <vmware image> : <plain image> : <image size in MB>
1082
1083	IMAGE_SIZE on $(vmwareImage) = $(imageSize) ;
1084
1085	Depends $(vmwareImage) : <build>vmdkheader $(plainImage) ;
1086	BuildVMWareImage1 $(vmwareImage) : <build>vmdkheader $(plainImage) ;
1087}
1088
1089actions BuildVMWareImage1
1090{
1091	$(RM) $(1)
1092	$(2[1]) -h 64k -i$(IMAGE_SIZE)M $(1) &&
1093	cat $(2[2]) >> $(1)
1094}
1095
1096
1097#pragma mark - Network Boot Archive rules
1098
1099rule AddDirectoryToNetBootArchive directoryTokens
1100{
1101	# AddDirectoryToNetBootArchive <directoryTokens>
1102
1103	return [ AddDirectoryToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1104		: $(directoryTokens) ] ;
1105}
1106
1107rule AddFilesToNetBootArchive directory : targets : destName
1108{
1109	# AddFilesToNetBootArchive <directory> : <targets> [ : dest name ]
1110
1111	AddFilesToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(directory)
1112		: $(targets) : $(destName) ;
1113}
1114
1115rule AddSymlinkToNetBootArchive directoryTokens : linkTarget : linkName
1116{
1117	# AddSymlinkToNetBootArchive <directory> : <link target> [ : <link name> ] ;
1118
1119	AddSymlinkToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1120		: $(directoryTokens) : $(linkTarget) : $(linkName) ;
1121}
1122
1123rule AddDriversToNetBootArchive relativeDirectoryTokens : targets
1124{
1125	# AddDriversToNetBootArchive <relative directory> : <targets> ;
1126
1127	AddDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1128		: $(relativeDirectoryTokens) : $(targets) ;
1129}
1130
1131rule AddNewDriversToNetBootArchive relativeDirectoryTokens : targets
1132{
1133	# AddNewDriversToNetBootArchive <relative directory> : <targets> ;
1134
1135	AddNewDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1136		: $(relativeDirectoryTokens) : $(targets) ;
1137}
1138
1139rule AddDriverRegistrationToNetBootArchive relativeDirectoryTokens : target
1140	: links
1141{
1142	# AddDriverRegistrationToNetBootArchive <directory> : <link target>
1143	#	: <link names> ] ;
1144
1145	AddDriverRegistrationToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1146		: $(relativeDirectoryTokens) : $(target) : $(links) ;
1147}
1148
1149rule AddBootModuleSymlinksToNetBootArchive targets
1150{
1151	# AddBootModuleSymlinksToNetBootArchive <targets> ;
1152
1153	AddBootModuleSymlinksToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1154		: $(targets) ;
1155}
1156
1157rule CreateNetBootArchiveMakeDirectoriesScript script
1158{
1159	CreateContainerMakeDirectoriesScript
1160		$(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(script) ;
1161}
1162
1163rule CreateNetBootArchiveCopyFilesScript script
1164{
1165	CreateContainerCopyFilesScript $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
1166		: $(script) ;
1167}
1168
1169rule BuildNetBootArchive archive : scripts
1170{
1171	# BuildNetBootArchive <archive> : <scripts>  ;
1172
1173	local mainScript = build_archive ;
1174	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
1175
1176	Depends $(archive) : $(mainScript) $(scripts) ;
1177	BuildNetBootArchive1 $(archive) : $(mainScript) $(scripts) ;
1178}
1179
1180actions BuildNetBootArchive1
1181{
1182	$(2[1]) $(1) $(2[2-])
1183}
1184
1185
1186#pragma mark - Floppy Boot Archive rules
1187
1188
1189rule AddDirectoryToFloppyBootArchive directoryTokens
1190{
1191	# AddDirectoryToFloppyBootArchive <directoryTokens>
1192
1193	return [ AddDirectoryToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1194		: $(directoryTokens) ] ;
1195}
1196
1197rule AddFilesToFloppyBootArchive directory : targets : destName
1198{
1199	# AddFilesToFloppyBootArchive <directory> : <targets> [ : dest name ]
1200
1201	AddFilesToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(directory)
1202		: $(targets) : $(destName) ;
1203}
1204
1205rule AddSymlinkToFloppyBootArchive directoryTokens : linkTarget : linkName
1206{
1207	# AddSymlinkToFloppyBootArchive <directory> : <link target>
1208	#	[ : <link name> ] ;
1209
1210	AddSymlinkToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1211		: $(directoryTokens) : $(linkTarget) : $(linkName) ;
1212}
1213
1214rule AddDriversToFloppyBootArchive relativeDirectoryTokens : targets
1215{
1216	# AddDriversToFloppyBootArchive <relative directory> : <targets> ;
1217
1218	AddDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1219		: $(relativeDirectoryTokens) : $(targets) ;
1220}
1221
1222rule AddNewDriversToFloppyBootArchive relativeDirectoryTokens : targets
1223{
1224	# AddNewDriversToFloppyBootArchive <relative directory> : <targets> ;
1225
1226	AddNewDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1227		: $(relativeDirectoryTokens) : $(targets) ;
1228}
1229
1230rule AddDriverRegistrationToFloppyBootArchive relativeDirectoryTokens : target
1231	: links
1232{
1233	# AddDriverRegistrationToFloppyBootArchive <directory> : <link target>
1234	#	: <link names> ] ;
1235
1236	AddDriverRegistrationToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1237		: $(relativeDirectoryTokens) : $(target) : $(links) ;
1238}
1239
1240rule AddBootModuleSymlinksToFloppyBootArchive targets
1241{
1242	# AddBootModuleSymlinksToFloppyBootArchive <targets> ;
1243
1244	AddBootModuleSymlinksToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1245		: $(targets) ;
1246}
1247
1248rule CreateFloppyBootArchiveMakeDirectoriesScript script
1249{
1250	CreateContainerMakeDirectoriesScript
1251		$(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(script) ;
1252}
1253
1254rule CreateFloppyBootArchiveCopyFilesScript script
1255{
1256	CreateContainerCopyFilesScript $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1257		: $(script) ;
1258}
1259
1260rule BuildFloppyBootArchive archive : scripts
1261{
1262	# BuildHFloppyBootArchive <archive> : <scripts>  ;
1263
1264	local mainScript = build_archive ;
1265	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
1266
1267	Depends $(archive) : $(mainScript) $(scripts) ;
1268	BuildFloppyBootArchive1 $(archive) : $(mainScript) $(scripts) ;
1269}
1270
1271actions BuildFloppyBootArchive1
1272{
1273	$(2[1]) $(1) $(2[2-])
1274}
1275
1276# warning: that is quite x86 dependant...
1277
1278rule BuildFloppyBootImage image : haikuLoader : archive
1279{
1280	Depends $(image) : $(haikuLoader) ;
1281	Depends $(image) : $(archive) ;
1282	#MakeLocateDebug $(image) ;
1283	FLOPPY_IMAGE_SIZE on $(image) = $(HAIKU_BOOT_FLOPPY_IMAGE_SIZE) ;
1284	ARCHIVE_IMAGE_OFFSET on $(image) = $(HAIKU_BOOT_ARCHIVE_IMAGE_OFFSET) ;
1285	BuildFloppyBootImage1 $(image) : $(haikuLoader) $(archive) ;
1286	if $(HAIKU_BOOT_PLATFORM) = atari_m68k {
1287		Depends $(image) : <build>fixup_tos_boot_checksum ;
1288		BuildFloppyBootImageFixupM68K $(image)
1289			: <build>fixup_tos_boot_checksum ;
1290	}
1291	if $(HAIKU_BOOT_PLATFORM) = amiga_m68k {
1292		Depends $(image) : <build>fixup_amiga_boot_checksum ;
1293		BuildFloppyBootImageFixupM68K $(image)
1294			: <build>fixup_amiga_boot_checksum ;
1295	}
1296}
1297
1298actions BuildFloppyBootImage1
1299{
1300	haiku_loader_size=`stat -c %s "$(>[1])"`
1301	if [ $? -ne 0 ] ; then
1302		# FreeBSD's stat command don't support -c/--format option
1303		# and use %z specifier for file size
1304		haiku_loader_size=`stat -f %z "$(>[1])"`
1305	fi
1306	archive_image_offset=`echo "$(ARCHIVE_IMAGE_OFFSET) * 1024" | bc`
1307	if [ $haiku_loader_size -gt $archive_image_offset ] ; then
1308		echo "Error: $(>[1]) is too big ($haiku_loader_size) to fit "
1309		echo "       before the boot archive starting at $archive_image_offset!"
1310		exit 1
1311	fi
1312	$(RM) $(<)
1313	# make an empty image
1314	dd if=/dev/zero of=$(<) bs=1k count=$(FLOPPY_IMAGE_SIZE)
1315	# add haiku_loader
1316	dd if=$(>[1]) of=$(<) conv=notrunc
1317	# add the boot drivers tgz archive
1318	dd if=$(>[2]) of=$(<) bs=$(ARCHIVE_IMAGE_OFFSET)k seek=1 conv=notrunc
1319}
1320
1321actions BuildFloppyBootImageFixupM68K
1322{
1323	# fixup the boot sector checksum
1324	$(>[1]) $(<)
1325}
1326
1327#pragma mark - CD Boot Image rules
1328
1329rule BuildCDBootImage image : bootfloppy : extrafiles
1330{
1331	Depends $(image) : $(bootfloppy) ;
1332	Depends $(image) : $(extrafiles) ;
1333	BOOTIMG on $(image) = $(bootfloppy) ;
1334
1335	BuildCDBootImage1 $(image) : $(bootfloppy) $(extrafiles) ;
1336}
1337
1338actions BuildCDBootImage1
1339{
1340	$(RM) $(<)
1341	mkisofs -b $(BOOTIMG) -r -J -V bootimg -o $(<) $(>[1]) $(>[2-])
1342}
1343
1344
1345#pragma mark - CD Boot PPC Image rules
1346
1347rule BuildCDBootPPCImage image : hfsmaps : elfloader : coffloader : chrpscript
1348	: extrafiles
1349{
1350	Depends $(image) : $(elfloader) ;
1351	Depends $(image) : $(coffloader) ;
1352	Depends $(image) : $(chrpscript) ;
1353	Depends $(image) : $(extrafiles) ;
1354	Depends $(image) : $(hfsmaps) ;
1355	MAPS on $(image) = $(hfsmaps) ;
1356
1357	BuildCDBootPPCImage1 $(image) : $(elfloader) $(coffloader) $(chrpscript)
1358		$(extrafiles) ;
1359}
1360
1361actions BuildCDBootPPCImage1 bind MAPS
1362{
1363	$(RM) $(<)
1364	mkdir -p $(HAIKU_OUTPUT_DIR)/cd/ppc
1365	cp $(>) $(HAIKU_OUTPUT_DIR)/cd/ppc/
1366	cp $(>[3]) $(HAIKU_OUTPUT_DIR)/cd/ppc/bootinfo.txt
1367	cp $(>[1]) $(HAIKU_OUTPUT_DIR)/cd/ofwboot.elf
1368	cp $(>[2]) $(HAIKU_OUTPUT_DIR)/cd/ofwboot.xcf
1369	#mkisofs -r -U -chrp-boot -V bootimg -o $(<) $(>[1]) $(>[2-])
1370	#mkisofs -hfs -r -U -chrp-boot -part -map $(MAPS) -no-desktop \
1371	#	-hfs-volid bootimg -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1])
1372	#	- $(>[2-])
1373	#mkisofs -v -hfs -part -map $(MAPS) -no-desktop -hfs-volid bootimg \
1374	#	-V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/ppc -r -o $(<) $(>[1]) \
1375	#	$(>[2-]) $(HAIKU_OUTPUT_DIR)/cd
1376	#mkisofs -r -U -chrp-boot -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) \
1377	#	$(>[2-])
1378	#mkisofs -r -U -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) $(>[2-])
1379	# $(HAIKU_OUTPUT_DIR)/cd
1380	# -hfs -hfs-bless .
1381	mkisofs -v -hfs -part -map $(MAPS) -no-desktop -hfs-volid bootimg \
1382		-V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/ppc -prep-boot \
1383		ppc/$(>[2]:D=) -r -o $(<) $(HAIKU_OUTPUT_DIR)/cd
1384	#$(RM) -R $(HAIKU_OUTPUT_DIR)/cd
1385}
1386
1387
1388