ImageRules revision 47577f1c
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}
194
195rule FFilesInContainerDirectory container : directoryTokens
196{
197	local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
198	local directory = [ FDirName $(directoryTokens) ] ;
199	directory = $(directory:G=$(containerGrist)) ;
200
201	if [ on $(directory) return $(__is_on_image) ] {
202		on $(directory) return $(TARGETS_TO_INSTALL) ;
203	}
204
205	return ;
206}
207
208rule AddSymlinkToContainer container : directoryTokens : linkTarget : linkName
209{
210	# AddSymlinkToContainer <container> : <directory> : <link target>
211	#	[ : <link name> ] ;
212	#
213
214	# If the image shall only be updated, we don't add any symlinks.
215	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
216		&& ! [ IncludeAllTargetsInContainer $(container) ] {
217		return ;
218	}
219
220	local directory = [ AddDirectoryToContainer $(container)
221		: $(directoryTokens) ] ;
222
223	if ! $(linkName) {
224		local path = [ FReverse [ FSplitPath $(linkTarget) ] ] ;
225		linkName = $(path[1]) ;
226	}
227
228	local link = $(directory)/$(linkName) ;
229	SYMLINK_TARGET on $(link) = $(linkTarget) ;
230	SYMLINKS_TO_INSTALL on $(directory) += $(link) ;
231}
232
233rule FSymlinksInContainerDirectory container : directoryTokens
234{
235	local containerGrist = [ on $(container) return $(HAIKU_CONTAINER_GRIST) ] ;
236	local directory = [ FDirName $(directoryTokens) ] ;
237	directory = $(directory:G=$(containerGrist)) ;
238
239	if [ on $(directory) return $(__is_on_image) ] {
240		on $(directory) return $(SYMLINKS_TO_INSTALL) ;
241	}
242
243	return ;
244}
245
246rule CopyDirectoryToContainer container : directoryTokens : sourceDirectory
247	: targetDirectoryName : excludePatterns : alwaysUpdate
248{
249	# CopyDirectoryToContainer <container> : <directoryTokens>
250	#	: <sourceDirectory> : <targetDirectoryName> : <excludePatterns>
251	#	: <alwaysUpdate> ;
252	#
253
254	# If the image shall only be updated, we don't copy any directories
255	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
256			&& ! [ IncludeAllTargetsInContainer $(container) ]
257			&& ! $(alwaysUpdate) {
258		return ;
259	}
260
261	if ! $(targetDirectoryName) {
262		local path = [ FReverse [ FSplitPath $(sourceDirectory) ] ] ;
263		targetDirectoryName = $(path[1]) ;
264	}
265
266	local directory = [ AddDirectoryToContainer $(container)
267		: $(directoryTokens) $(targetDirectoryName) ] ;
268
269	local targetDir = $(directory)/-/$(sourceDirectory) ;
270	EXCLUDE_PATTERNS on $(targetDir) = $(excludePatterns) ;
271	SOURCE_DIRECTORY on $(targetDir) = $(sourceDirectory) ;
272	TARGET_DIRECTORY on $(targetDir) = $(directory) ;
273	DIRECTORIES_TO_INSTALL on $(directory) += $(targetDir) ;
274}
275
276rule UnzipArchiveToContainer container : directoryTokens : zipFile
277{
278	# UnzipArchiveToContainer <container> : <directory> : <zipFile> ] ;
279	#
280
281	local directory = [ AddDirectoryToContainer $(container)
282		: $(directoryTokens) ] ;
283
284	ZIP_FILES_TO_INSTALL on $(directory) += $(zipFile) ;
285}
286
287rule AddDriversToContainer container : relativeDirectoryTokens : targets
288{
289	# AddDriversToContainer <container> : <relative directory> : <targets> ;
290	#
291	local directoryTokens = beos system add-ons kernel drivers dev
292		$(relativeDirectoryTokens) ;
293
294	AddFilesToContainer $(container) : beos system add-ons kernel drivers bin
295		: $(targets) ;
296
297	# If the image shall only be updated, we don't add any symlinks.
298	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
299		&& ! [ IncludeAllTargetsInContainer $(container) ] {
300		return ;
301	}
302
303	# get the relative symlink path prefix
304	local linkPrefix = ;
305	for i in $(relativeDirectoryTokens) {
306		linkPrefix += .. ;
307	}
308	linkPrefix += .. bin ;
309
310	# add the symlinks
311	local name ;
312	for name in $(targets:BS) {
313		AddSymlinkToContainer $(container) : $(directoryTokens)
314			: [ FDirName $(linkPrefix) $(name) ] : $(name) ;
315	}
316}
317
318rule AddNewDriversToContainer container : relativeDirectoryTokens
319	: targets
320{
321	# AddNewDriversToContainer <container> : <directory> : <targets> ;
322	#
323	local directoryTokens = beos system add-ons kernel drivers
324		$(relativeDirectoryTokens) ;
325
326	AddFilesToContainer $(container) : $(directoryTokens)
327		: $(targets) ;
328}
329
330rule AddBootModuleSymlinksToContainer container : targets
331{
332	# AddBootModuleSymlinksToContainer <container> : <targets> ;
333	#
334
335	# If the image shall only be updated, we don't add any symlinks.
336	if [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
337		&& ! [ IncludeAllTargetsInContainer $(container) ] {
338		return ;
339	}
340
341	# add the symlinks
342	local installTargetsVar
343		= [ on $(container) return $(HAIKU_INSTALL_TARGETS_VAR) ] ;
344	local target ;
345	for target in $(targets) {
346		# Symlink to the first place where the target has been installed.
347		local destTarget = [ on $(target) return $($(installTargetsVar)[1]) ] ;
348		local installDir = [ on $(destTarget) return $(INSTALL_DIR) ] ;
349
350		if ! $(installDir) {
351			Echo "ERROR: AddBootModuleSymlinksToContainer: Can't create a "
352				"symlink to target" \"$(target)"\"." ;
353			Exit "ERROR: Add*ToContainer has not been invoked for it yet." ;
354		}
355
356		local name = $(target:BS) ;
357		local linkTarget = [ FDirName /boot $(installDir:G=) $(name) ] ;
358
359		AddSymlinkToContainer $(container) : beos system add-ons kernel boot
360			: $(linkTarget) : $(name) ;
361	}
362}
363
364
365rule CreateContainerMakeDirectoriesScript container : script
366{
367	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
368	Always $(script) ;
369
370	local initScript = [ InitScript $(script) ] ;
371
372	local scriptBody
373		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
374	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
375	Depends $(scriptBody) : $(initScript) ;
376	Depends $(script) : $(scriptBody) ;
377
378	# collect the directories to create
379	local dirsToCreate ;
380	local directories = [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] ;
381	local dir ;
382	for dir in $(directories) {
383		if ! [ on $(dir) return $(DONT_CREATE) ] {
384			dirsToCreate += $(dir) ;
385		}
386	}
387
388	# If the image shall only be updated, we don't create directories.
389	if $(dirsToCreate)
390		&& ( ! [ on $(container) return $(HAIKU_CONTAINER_UPDATE_ONLY) ]
391			|| [ IncludeAllTargetsInContainer $(container) ] ) {
392		Depends $(scriptBody) : $(dirsToCreate) ;
393		CreateContainerMakeDirectoriesScript1 $(scriptBody) : $(dirsToCreate) ;
394
395		# For directories with attributes, we convert those the specified
396		# resource files to files with attributes and add commands to the script
397		# adding the attributes to the directories.
398		for dir in $(directories) {
399			local resourceFiles = [ on $(dir) return $(ATTRIBUTE_FILES) ] ;
400			if $(resourceFiles) {
401				local dirTokens = [ on $(dir) return $(DIRECTORY_TOKENS) ] ;
402
403				# translate resources file to file with attributes
404				local attributeFile = $(script)-attributes-$(dirTokens:J=-) ;
405				ResAttr $(attributeFile) : $(resourceFiles) ;
406
407				# use a unique dummy target for this file, on which we
408				# can define the TARGET_DIR variable
409				local dummyTarget = $(script)-attributes-dummy-$(dir:G=) ;
410				NotFile $(dummyTarget) ;
411				TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
412
413				Depends $(dummyTarget) : $(initScript) $(attributeFile) ;
414				Depends $(script) : $(dummyTarget) ;
415
416				AppendToContainerMakeDirectoriesScriptAttributes $(dummyTarget)
417					: $(initScript) $(attributeFile) ;
418			}
419		}
420	}
421}
422
423actions piecemeal CreateContainerMakeDirectoriesScript1
424{
425	echo \$mkdir -p "\"\${tPrefix}$(2:G=)\"" >> $(1)
426}
427
428actions AppendToContainerMakeDirectoriesScriptAttributes
429{
430	echo \$copyAttrs "\"\${sPrefix}$(2[2])\"" \
431		"\"\${tPrefix}$(TARGET_DIR)\"" >> $(2[1])
432}
433
434rule CreateContainerCopyFilesScript container : script
435{
436	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
437	Always $(script) ;
438
439	local initScript = [ InitScript $(script) ] ;
440
441	local scriptBody
442		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
443	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
444	Depends $(scriptBody) : $(initScript) ;
445	Depends $(script) : $(scriptBody) ;
446
447	local dir ;
448	for dir in [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] {
449		# filter the targets that shall be renamed; they have to be copied
450		# individually
451		local destTargets = [ on $(dir) return $(TARGETS_TO_INSTALL) ] ;
452		local remainingTargets ;
453		local destTarget ;
454		for destTarget in $(destTargets) {
455			local target = [ on $(destTarget) return $(TARGET) ] ;
456			local name = $(destTarget:BS) ;
457			if $(name) != $(target:BS) {
458				# use a unique dummy target for this file, on which we
459				# can define the TARGET_DIR variable
460				local dummyTarget = $(script)-dummy-$(dir:G=)-$(target) ;
461				NotFile $(dummyTarget) ;
462				TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
463				INSTALL_TARGET_NAME on $(dummyTarget) = $(name) ;
464
465				Depends $(dummyTarget) : $(initScript) $(target) ;
466				Depends $(script) : $(dummyTarget) ;
467
468				AppendToContainerCopyFilesScriptSingleFile $(dummyTarget)
469					: $(initScript) $(target) ;
470			} else {
471				remainingTargets += $(target) ;
472			}
473		}
474		targets = $(remainingTargets) ;
475
476		if $(targets) {
477			# use a unique dummy target for this directory, on which we
478			# can define the TARGET_DIR variable
479			local dummyTarget = $(script)-dummy-$(dir:G=) ;
480			NotFile $(dummyTarget) ;
481			TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
482
483			Depends $(dummyTarget) : $(initScript) $(targets) ;
484			Depends $(script) : $(dummyTarget) ;
485
486			OUTPUT_SCRIPT on $(dummyTarget) = $(initScript) ;
487			AppendToContainerCopyFilesScript $(dummyTarget) : $(targets) ;
488		}
489
490		local symlinks = [ on $(dir) return $(SYMLINKS_TO_INSTALL) ] ;
491		local symlink ;
492		for symlink in $(symlinks) {
493			NotFile $(symlink) ;
494
495			Depends $(script) : $(symlink) ;
496			Depends $(symlink) : $(initScript) ;
497
498			AddSymlinkToContainerCopyFilesScript $(symlink) : $(initScript) ;
499		}
500
501		local targetDirs = [ on $(dir) return $(DIRECTORIES_TO_INSTALL) ] ;
502		local targetDir ;
503		for targetDir in $(targetDirs) {
504			NotFile $(targetDir) ;
505
506			Depends $(script) : $(targetDir) ;
507			Depends $(targetDir) : $(initScript) ;
508
509			AddDirectoryToContainerCopyFilesScript $(targetDir) : $(initScript) ;
510		}
511	}
512}
513
514
515actions piecemeal AppendToContainerCopyFilesScript bind OUTPUT_SCRIPT
516{
517	echo \$cp "\"\${sPrefix}$(2)\"" "\"\${tPrefix}$(TARGET_DIR)\"" >> $(OUTPUT_SCRIPT)
518}
519
520
521actions AppendToContainerCopyFilesScriptSingleFile
522{
523	echo \$cp "\"\${sPrefix}$(2[2])\"" \
524		"\"\${tPrefix}$(TARGET_DIR)/$(INSTALL_TARGET_NAME)\"" >> $(2[1])
525}
526
527
528actions AddSymlinkToContainerCopyFilesScript
529{
530	echo \$ln -sfn "\"$(SYMLINK_TARGET)\"" "\"\${tPrefix}$(1:G=)\"" >> $(2[1])
531}
532
533
534actions AddDirectoryToContainerCopyFilesScript
535{
536	echo \$cp -r $(EXCLUDE_PATTERNS) "\"\${sPrefix}$(SOURCE_DIRECTORY)/.\"" \
537		"\"\${tPrefix}$(TARGET_DIRECTORY:G=)\"" >> $(2[1])
538}
539
540
541rule CreateContainerUnzipFilesScript container : script
542{
543	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
544	Always $(script) ;
545
546	local initScript = [ InitScript $(script) ] ;
547
548	local scriptBody
549		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
550	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
551	Depends $(scriptBody) : $(initScript) ;
552	Depends $(script) : $(scriptBody) ;
553
554	local dir ;
555	for dir in [ on $(container) return $(HAIKU_INSTALL_DIRECTORIES) ] {
556		local zipFiles = [ on $(dir) return $(ZIP_FILES_TO_INSTALL) ] ;
557		local zipFile ;
558		for zipFile in $(zipFiles) {
559			# use a unique dummy target for this file, on which we
560			# can define the TARGET_DIR variable
561			local dummyTarget = $(script)-dummy-$(dir:G=)-$(zipFile) ;
562			NotFile $(dummyTarget) ;
563			TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
564
565			Depends $(dummyTarget) : $(initScript) $(zipFile) ;
566			Depends $(script) : $(dummyTarget) ;
567
568			AddUnzipFileToContainerUnzipFilesScript $(dummyTarget)
569				: $(initScript) $(zipFile) ;
570		}
571	}
572}
573
574actions AddUnzipFileToContainerUnzipFilesScript
575{
576	echo unzipFile "\"$(2[2])\"" "\"$(TARGET_DIR)\"" >> $(2[1])
577}
578
579
580#pragma mark - Haiku Image rules
581
582rule SetUpdateHaikuImageOnly flag
583{
584	HAIKU_CONTAINER_UPDATE_ONLY on $(HAIKU_IMAGE_CONTAINER_NAME) = $(flag) ;
585}
586
587rule IsUpdateHaikuImageOnly
588{
589	on $(HAIKU_IMAGE_CONTAINER_NAME) return $(HAIKU_CONTAINER_UPDATE_ONLY) ;
590}
591
592rule AddDirectoryToHaikuImage directoryTokens : attributeFiles
593{
594	# AddDirectoryToHaikuImage <directoryTokens>
595
596	local dir = [ AddDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
597		: $(directoryTokens) ] ;
598
599	if $(attributeFiles) {
600		SEARCH on $(attributeFiles)
601			+= [ FDirName $(HAIKU_TOP) data image_directories ] ;
602		ATTRIBUTE_FILES on $(dir) += $(attributeFiles) ;
603	}
604
605	return $(dir) ;
606}
607
608rule AddFilesToHaikuImage directory : targets : destName
609{
610	# AddFilesToHaikuImage <directory> : <targets> [ : dest name ]
611
612	AddFilesToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directory)
613		: $(targets) : $(destName) ;
614}
615
616rule FFilesInHaikuImageDirectory directoryTokens
617{
618	return [ FFilesInContainerDirectory $(HAIKU_IMAGE_CONTAINER_NAME)
619		: $(directoryTokens) ] ;
620}
621
622rule AddSymlinkToHaikuImage directoryTokens : linkTarget : linkName
623{
624	# AddSymlinkToHaikuImage <directory> : <link target> [ : <link name> ] ;
625
626	AddSymlinkToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens)
627		: $(linkTarget) : $(linkName) ;
628}
629
630rule FSymlinksInHaikuImageDirectory directoryTokens
631{
632	return [ FSymlinksInContainerDirectory $(HAIKU_IMAGE_CONTAINER_NAME)
633		: $(directoryTokens) ] ;
634}
635
636rule CopyDirectoryToHaikuImage directoryTokens : sourceDirectory
637	: targetDirectoryName : excludePatterns : alwaysUpdate
638{
639	CopyDirectoryToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(directoryTokens)
640		: $(sourceDirectory) : $(targetDirectoryName) : $(excludePatterns)
641		: $(alwaysUpdate) ;
642}
643
644rule AddSourceDirectoryToHaikuImage dirTokens : alwaysUpdate
645{
646	# AddSourceDirectoryToHaikuImage <dirTokens> : <alwaysUpdate> ;
647
648	CopyDirectoryToHaikuImage home HaikuSources
649		: [ FDirName $(HAIKU_TOP) $(dirTokens) ]
650		: : -x .svn : $(alwaysUpdate) ;
651}
652
653rule AddHeaderDirectoryToHaikuImage dirTokens : dirName : alwaysUpdate
654{
655	# AddHeaderDirectoryToHaikuImage <dirTokens> : [ <dirName> ]
656	#	: <alwaysUpdate> ;
657
658	CopyDirectoryToHaikuImage develop headers
659		: [ FDirName $(HAIKU_TOP) headers $(dirTokens) ]
660		: $(dirName) : -x .svn : $(alwaysUpdate) ;
661}
662
663rule UnzipArchiveToHaikuImage dirTokens : zipFile : alwaysUpdate
664{
665	# UnzipArchiveToHaikuImage <dirTokens> : <zipFile> : <alwaysUpdate> ;
666
667	# If the image shall only be updated, we unzip only, if explicitely
668	# requested.
669	if ! [ IsUpdateHaikuImageOnly ] || $(alwaysUpdate) {
670		UnzipArchiveToContainer $(HAIKU_IMAGE_CONTAINER_NAME) : $(dirTokens)
671			: $(zipFile) ;
672	}
673}
674
675rule AddDriversToHaikuImage relativeDirectoryTokens : targets
676{
677	# AddDriversToHaikuImage <relative directory> : <targets> ;
678
679	AddDriversToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
680		: $(relativeDirectoryTokens) : $(targets) ;
681}
682
683rule AddNewDriversToHaikuImage relativeDirectoryTokens : targets
684{
685	# AddNewDriversToHaikuImage <relative directory> : <targets> ;
686
687	AddNewDriversToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
688		: $(relativeDirectoryTokens) : $(targets) ;
689}
690
691rule AddBootModuleSymlinksToHaikuImage targets
692{
693	# AddBootModuleSymlinksToHaikuImage <targets> ;
694
695	AddBootModuleSymlinksToContainer $(HAIKU_IMAGE_CONTAINER_NAME)
696		: $(targets) ;
697}
698
699rule AddOptionalHaikuImagePackages packages
700{
701	HAIKU_OPTIONAL_PACKAGE_ADDED on $(packages) = 1 ;
702}
703
704rule IsOptionalHaikuImagePackageAdded package
705{
706	if [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] {
707		return 1 ;
708	}
709
710	return $(HAIKU_ADD_ALL_OPTIONAL_PACKAGES) ;
711}
712
713rule OptionalPackageDependencies package : dependencies
714{
715	if [ IsOptionalHaikuImagePackageAdded $(package) ] {
716		AddOptionalHaikuImagePackages $(dependencies) ;
717	}
718}
719
720rule InstallOptionalHaikuImagePackage package : url : dirTokens
721{
722	# download zip file
723	local zipFile = $(package:G=download).zip ;
724	MakeLocate $(zipFile) : $(HAIKU_DOWNLOAD_DIR) ;
725	DownloadFile $(zipFile) : $(url) ;
726
727	# unzip onto image
728	UnzipArchiveToHaikuImage $(dirTokens) : $(zipFile) ;
729}
730
731rule AddEntryToHaikuImageUserGroupFile file : entry
732{
733	local allEntries = [ on $(file) return $(HAIKU_IMAGE_USER_GROUP_ENTRIES) ] ;
734
735	if $(allEntries) {
736		allEntries = $(allEntries)|$(entry) ;
737	} else {
738		allEntries = $(entry) ;
739
740		Always $(file) ;
741		MakeLocate $(file) : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ;
742		BuildHaikuImageUserGroupFile $(file) ;
743		AddFilesToHaikuImage beos etc : $(file) ;
744	}
745
746	HAIKU_IMAGE_USER_GROUP_ENTRIES on $(file) = $(allEntries) ;
747}
748
749actions BuildHaikuImageUserGroupFile
750{
751	echo "$(HAIKU_IMAGE_USER_GROUP_ENTRIES)" | tr '|' '\n' > $(1)
752}
753
754rule AddUserToHaikuImage user : uid : gid : home : shell : realName
755{
756	if ! $(user) || ! $(uid) || ! $(gid) || ! $(home) {
757		Exit "Invalid haiku user specification passed to AddUserToHaikuImage." ;
758	}
759
760	local entry
761		= $(user):x:$(uid):$(gid):$(realName:E=$(user)):$(home):$(shell:E="") ;
762
763	AddEntryToHaikuImageUserGroupFile <haiku-image>passwd : $(entry) ;
764}
765
766rule AddGroupToHaikuImage group : gid : members
767{
768	if ! $(group) || ! $(gid) {
769		Exit "Invalid haiku group specification passed to"
770			"AddGroupToHaikuImage." ;
771	}
772
773	local entry = $(group):x:$(gid):$(members:J=,:E) ;
774
775	AddEntryToHaikuImageUserGroupFile <haiku-image>group : $(entry) ;
776}
777
778rule AddOptionalPackageDescriptionToHaikuImage file : searchPath
779{
780	if $(searchPath) {
781		SEARCH on $(file) = [ FDirName $(searchPath) ] ;
782	}
783
784	HAIKU_IMAGE_OPTIONAL_PACKAGE_DESCRIPTIONS += $(file) ;
785}
786
787rule AddLicenseToHaikuImage file : name : searchPath
788{
789	if $(searchPath) {
790		SEARCH on $(file) = [ FDirName $(searchPath) ] ;
791	}
792
793	if $(name) && $(file:BS) = $(name) {
794		name = ;
795	}
796
797	AddFilesToHaikuImage beos etc licenses : $(file) : $(name) ;
798}
799
800
801rule CreateHaikuImageMakeDirectoriesScript script
802{
803	CreateContainerMakeDirectoriesScript $(HAIKU_IMAGE_CONTAINER_NAME)
804		: $(script) ;
805}
806
807rule CreateHaikuImageCopyFilesScript script
808{
809	CreateContainerCopyFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ;
810}
811
812rule CreateHaikuImageUnzipFilesScript script
813{
814	CreateContainerUnzipFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ;
815}
816
817rule BuildHaikuImage haikuImage : scripts : isImage : isVMwareImage
818{
819	# BuildHaikuImage <haiku image> : <scripts> : <is image> : <isVMwareImage> ;
820
821	if $(isImage) = 1 || $(isImage) = true {
822		IS_IMAGE on $(haikuImage) = 1 ;
823	} else {
824		IS_IMAGE on $(haikuImage) = "" ;
825	}
826
827	if $(isVMwareImage) = 1 || $(isVMwareImage) = true {
828		IS_VMWARE_IMAGE on $(haikuImage) = 1 ;
829	} else {
830		IS_VMWARE_IMAGE on $(haikuImage) = "" ;
831	}
832
833	local mainScript = build_haiku_image ;
834	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
835
836	Depends $(haikuImage) : $(mainScript) $(scripts) ;
837	BuildHaikuImage1 $(haikuImage) : $(mainScript) $(scripts) ;
838}
839
840actions BuildHaikuImage1
841{
842	export imagePath="$(1)"
843	export isImage="$(IS_IMAGE)"
844	export isVMwareImage="$(IS_VMWARE_IMAGE)"
845	$(2[1]) $(2[2-])
846}
847
848rule BuildVMWareImage vmwareImage : plainImage : imageSize
849{
850	# BuildVMWareImage <vmware image> : <plain image> : <image size in MB>
851
852	IMAGE_SIZE on $(vmwareImage) = $(imageSize) ;
853
854	Depends $(vmwareImage) : <build>vmdkheader $(plainImage) ;
855	BuildVMWareImage1 $(vmwareImage) : <build>vmdkheader $(plainImage) ;
856}
857
858actions BuildVMWareImage1
859{
860	$(RM) $(1)
861	$(2[1]) -h 64k -i$(IMAGE_SIZE)M $(1) &&
862	cat $(2[2]) >> $(1)
863}
864
865
866#pragma mark - Network Boot Archive rules
867
868rule AddDirectoryToNetBootArchive directoryTokens
869{
870	# AddDirectoryToNetBootArchive <directoryTokens>
871
872	return [ AddDirectoryToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
873		: $(directoryTokens) ] ;
874}
875
876rule AddFilesToNetBootArchive directory : targets : destName
877{
878	# AddFilesToNetBootArchive <directory> : <targets> [ : dest name ]
879
880	AddFilesToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(directory)
881		: $(targets) : $(destName) ;
882}
883
884rule AddSymlinkToNetBootArchive directoryTokens : linkTarget : linkName
885{
886	# AddSymlinkToNetBootArchive <directory> : <link target> [ : <link name> ] ;
887
888	AddSymlinkToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
889		: $(directoryTokens) : $(linkTarget) : $(linkName) ;
890}
891
892rule AddDriversToNetBootArchive relativeDirectoryTokens : targets
893{
894	# AddDriversToNetBootArchive <relative directory> : <targets> ;
895
896	AddDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
897		: $(relativeDirectoryTokens) : $(targets) ;
898}
899
900rule AddDriverRegistrationToNetBootArchive relativeDirectoryTokens : target
901	: links
902{
903	# AddDriverRegistrationToNetBootArchive <directory> : <link target>
904	#	: <link names> ] ;
905
906	AddDriverRegistrationToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
907		: $(relativeDirectoryTokens) : $(target) : $(links) ;
908}
909
910rule AddBootModuleSymlinksToNetBootArchive targets
911{
912	# AddBootModuleSymlinksToNetBootArchive <targets> ;
913
914	AddBootModuleSymlinksToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
915		: $(targets) ;
916}
917
918rule CreateNetBootArchiveMakeDirectoriesScript script
919{
920	CreateContainerMakeDirectoriesScript
921		$(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(script) ;
922}
923
924rule CreateNetBootArchiveCopyFilesScript script
925{
926	CreateContainerCopyFilesScript $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
927		: $(script) ;
928}
929
930rule BuildNetBootArchive archive : scripts
931{
932	# BuildHNetBootArchive <archive> : <scripts>  ;
933
934	local mainScript = build_tgz_archive ;
935	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
936
937	Depends $(archive) : $(mainScript) $(scripts) ;
938	BuildNetBootArchive1 $(archive) : $(mainScript) $(scripts) ;
939}
940
941actions BuildNetBootArchive1
942{
943	$(2[1]) $(1) $(2[2-])
944}
945
946
947#pragma mark - Floppy Boot Archive rules
948
949rule AddDirectoryToFloppyBootArchive directoryTokens
950{
951	# AddDirectoryToFloppyBootArchive <directoryTokens>
952
953	return [ AddDirectoryToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
954		: $(directoryTokens) ] ;
955}
956
957rule AddFilesToFloppyBootArchive directory : targets : destName
958{
959	# AddFilesToFloppyBootArchive <directory> : <targets> [ : dest name ]
960
961	AddFilesToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(directory)
962		: $(targets) : $(destName) ;
963}
964
965rule AddSymlinkToFloppyBootArchive directoryTokens : linkTarget : linkName
966{
967	# AddSymlinkToFloppyBootArchive <directory> : <link target> [ : <link name> ] ;
968
969	AddSymlinkToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
970		: $(directoryTokens) : $(linkTarget) : $(linkName) ;
971}
972
973rule AddDriversToFloppyBootArchive relativeDirectoryTokens : targets
974{
975	# AddDriversToFloppyBootArchive <relative directory> : <targets> ;
976
977	AddDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
978		: $(relativeDirectoryTokens) : $(targets) ;
979}
980
981rule AddDriverRegistrationToFloppyBootArchive relativeDirectoryTokens : target
982	: links
983{
984	# AddDriverRegistrationToFloppyBootArchive <directory> : <link target>
985	#	: <link names> ] ;
986
987	AddDriverRegistrationToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
988		: $(relativeDirectoryTokens) : $(target) : $(links) ;
989}
990
991rule AddBootModuleSymlinksToFloppyBootArchive targets
992{
993	# AddBootModuleSymlinksToFloppyBootArchive <targets> ;
994
995	AddBootModuleSymlinksToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
996		: $(targets) ;
997}
998
999rule CreateFloppyBootArchiveMakeDirectoriesScript script
1000{
1001	CreateContainerMakeDirectoriesScript
1002		$(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(script) ;
1003}
1004
1005rule CreateFloppyBootArchiveCopyFilesScript script
1006{
1007	CreateContainerCopyFilesScript $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1008		: $(script) ;
1009}
1010
1011rule BuildFloppyBootArchive archive : scripts
1012{
1013	# BuildHFloppyBootArchive <archive> : <scripts>  ;
1014
1015	local mainScript = build_tgz_archive ;
1016	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
1017
1018	Depends $(archive) : $(mainScript) $(scripts) ;
1019	BuildFloppyBootArchive1 $(archive) : $(mainScript) $(scripts) ;
1020}
1021
1022actions BuildFloppyBootArchive1
1023{
1024	$(2[1]) $(1) $(2[2-])
1025}
1026
1027# warning: that is quite x86 dependant...
1028
1029rule BuildFloppyBootImage image : zbeos : archive
1030{
1031	Depends $(image) : $(zbeos) ;
1032	Depends $(image) : $(archive) ;
1033	#MakeLocateDebug $(image) ;
1034	BuildFloppyBootImage1 $(image) : $(zbeos) $(archive) ;
1035}
1036
1037actions BuildFloppyBootImage1
1038{
1039	$(RM) $(<)
1040	# make an empty image
1041	dd if=/dev/zero of=$(<) bs=1k count=1440
1042	# add zbeos
1043	dd if=$(>[1]) of=$(<) conv=notrunc
1044	# add the boot drivers tgz archive
1045	# keep the offset in sync with
1046	# src/system/boot/loader/file_systems/tarfs/tarfs.cpp:kFloppyArchiveOffset
1047	dd if=$(>[2]) of=$(<) bs=192k seek=1 conv=notrunc
1048}
1049
1050
1051#pragma mark - CD Boot Image rules
1052
1053rule BuildCDBootImage image : bootfloppy : extrafiles
1054{
1055	Depends $(image) : $(bootfloppy) ;
1056	Depends $(image) : $(extrafiles) ;
1057	BOOTIMG on $(image) = $(bootfloppy) ;
1058
1059	BuildCDBootImage1 $(image) : $(bootfloppy) $(extrafiles) ;
1060}
1061
1062actions BuildCDBootImage1
1063{
1064	$(RM) $(<)
1065	mkisofs -b $(BOOTIMG) -r -J -V bootimg -o $(<) $(>[1]) $(>[2-])
1066}
1067
1068
1069#pragma mark - CD Boot PPC Image rules
1070
1071rule BuildCDBootPPCImage image : hfsmaps : elfloader : coffloader : chrpscript : extrafiles
1072{
1073	Depends $(image) : $(elfloader) ;
1074	Depends $(image) : $(coffloader) ;
1075	Depends $(image) : $(chrpscript) ;
1076	Depends $(image) : $(extrafiles) ;
1077	Depends $(image) : $(hfsmaps) ;
1078	MAPS on $(image) = $(hfsmaps) ;
1079
1080	BuildCDBootPPCImage1 $(image) : $(elfloaders) $(coffloader) $(chrpscript) $(extrafiles) ;
1081}
1082
1083actions BuildCDBootPPCImage1 bind MAPS
1084{
1085	$(RM) $(<)
1086	mkdir -p $(HAIKU_OUTPUT_DIR)/cd/ppc
1087	cp $(>) $(HAIKU_OUTPUT_DIR)/cd/ppc/
1088	cp $(>[3]) $(HAIKU_OUTPUT_DIR)/cd/ppc/bootinfo.txt
1089	cp $(>[1]) $(HAIKU_OUTPUT_DIR)/cd/ofwboot.elf
1090	cp $(>[2]) $(HAIKU_OUTPUT_DIR)/cd/ofwboot.xcf
1091	#mkisofs -r -U -chrp-boot -V bootimg -o $(<) $(>[1]) $(>[2-])
1092	#mkisofs -hfs -r -U -chrp-boot -part -map $(MAPS) -no-desktop -hfs-volid bootimg -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) $(>[2-])
1093	#mkisofs -v -hfs -part -map $(MAPS) -no-desktop -hfs-volid bootimg -V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/ppc -r -o $(<) $(>[1]) $(>[2-]) $(HAIKU_OUTPUT_DIR)/cd
1094	#mkisofs -r -U -chrp-boot -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) $(>[2-])
1095	#mkisofs -r -U -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) $(>[2-])
1096	# $(HAIKU_OUTPUT_DIR)/cd
1097	# -hfs -hfs-bless .
1098	mkisofs -v -hfs -part -map $(MAPS) -no-desktop -hfs-volid bootimg -V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/ppc -prep-boot ppc/$(>[2]:D=) -r -o $(<) $(HAIKU_OUTPUT_DIR)/cd
1099	#$(RM) -R $(HAIKU_OUTPUT_DIR)/cd
1100}
1101
1102
1103