xref: /haiku/build/jam/MiscRules (revision cfc3fa87da824bdf593eb8b817a83b6376e77935)
1
2rule SetupObjectsDir
3{
4	local relPath = [ FDirName $(SUBDIR_TOKENS[2-]) ] ;
5	if $(relPath) = . {
6		relPath = ;
7	}
8	COMMON_PLATFORM_LOCATE_TARGET =
9		[ FDirName $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) $(relPath) ] ;
10
11	local var ;
12	for var in COMMON_ARCH COMMON_DEBUG DEBUG_$(HAIKU_DEBUG_LEVELS) {
13		HOST_$(var)_LOCATE_TARGET
14			= [ FDirName $(HOST_$(var)_OBJECT_DIR) $(relPath) ] ;
15		TARGET_$(var)_LOCATE_TARGET
16			= [ FDirName $(TARGET_$(var)_OBJECT_DIR) $(relPath) ] ;
17	}
18
19	LOCATE_TARGET = $(COMMON_PLATFORM_LOCATE_TARGET) ;
20	LOCATE_SOURCE = $(LOCATE_TARGET) ;
21	SEARCH_SOURCE = $(SUBDIR) $(LOCATE_SOURCE)
22		$(HOST_COMMON_DEBUG_LOCATE_TARGET)		# Also add the standard output
23		$(TARGET_COMMON_DEBUG_LOCATE_TARGET)	# dirs for generated sources.
24	;
25}
26
27rule SubIncludeGPL
28{
29	# SubInclude rule that can be used to conditionally include GPL licensed
30	# add-ons
31	if $(INCLUDE_GPL_ADDONS) = 1 {
32		SubInclude $(1) ;
33	}
34}
35
36
37# pragma mark - MakeLocate variants
38
39
40rule MakeLocateCommonPlatform
41{
42	MakeLocate $(1) : $(COMMON_PLATFORM_LOCATE_TARGET) ;
43}
44
45rule MakeLocatePlatform
46{
47	local files = $(1) ;
48	local file ;
49	for file in $(files) {
50		if [ on $(file) return $(PLATFORM) ] = host {
51			MakeLocate $(file) : $(HOST_COMMON_ARCH_LOCATE_TARGET) ;
52		} else {
53			MakeLocate $(file) : $(TARGET_COMMON_ARCH_LOCATE_TARGET) ;
54		}
55	}
56}
57
58rule MakeLocateArch
59{
60	local files = $(1) ;
61	local file ;
62	for file in $(files) {
63		if [ on $(file) return $(PLATFORM) ] = host {
64			MakeLocate $(file) : $(HOST_COMMON_DEBUG_LOCATE_TARGET) ;
65		} else {
66			MakeLocate $(file) : $(TARGET_COMMON_DEBUG_LOCATE_TARGET) ;
67		}
68	}
69}
70
71rule MakeLocateDebug
72{
73	local files = $(1) ;
74	local file ;
75	for file in $(files) {
76		on $(file) {
77			if $(PLATFORM) = host {
78				MakeLocate $(file) : $(HOST_DEBUG_$(DEBUG)_LOCATE_TARGET) ;
79			} else {
80				MakeLocate $(file) : $(TARGET_DEBUG_$(DEBUG)_LOCATE_TARGET) ;
81			}
82		}
83	}
84}
85
86
87# pragma mark - Deferred SubIncludes
88
89
90# The variable used to collect the deferred SubIncludes.
91HAIKU_DEFERRED_SUB_INCLUDES = ;
92
93rule DeferredSubInclude params : jamfile : scope
94{
95	# DeferredSubInclude <subdir tokens> [ : <jamfile name>  [ : <scope> ] ] ;
96	#
97	# Takes the same directory tokens parameter as SubInclude plus an optional
98	# alternative Jamfile name. The the subdirectory referred to by
99	# <subdir tokens> will be included when ExecuteDeferredSubIncludes is
100	# invoked, i.e. at the end of the root Jamfile. The <jamfile name> parameter
101	# specifies the name of the Jamfile to include. By default it is "Jamfile".
102	# The <scope> parameter can be "global" (default) or "local", specifying
103	# whether the alternative Jamfile name shall also be used for subdirectories.
104
105	HAIKU_DEFERRED_SUB_INCLUDES += "/" $(params) ;
106	if $(jamfile) {
107		SetConfigVar JAMFILE : $(params) : $(jamfile) : $(scope) ;
108	}
109}
110
111rule ExecuteDeferredSubIncludes
112{
113	# ExecuteDeferredSubIncludes ;
114	#
115	# Performs the deferred SubIncludes scheduled by DeferredSubInclude.
116
117	local tokensList = $(HAIKU_DEFERRED_SUB_INCLUDES) ;
118	while $(tokensList) {
119		# chop off leading "/"
120		tokensList = $(tokensList[2-]) ;
121
122		# get the tokens for the next include
123		local tokens ;
124		while $(tokensList) && $(tokensList[1]) != "/" {
125			tokens += $(tokensList[1]) ;
126			tokensList = $(tokensList[2-]) ;
127		}
128
129		# perform the include
130		if $(tokens) {
131			SubInclude $(tokens) ;
132		}
133	}
134}
135
136rule HaikuSubInclude tokens
137{
138	# HaikuSubInclude <tokens> ;
139	#
140	# Current subdir relative SubInclude.
141	# <tokens> - subdir tokens specifying the subdirectory to be include
142	#            (relative to the current subdir)
143
144	if $(tokens) {
145		SubInclude HAIKU_TOP $(SUBDIR_TOKENS) $(tokens) ;
146	}
147}
148
149
150# pragma mark - Unique IDs/targets
151
152
153# private to NextID; incremented with each NextID invocation
154HAIKU_NEXT_ID = 0 ;
155
156rule NextID
157{
158	# NextID ;
159
160	local result = $(HAIKU_NEXT_ID:J=) ;
161	HAIKU_NEXT_ID = [ AddNumAbs $(HAIKU_NEXT_ID) : 1 ] ;
162	return $(result) ;
163}
164
165rule NewUniqueTarget basename
166{
167	# NewUniqueTarget [ basename ] ;
168
169	local id = [ NextID ] ;
170	return $(basename[1]:E=_target:G=unique!target)_$(id) ;
171}
172
173
174# pragma mark - RunCommandLine
175
176
177rule RunCommandLine commandLine
178{
179	# RunCommandLine <commandLine>
180	#
181	# Creates a pseudo target that, when made by jam, causes the supplied shell
182	# command line to be executed. Elements of <commandLine> with the prefix ":"
183	# are replaced by the rule. After stripping the prefix such a string specifies
184	# a build system target and the finally executed command line will contain
185	# a path to the target instead.
186	# The pseudo target will depend on all targets thus identified. Each
187	# invocation of this rule creates a different pseudo target, which is
188	# returned to the caller.
189
190	# collect the targets in the command line and replace them by $targetX*
191	# variables
192	local substitutedCommandLine ;
193	local targets ;
194
195	local targetVarName = target ;
196	local i ;
197	for i in $(commandLine)  {
198		# targets are marked by the ":" prefix
199		local target = [ Match ^:(.*) : $(i) ] ;
200		if $(target) {
201			targets += $(target) ;
202			targetVarName = $(targetVarName)X ;
203			i = "$"$(targetVarName) ;
204		}
205
206		substitutedCommandLine += $(i) ;
207	}
208
209	# define the "run" target
210	local run = [ NewUniqueTarget run ] ;
211	COMMAND_LINE on $(run) = $(substitutedCommandLine) ;
212	NotFile $(run) ;
213	Always $(run) ;
214	Depends $(run) : $(targets) ;
215	RunCommandLine1 $(run) : $(targets) ;
216
217	return $(run) ;
218}
219
220actions RunCommandLine1 {
221	target=target;
222	for t in $(2) ; do
223		target=${target}X
224		eval "${target}=${t}"
225	done
226	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
227	$(COMMAND_LINE)
228}
229
230
231#pragma mark - DefineBuildProfile
232
233
234rule DefineBuildProfile name : type : path {
235	# DefineBuildProfile <name> : <type> [ : <path> ]
236	#
237	# Makes a build profile known. Build profiles can be used to define
238	# different sets of settings for Haiku images/installations. For each
239	# profile the default actions "build", "update", and "mount" (the latter
240	# only for disks or image types) will be available (i.e. can be specified
241	# as second parameter on the jam command line). They will build an image
242	# or installation, update only given targets, respectively just mount the
243	# image or disk using the bfs_shell.
244	#
245	# <name> - The name of the build profile.
246	# <type> - The type of the build profile. Must be one of "image" (plain
247	#          disk image), "vmware-image" (VMware disk image), "disk"
248	#          (actual partition or hard disk device), "install" (installation
249	#          in a directory), or "custom" (user-defined).
250	# <path> - The path associated with the profile. Depending on the profile
251	#          type, this is the path to the disk image/VMware image, hard
252	#          disk/partition device, or the installation directory. If the
253	#          parameter is omitted, the value of the HAIKU[_VMWARE]_IMAGE_NAME,
254	#          HAIKU_IMAGE_DIR, respectively HAIKU_INSTALL_DIR or their default
255	#          values will be used instead.
256
257	if ! $(HAIKU_BUILD_PROFILE) || $(HAIKU_BUILD_PROFILE) != $(name) {
258		return ;
259	}
260
261	HAIKU_BUILD_PROFILE_DEFINED = 1 ;
262
263	# split path into directory path and name
264	local targetDir = $(path:D) ;
265	local targetName = $(path:BS) ;
266
267	# Jam's path splitting produces an empty string, if a component doesn't
268	# exist. That's a little unhandy for checks.
269	if $(targetDir) = "" {
270		targetDir = ;
271	}
272	if $(targetName) = "" {
273		targetName = ;
274	}
275
276	targetDir ?= $(HAIKU_IMAGE_DIR) ;
277	targetDir ?= $(HAIKU_DEFAULT_IMAGE_DIR) ;
278
279	# "disk" is "image" with HAIKU_DONT_CLEAR_IMAGE
280	if $(type) = "disk" {
281		type = "image" ;
282		HAIKU_DONT_CLEAR_IMAGE = 1 ;
283	}
284
285	local buildTarget ;
286	local startOffset ;
287
288	switch $(type) {
289		case "image" : {
290			targetName ?= $(HAIKU_IMAGE_NAME) ;
291			targetName ?= $(HAIKU_DEFAULT_IMAGE_NAME) ;
292			HAIKU_IMAGE_DIR = $(targetDir) ;
293			HAIKU_IMAGE_NAME = $(targetName) ;
294			buildTarget = haiku-image ;
295		}
296
297		case "vmware-image" : {
298			targetName ?= $(HAIKU_VMWARE_IMAGE_NAME) ;
299			targetName ?= $(HAIKU_DEFAULT_VMWARE_IMAGE_NAME) ;
300			HAIKU_IMAGE_DIR = $(targetDir) ;
301			HAIKU_VMWARE_IMAGE_NAME = $(targetName) ;
302			buildTarget = haiku-vmware-image ;
303			startOffset = --start-offset 65536 ;
304		}
305
306		case "install" : {
307			path ?= $(HAIKU_INSTALL_DIR) ;
308			path ?= $(HAIKU_DEFAULT_INSTALL_DIR) ;
309			HAIKU_INSTALL_DIR = $(path) ;
310			buildTarget = install-haiku ;
311		}
312
313		case "custom" : {
314			# user-defined -- don't do anything
315			return 1 ;
316		}
317
318		case * : {
319			Exit "Unsupported build profile type: " $(type) ;
320		}
321	}
322
323	switch $(HAIKU_BUILD_PROFILE_ACTION) {
324		case "build" : {
325			JAM_TARGETS = $(buildTarget) ;
326		}
327
328		case "update" : {
329			JAM_TARGETS = $(buildTarget) ;
330			SetUpdateHaikuImageOnly 1 ;
331			HAIKU_INCLUDE_IN_IMAGE on $(HAIKU_BUILD_PROFILE_PARAMETERS) = 1 ;
332		}
333
334		case "mount" : {
335			if $(type) = "install" {
336				Exit "Build action \"mount\" not supported for profile type"
337					"\"install\"." ;
338			}
339
340			local commandLine = :<build>bfs_shell $(startOffset)
341				\"$(targetName:D=$(targetDir))\" ;
342			JAM_TARGETS = [ RunCommandLine $(commandLine) ] ;
343		}
344	}
345
346	return 1 ;
347}
348