xref: /haiku/build/jam/ImageRules (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
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 -f $(1)
41	echo -n > $(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)+=\\\" $(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
98rule AddDirectoryToHaikuImage directoryTokens
99{
100	# AddDirectoryToHaikuImage <directoryTokens>
101
102	local directory = [ FDirName $(directoryTokens) ] ;
103	directory = $(directory:G=HaikuImage) ;
104
105	if ! [ on $(directory) return $(__is_on_image) ] {
106		INSTALL_DIRECTORIES on haiku-image-contents += $(directory) ;
107		__is_on_image on $(directory) = true ;
108		NotFile $(directory) ;
109
110		# mark the parent dir as not to be created
111		local parent = [ FReverse $(directoryTokens) ] ;
112		parent = [ FReverse $(parent[2-]) ] ;
113		if $(parent) {
114			parent = [ FDirName $(parent) ] ;
115			parent = $(parent:G=HaikuImage) ;
116			DONT_CREATE on $(parent) = true ;
117		}
118	}
119
120	return $(directory) ;
121}
122
123rule FilterImageUpdateTargets targets
124{
125	# FilterImageUpdateTargets targets
126
127	local filteredTargets ;
128	local target ;
129	for target in $(targets) {
130		if [ on $(target) return $(HAIKU_INCLUDE_IN_IMAGE) ] {
131			filteredTargets += $(target) ;
132		}
133	}
134	return $(filteredTargets) ;
135}
136
137rule AddFilesToHaikuImage
138{
139	# AddFilesToHaikuImage <directory> : <targets> [ : dest name ]
140	#
141	local directory = [ AddDirectoryToHaikuImage $(1) ] ;
142	local targets = $(2) ;
143	local destName = $(3) ;
144
145	# If the image shall only be updated, we filter out all targets not marked
146	# accordingly.
147	if $(HAIKU_IMAGE_UPDATE_ONLY) {
148		targets = [ FilterImageUpdateTargets $(targets) ] ;
149	}
150
151	# We create a unique dummy target per target to install.
152	local target ;
153	for target in $(targets) {
154		local name ;
155		if $(destName) {
156			name = $(destName) ;
157		} else {
158			name = $(target:G=:D=) ;
159		}
160
161		local destTarget = $(name:G=HaikuImage__$(directory:G=)) ;
162		TARGET on $(destTarget) = $(target) ;
163		INSTALL_DIR on $(destTarget) = $(directory) ;
164		INSTALL_TARGETS on $(target) += $(destTarget) ;
165		TARGETS_TO_INSTALL on $(directory) += $(destTarget) ;
166	}
167}
168
169rule AddSymlinkToHaikuImage directoryTokens : linkTarget : linkName
170{
171	# AddSymlinkToHaikuImage <directory> : <link target> [ : <link name> ] ;
172	#
173
174	# If the image shall only be updated, we don't add any symlinks.
175	if $(HAIKU_IMAGE_UPDATE_ONLY) {
176		return ;
177	}
178
179	local directory = [ AddDirectoryToHaikuImage $(directoryTokens) ] ;
180
181	if ! $(linkName) {
182		local path = [ FReverse [ FSplitPath $(linkTarget) ] ] ;
183		linkName = $(path[1]) ;
184	}
185
186	local link = $(directory)/$(linkName) ;
187	SYMLINK_TARGET on $(link) = $(linkTarget) ;
188	SYMLINKS_TO_INSTALL on $(directory) += $(link) ;
189}
190
191rule AddSourceDirectoryToHaikuImage dirTokens : alwaysUpdate
192{
193	# AddSourceDirectoryToHaikuImage <dirTokens> : <alwaysUpdate> ;
194
195	# If the image shall only be updated, we update sources only, if explicitely
196	# requested.
197	if ! $(HAIKU_IMAGE_UPDATE_ONLY) || $(alwaysUpdate) {
198		HAIKU_INSTALL_SOURCE_DIRS += [ FDirName $(HAIKU_TOP) $(dirTokens) ] ;
199	}
200}
201
202rule AddDriversToHaikuImage
203{
204	# AddDriversToHaikuImage <relative directory> : <targets> ;
205	#
206	local relativeDirectoryTokens = $(1) ;
207	local targets = $(2) ;
208	local directoryTokens = beos system add-ons kernel drivers dev
209		$(relativeDirectoryTokens) ;
210
211	AddFilesToHaikuImage beos system add-ons kernel drivers bin : $(targets) ;
212
213	# If the image shall only be updated, we don't add any symlinks.
214	if $(HAIKU_IMAGE_UPDATE_ONLY) {
215		return ;
216	}
217
218	# get the relative symlink path prefix
219	local linkPrefix = ;
220	for i in $(relativeDirectoryTokens) {
221		linkPrefix += .. ;
222	}
223	linkPrefix += .. bin ;
224
225	# add the symlinks
226	local name ;
227	for name in $(targets:BS) {
228		AddSymlinkToHaikuImage $(directoryTokens)
229			: [ FDirName $(linkPrefix) $(name) ] : $(name) ;
230	}
231}
232
233rule AddDriverRegistrationToHaikuImage
234{
235	# AddDriverRegistrationToHaikuImage <directory> : <link target> : <link names> ] ;
236	#
237	local relativeDirectoryTokens = $(1) ;
238	local target = $(2) ;
239	local links = $(3) ;
240	local directoryTokens = beos system add-ons kernel registration
241		$(relativeDirectoryTokens) ;
242
243	# get the relative symlink path prefix
244	local linkPrefix = ;
245	for i in $(relativeDirectoryTokens) {
246		linkPrefix += .. ;
247	}
248	linkPrefix += .. drivers bin ;
249
250	# add the symlink
251	AddSymlinkToHaikuImage $(directoryTokens)
252		: [ FDirName $(linkPrefix) $(target:BS) ] : $(links) ;
253}
254
255rule AddBootModuleSymlinks targets
256{
257	# AddBootModuleSymlinks <targets> ;
258	#
259
260	# If the image shall only be updated, we don't add any symlinks.
261	if $(HAIKU_IMAGE_UPDATE_ONLY) {
262		return ;
263	}
264
265	# add the symlinks
266	local target ;
267	for target in $(targets) {
268		# Symlink to the first place where the target has been installed.
269		local destTarget = [ on $(target) return $(INSTALL_TARGETS[1]) ] ;
270		local installDir = [ on $(destTarget) return $(INSTALL_DIR) ] ;
271
272		if ! $(installDir) {
273			Echo "ERROR: AddBootModuleSymlinks: Can't create a symlink to"
274				"target" \"$(target)"\"." ;
275			Exit "ERROR: Add*ToHaikuImage has not been invoked for it yet." ;
276		}
277
278		local name = $(target:BS) ;
279		local linkTarget = [ FDirName /boot $(installDir:G=) $(name) ] ;
280
281		AddSymlinkToHaikuImage beos system add-ons kernel boot
282			: $(linkTarget) : $(name) ;
283	}
284}
285
286rule CreateHaikuImageMakeDirectoriesScript
287{
288	local script = $(1) ;
289	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
290	Always $(script) ;
291
292	local initScript = [ InitScript $(script) ] ;
293
294	local scriptBody
295		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
296	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
297	Depends $(scriptBody) : $(initScript) ;
298	Depends $(script) : $(scriptBody) ;
299
300	local dirsToCreate ;
301	local dir ;
302	for dir in [ on haiku-image-contents return $(INSTALL_DIRECTORIES) ] {
303		if ! [ on $(dir) return $(DONT_CREATE) ] {
304			dirsToCreate += $(dir) ;
305		}
306	}
307
308	Depends $(scriptBody) : $(dirsToCreate) ;
309	# If the image shall only be updated, we don't create directories.
310	if $(dirsToCreate) && ! $(HAIKU_IMAGE_UPDATE_ONLY) {
311		CreateHaikuImageMakeDirectoriesScript1 $(scriptBody) : $(dirsToCreate) ;
312	}
313}
314
315actions piecemeal CreateHaikuImageMakeDirectoriesScript1
316{
317	echo \$mkdir -p "\"\${tPrefix}$(2:G=)\"" >> $(1)
318}
319
320rule CreateHaikuImageCopyFilesScript
321{
322	local script = $(1) ;
323	MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ;
324	Always $(script) ;
325
326	local initScript = [ InitScript $(script) ] ;
327
328	local scriptBody
329		= [ FSameTargetWithPrependedGrist $(script) : script-body ] ;
330	LOCATE on $(scriptBody) = [ on $(script) return $(LOCATE) ] ;
331	Depends $(scriptBody) : $(initScript) ;
332	Depends $(script) : $(scriptBody) ;
333
334	local dir ;
335	for dir in [ on haiku-image-contents return $(INSTALL_DIRECTORIES) ] {
336		# filter the targets that shall be renamed; they have to be copied
337		# individually
338		local destTargets = [ on $(dir) return $(TARGETS_TO_INSTALL) ] ;
339		local remainingTargets ;
340		local destTarget ;
341		for destTarget in $(destTargets) {
342			local target = [ on $(destTarget) return $(TARGET) ] ;
343			local name = $(destTarget:BS) ;
344			if $(name) != $(target:BS) {
345				# use a unique dummy target for this file, on which we
346				# can define the TARGET_DIR variable
347				local dummyTarget = $(script)-dummy-$(dir:G=)-$(target) ;
348				NotFile $(dummyTarget) ;
349				TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
350				INSTALL_TARGET_NAME on $(dummyTarget) = $(name) ;
351
352				Depends $(dummyTarget) : $(initScript) $(target) ;
353				Depends $(script) : $(dummyTarget) ;
354
355				AppendToHaikuImageCopyFilesScriptSingleFile $(dummyTarget)
356					: $(initScript) $(target) ;
357			} else {
358				remainingTargets += $(target) ;
359			}
360		}
361		targets = $(remainingTargets) ;
362
363		if $(targets) {
364			# use a unique dummy target for this directory, on which we
365			# can define the TARGET_DIR variable
366			local dummyTarget = $(script)-dummy-$(dir:G=) ;
367			NotFile $(dummyTarget) ;
368			TARGET_DIR on $(dummyTarget) = $(dir:G=) ;
369
370			Depends $(dummyTarget) : $(initScript) $(targets) ;
371			Depends $(script) : $(dummyTarget) ;
372
373			OUTPUT_SCRIPT on $(dummyTarget) = $(initScript) ;
374			AppendToHaikuImageCopyFilesScript $(dummyTarget) : $(targets) ;
375		}
376
377		local symlinks = [ on $(dir) return $(SYMLINKS_TO_INSTALL) ] ;
378		local symlink ;
379		for symlink in $(symlinks) {
380			NotFile $(symlink) ;
381
382			Depends $(script) : $(symlink) ;
383			Depends $(symlink) : $(initScript) ;
384
385			AddSymlinkToHaikuImageCopyFilesScript $(symlink) : $(initScript) ;
386		}
387	}
388}
389
390actions piecemeal AppendToHaikuImageCopyFilesScript bind OUTPUT_SCRIPT
391{
392	echo \$cp "\"\${sPrefix}$(2)\"" "\"\${tPrefix}$(TARGET_DIR)\"" >> $(OUTPUT_SCRIPT)
393}
394
395actions AppendToHaikuImageCopyFilesScriptSingleFile
396{
397	echo \$cp "\"\${sPrefix}$(2[2])\"" \
398		"\"\${tPrefix}$(TARGET_DIR)/$(INSTALL_TARGET_NAME)\"" >> $(2[1])
399}
400
401actions AddSymlinkToHaikuImageCopyFilesScript
402{
403	echo \$ln -sfn "\"$(SYMLINK_TARGET)\"" "\"\${tPrefix}$(1:G=)\"" >> $(2[1])
404}
405
406rule BuildHaikuImage
407{
408	# BuildHaikuImage <haiku image> : <scripts> : <is image> ;
409	#
410	local haikuImage = $(1) ;
411	local scripts = $(2) ;
412	local isImage = $(3) ;
413
414	if $(isImage) = 1 || $(isImage) = true {
415		IS_IMAGE on $(haikuImage) = 1 ;
416	} else {
417		IS_IMAGE on $(haikuImage) = "" ;
418	}
419
420	local mainScript = build_haiku_image ;
421	SEARCH on $(mainScript) = [ FDirName $(HAIKU_TOP) build scripts ] ;
422
423	Depends $(haikuImage) : $(mainScript) $(scripts) ;
424	BuildHaikuImage1 $(haikuImage) : $(mainScript) $(scripts) ;
425}
426
427actions BuildHaikuImage1
428{
429	export isImage="$(IS_IMAGE)"
430	$(2[1]) $(2[2-])
431}
432
433rule BuildVMWareImage vmwareImage : plainImage : imageSize
434{
435	# BuildVMWareImage <vmware image> : <plain image> : <image size in MB>
436
437	IMAGE_SIZE on $(vmwareImage) = $(imageSize) ;
438
439	Depends $(vmwareImage) : <build>vmdkheader $(plainImage) ;
440	BuildVMWareImage1 $(vmwareImage) : <build>vmdkheader $(plainImage) ;
441}
442
443actions BuildVMWareImage1
444{
445	rm -f $(1)
446	$(2[1]) -h 64k -i$(IMAGE_SIZE)M $(1) &&
447	cat $(2[2]) >> $(1)
448}
449