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