xref: /haiku/build/jam/ImageRules (revision 1b80286772b529a3d6de3bbeb0720c62e6a32fed)
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 = system add-ons kernel drivers dev
292		$(relativeDirectoryTokens) ;
293
294	AddFilesToContainer $(container) : 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 = 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) : 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	local package ;
702	for package in $(packages) {
703		if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] {
704			HAIKU_OPTIONAL_PACKAGE_ADDED on $(package) = 1 ;
705			HAIKU_ADDED_OPTIONAL_PACKAGES += $(package) ;
706		}
707	}
708}
709
710rule IsOptionalHaikuImagePackageAdded package
711{
712	if ! [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_EXISTS) ] {
713		HAIKU_OPTIONAL_PACKAGE_EXISTS on $(package) = 1 ;
714		HAIKU_EXISTING_OPTIONAL_PACKAGES += $(package) ;
715	}
716
717	if [ on $(package) return $(HAIKU_OPTIONAL_PACKAGE_ADDED) ] {
718		return 1 ;
719	}
720
721	return ;
722}
723
724rule OptionalPackageDependencies package : dependencies
725{
726	if [ IsOptionalHaikuImagePackageAdded $(package) ] {
727		AddOptionalHaikuImagePackages $(dependencies) ;
728	}
729}
730
731rule InstallOptionalHaikuImagePackage package : url : dirTokens
732{
733	# download zip file
734	local zipFile = [ DownloadOptionalPackage $(package) : $(url) ] ;
735
736	# unzip onto image
737	UnzipArchiveToHaikuImage $(dirTokens) : $(zipFile) ;
738}
739
740rule AddEntryToHaikuImageUserGroupFile file : entry
741{
742	local allEntries = [ on $(file) return $(HAIKU_IMAGE_USER_GROUP_ENTRIES) ] ;
743
744	if $(allEntries) {
745		allEntries = $(allEntries)|$(entry) ;
746	} else {
747		allEntries = $(entry) ;
748
749		Always $(file) ;
750		MakeLocate $(file) : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ;
751		BuildHaikuImageUserGroupFile $(file) ;
752		AddFilesToHaikuImage system etc : $(file) ;
753	}
754
755	HAIKU_IMAGE_USER_GROUP_ENTRIES on $(file) = $(allEntries) ;
756}
757
758actions BuildHaikuImageUserGroupFile
759{
760	echo "$(HAIKU_IMAGE_USER_GROUP_ENTRIES)" | tr '|' '\n' > $(1)
761}
762
763rule AddUserToHaikuImage user : uid : gid : home : shell : realName
764{
765	if ! $(user) || ! $(uid) || ! $(gid) || ! $(home) {
766		Exit "Invalid haiku user specification passed to AddUserToHaikuImage." ;
767	}
768
769	local entry
770		= $(user):x:$(uid):$(gid):$(realName:E=$(user)):$(home):$(shell:E="") ;
771
772	AddEntryToHaikuImageUserGroupFile <haiku-image>passwd : $(entry) ;
773}
774
775rule AddGroupToHaikuImage group : gid : members
776{
777	if ! $(group) || ! $(gid) {
778		Exit "Invalid haiku group specification passed to"
779			"AddGroupToHaikuImage." ;
780	}
781
782	local entry = $(group):x:$(gid):$(members:J=,:E) ;
783
784	AddEntryToHaikuImageUserGroupFile <haiku-image>group : $(entry) ;
785}
786
787rule AddOptionalPackageDescriptionToHaikuImage file : searchPath
788{
789	if $(searchPath) {
790		SEARCH on $(file) = [ FDirName $(searchPath) ] ;
791	}
792
793	HAIKU_IMAGE_OPTIONAL_PACKAGE_DESCRIPTIONS += $(file) ;
794}
795
796rule AddLicenseToHaikuImage file : name : searchPath
797{
798	if $(searchPath) {
799		SEARCH on $(file) = [ FDirName $(searchPath) ] ;
800	}
801
802	if $(name) && $(file:BS) = $(name) {
803		name = ;
804	}
805
806	AddFilesToHaikuImage system data licenses : $(file) : $(name) ;
807}
808
809
810rule CreateHaikuImageMakeDirectoriesScript script
811{
812	CreateContainerMakeDirectoriesScript $(HAIKU_IMAGE_CONTAINER_NAME)
813		: $(script) ;
814}
815
816rule CreateHaikuImageCopyFilesScript script
817{
818	CreateContainerCopyFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ;
819}
820
821rule CreateHaikuImageUnzipFilesScript script
822{
823	CreateContainerUnzipFilesScript $(HAIKU_IMAGE_CONTAINER_NAME) : $(script) ;
824}
825
826rule BuildHaikuImage haikuImage : scripts : isImage : isVMwareImage
827{
828	# BuildHaikuImage <haiku image> : <scripts> : <is image> : <isVMwareImage> ;
829
830	if $(isImage) = 1 || $(isImage) = true {
831		IS_IMAGE on $(haikuImage) = 1 ;
832	} else {
833		IS_IMAGE on $(haikuImage) = "" ;
834	}
835
836	if $(isVMwareImage) = 1 || $(isVMwareImage) = true {
837		IS_VMWARE_IMAGE on $(haikuImage) = 1 ;
838	} else {
839		IS_VMWARE_IMAGE on $(haikuImage) = "" ;
840	}
841
842	local mainScript = build_haiku_image ;
843	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
844
845	Depends $(haikuImage) : $(mainScript) $(scripts) ;
846	BuildHaikuImage1 $(haikuImage) : $(mainScript) $(scripts) ;
847}
848
849actions BuildHaikuImage1
850{
851	export imagePath="$(1)"
852	export isImage="$(IS_IMAGE)"
853	export isVMwareImage="$(IS_VMWARE_IMAGE)"
854	$(2[1]) $(2[2-])
855}
856
857rule BuildVMWareImage vmwareImage : plainImage : imageSize
858{
859	# BuildVMWareImage <vmware image> : <plain image> : <image size in MB>
860
861	IMAGE_SIZE on $(vmwareImage) = $(imageSize) ;
862
863	Depends $(vmwareImage) : <build>vmdkheader $(plainImage) ;
864	BuildVMWareImage1 $(vmwareImage) : <build>vmdkheader $(plainImage) ;
865}
866
867actions BuildVMWareImage1
868{
869	$(RM) $(1)
870	$(2[1]) -h 64k -i$(IMAGE_SIZE)M $(1) &&
871	cat $(2[2]) >> $(1)
872}
873
874
875#pragma mark - Network Boot Archive rules
876
877rule AddDirectoryToNetBootArchive directoryTokens
878{
879	# AddDirectoryToNetBootArchive <directoryTokens>
880
881	return [ AddDirectoryToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
882		: $(directoryTokens) ] ;
883}
884
885rule AddFilesToNetBootArchive directory : targets : destName
886{
887	# AddFilesToNetBootArchive <directory> : <targets> [ : dest name ]
888
889	AddFilesToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(directory)
890		: $(targets) : $(destName) ;
891}
892
893rule AddSymlinkToNetBootArchive directoryTokens : linkTarget : linkName
894{
895	# AddSymlinkToNetBootArchive <directory> : <link target> [ : <link name> ] ;
896
897	AddSymlinkToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
898		: $(directoryTokens) : $(linkTarget) : $(linkName) ;
899}
900
901rule AddDriversToNetBootArchive relativeDirectoryTokens : targets
902{
903	# AddDriversToNetBootArchive <relative directory> : <targets> ;
904
905	AddDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
906		: $(relativeDirectoryTokens) : $(targets) ;
907}
908
909rule AddNewDriversToNetBootArchive relativeDirectoryTokens : targets
910{
911	# AddNewDriversToNetBootArchive <relative directory> : <targets> ;
912
913	AddNewDriversToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
914		: $(relativeDirectoryTokens) : $(targets) ;
915}
916
917rule AddDriverRegistrationToNetBootArchive relativeDirectoryTokens : target
918	: links
919{
920	# AddDriverRegistrationToNetBootArchive <directory> : <link target>
921	#	: <link names> ] ;
922
923	AddDriverRegistrationToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
924		: $(relativeDirectoryTokens) : $(target) : $(links) ;
925}
926
927rule AddBootModuleSymlinksToNetBootArchive targets
928{
929	# AddBootModuleSymlinksToNetBootArchive <targets> ;
930
931	AddBootModuleSymlinksToContainer $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
932		: $(targets) ;
933}
934
935rule CreateNetBootArchiveMakeDirectoriesScript script
936{
937	CreateContainerMakeDirectoriesScript
938		$(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME) : $(script) ;
939}
940
941rule CreateNetBootArchiveCopyFilesScript script
942{
943	CreateContainerCopyFilesScript $(HAIKU_NET_BOOT_ARCHIVE_CONTAINER_NAME)
944		: $(script) ;
945}
946
947rule BuildNetBootArchive archive : scripts
948{
949	# BuildHNetBootArchive <archive> : <scripts>  ;
950
951	local mainScript = build_tgz_archive ;
952	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
953
954	Depends $(archive) : $(mainScript) $(scripts) ;
955	BuildNetBootArchive1 $(archive) : $(mainScript) $(scripts) ;
956}
957
958actions BuildNetBootArchive1
959{
960	$(2[1]) $(1) $(2[2-])
961}
962
963
964#pragma mark - Floppy Boot Archive rules
965
966rule AddDirectoryToFloppyBootArchive directoryTokens
967{
968	# AddDirectoryToFloppyBootArchive <directoryTokens>
969
970	return [ AddDirectoryToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
971		: $(directoryTokens) ] ;
972}
973
974rule AddFilesToFloppyBootArchive directory : targets : destName
975{
976	# AddFilesToFloppyBootArchive <directory> : <targets> [ : dest name ]
977
978	AddFilesToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(directory)
979		: $(targets) : $(destName) ;
980}
981
982rule AddSymlinkToFloppyBootArchive directoryTokens : linkTarget : linkName
983{
984	# AddSymlinkToFloppyBootArchive <directory> : <link target> [ : <link name> ] ;
985
986	AddSymlinkToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
987		: $(directoryTokens) : $(linkTarget) : $(linkName) ;
988}
989
990rule AddDriversToFloppyBootArchive relativeDirectoryTokens : targets
991{
992	# AddDriversToFloppyBootArchive <relative directory> : <targets> ;
993
994	AddDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
995		: $(relativeDirectoryTokens) : $(targets) ;
996}
997
998rule AddNewDriversToFloppyBootArchive relativeDirectoryTokens : targets
999{
1000	# AddNewDriversToFloppyBootArchive <relative directory> : <targets> ;
1001
1002	AddNewDriversToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1003		: $(relativeDirectoryTokens) : $(targets) ;
1004}
1005
1006rule AddDriverRegistrationToFloppyBootArchive relativeDirectoryTokens : target
1007	: links
1008{
1009	# AddDriverRegistrationToFloppyBootArchive <directory> : <link target>
1010	#	: <link names> ] ;
1011
1012	AddDriverRegistrationToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1013		: $(relativeDirectoryTokens) : $(target) : $(links) ;
1014}
1015
1016rule AddBootModuleSymlinksToFloppyBootArchive targets
1017{
1018	# AddBootModuleSymlinksToFloppyBootArchive <targets> ;
1019
1020	AddBootModuleSymlinksToContainer $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1021		: $(targets) ;
1022}
1023
1024rule CreateFloppyBootArchiveMakeDirectoriesScript script
1025{
1026	CreateContainerMakeDirectoriesScript
1027		$(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME) : $(script) ;
1028}
1029
1030rule CreateFloppyBootArchiveCopyFilesScript script
1031{
1032	CreateContainerCopyFilesScript $(HAIKU_FLOPPY_BOOT_IMAGE_CONTAINER_NAME)
1033		: $(script) ;
1034}
1035
1036rule BuildFloppyBootArchive archive : scripts
1037{
1038	# BuildHFloppyBootArchive <archive> : <scripts>  ;
1039
1040	local mainScript = build_tgz_archive ;
1041	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
1042
1043	Depends $(archive) : $(mainScript) $(scripts) ;
1044	BuildFloppyBootArchive1 $(archive) : $(mainScript) $(scripts) ;
1045}
1046
1047actions BuildFloppyBootArchive1
1048{
1049	$(2[1]) $(1) $(2[2-])
1050}
1051
1052# warning: that is quite x86 dependant...
1053
1054rule BuildFloppyBootImage image : haikuLoader : archive
1055{
1056	Depends $(image) : $(haikuLoader) ;
1057	Depends $(image) : $(archive) ;
1058	#MakeLocateDebug $(image) ;
1059	ARCHIVE_IMAGE_OFFSET on $(image) = $(HAIKU_BOOT_ARCHIVE_IMAGE_OFFSET) ;
1060
1061	# TODO: the GCC4 archive is too large for a 1.44 floppy image
1062	if $(HAIKU_GCC_VERSION[1]) = 2 {
1063		FLOPPY_IMAGE_BLOCK_SIZE on $(image) = 1 ;
1064	} else {
1065		FLOPPY_IMAGE_BLOCK_SIZE on $(image) = 2 ;
1066	}
1067
1068	BuildFloppyBootImage1 $(image) : $(haikuLoader) $(archive) ;
1069}
1070
1071actions BuildFloppyBootImage1
1072{
1073	$(RM) $(<)
1074	# make an empty image
1075	dd if=/dev/zero of=$(<) bs=$(FLOPPY_IMAGE_BLOCK_SIZE)k count=1440
1076	# add haiku_loader
1077	dd if=$(>[1]) of=$(<) conv=notrunc
1078	# add the boot drivers tgz archive
1079	dd if=$(>[2]) of=$(<) bs=$(ARCHIVE_IMAGE_OFFSET)k seek=1 conv=notrunc
1080}
1081
1082
1083#pragma mark - CD Boot Image rules
1084
1085rule BuildCDBootImage image : bootfloppy : extrafiles
1086{
1087	Depends $(image) : $(bootfloppy) ;
1088	Depends $(image) : $(extrafiles) ;
1089	BOOTIMG on $(image) = $(bootfloppy) ;
1090
1091	BuildCDBootImage1 $(image) : $(bootfloppy) $(extrafiles) ;
1092}
1093
1094actions BuildCDBootImage1
1095{
1096	$(RM) $(<)
1097	mkisofs -b $(BOOTIMG) -r -J -V bootimg -o $(<) $(>[1]) $(>[2-])
1098}
1099
1100
1101#pragma mark - CD Boot PPC Image rules
1102
1103rule BuildCDBootPPCImage image : hfsmaps : elfloader : coffloader : chrpscript : extrafiles
1104{
1105	Depends $(image) : $(elfloader) ;
1106	Depends $(image) : $(coffloader) ;
1107	Depends $(image) : $(chrpscript) ;
1108	Depends $(image) : $(extrafiles) ;
1109	Depends $(image) : $(hfsmaps) ;
1110	MAPS on $(image) = $(hfsmaps) ;
1111
1112	BuildCDBootPPCImage1 $(image) : $(elfloader) $(coffloader) $(chrpscript) $(extrafiles) ;
1113}
1114
1115actions BuildCDBootPPCImage1 bind MAPS
1116{
1117	$(RM) $(<)
1118	mkdir -p $(HAIKU_OUTPUT_DIR)/cd/ppc
1119	cp $(>) $(HAIKU_OUTPUT_DIR)/cd/ppc/
1120	cp $(>[3]) $(HAIKU_OUTPUT_DIR)/cd/ppc/bootinfo.txt
1121	cp $(>[1]) $(HAIKU_OUTPUT_DIR)/cd/ofwboot.elf
1122	cp $(>[2]) $(HAIKU_OUTPUT_DIR)/cd/ofwboot.xcf
1123	#mkisofs -r -U -chrp-boot -V bootimg -o $(<) $(>[1]) $(>[2-])
1124	#mkisofs -hfs -r -U -chrp-boot -part -map $(MAPS) -no-desktop -hfs-volid bootimg -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) $(>[2-])
1125	#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
1126	#mkisofs -r -U -chrp-boot -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) $(>[2-])
1127	#mkisofs -r -U -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) $(>[2-])
1128	# $(HAIKU_OUTPUT_DIR)/cd
1129	# -hfs -hfs-bless .
1130	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
1131	#$(RM) -R $(HAIKU_OUTPUT_DIR)/cd
1132}
1133
1134
1135