xref: /haiku/build/jam/HelperRules (revision 2897df967633aab846ff4917b53e2af7d1e54eeb)
1# Rules without side effects.
2
3# Vanilla Jam compatibility
4if ! $(INVOCATION_SUBDIR_SET) {
5	rule FIsPrefix
6	{
7		# FIsPrefix <a> : <b> ;
8		# Returns true, if list <a> is a prefix (a proper one or equal) of
9		# list <b>, an empty list otherwise.
10		local a = $(1) ;
11		local b = $(2) ;
12		while $(a) && $(a[1]) = $(b[1]) {
13			a = $(a[2-]) ;
14			b = $(b[2-]) ;
15		}
16
17		if $(a) {
18			return ;
19		} else {
20			return true ;
21		}
22	}
23
24	rule LocalClean { Clean $(1) : $(2) ; }
25
26	rule LocalDepends { Depends $(1) : $(2) ; }
27
28} # vanilla Jam compatibility
29
30rule FFilter
31{
32	# FFilter <list> : <excludes> ;
33	# Removes all occurrences of <excludes> in <list>.
34
35	local list = $(1) ;
36	local excludes = $(2) ;
37	local newList ;
38	local item ;
39	for item in $(list) {
40		local skip ;
41		local exclude ;
42		for exclude in $(excludes) {
43			if $(item) = $(exclude) {
44				skip = true ;
45			}
46		}
47		if ! $(skip) {
48			newList += $(item) ;
49		}
50	}
51	return $(newList) ;
52}
53
54rule FGetGrist
55{
56	# FGetGrist <target> ;
57	#
58	# Returns the grist of a target, not including leading "<" and trailing ">".
59
60	local grist = $(1[1]:G) ;
61	if ! $(grist) {
62		return ;
63	}
64
65	return [ Match <(.*)> : $(grist) ] ;
66}
67
68rule FSplitString string : delimiterChar
69{
70	local result ;
71
72	while $(string) {
73		local split = [ Match $(delimiterChar)*([^$(delimiterChar)]+)(.*)
74			: $(string) ] ;
75		result += $(split[1]) ;
76		string = $(split[2-]) ;
77	}
78
79	return $(result) ;
80}
81
82rule FSplitPath
83{
84	# SplitPath <path> ;
85	# Decomposes a path into its components.
86	local path = $(1:G=) ;
87	local components ;
88	# $(path:D) for "/" is "/". Therefore the second condition.
89	while $(path:D) && $(path:D) != $(path)
90	{
91		# Note: $(path:B) returns "." for "..", but $(path:D=) is fine.
92		components = $(path:D=) $(components) ;
93		path = $(path:D) ;
94	}
95	components = $(path) $(components) ;
96	return $(components) ;
97}
98
99
100rule FConditionsHold conditions : predicate
101{
102	# FConditionsHold <conditions> : <predicate> ;
103	# Checks whether the conditions <conditions> are satisfied by the predicate
104	# rule <predicate> and returns a respective result (if so: "1", if not:
105	# empty list). The conditions are satisfied when <conditions> is not empty
106	# and
107	# * none of the negative conditions it contains hold and
108	# * if <conditions> contains any positive conditions, at least one of those
109	#   holds.
110	# A positive condition is an element not starting with a "!". It holds when
111	# the predicate rule <predicate> returns true for the element.
112	# A negative condition is an element that starts with a "!". It holds when
113	# the predicate rule <predicate> returns true for the string resulting from
114	# removing the leading "!".
115	#
116	# <conditions> - The list of conditions.
117	# <predicate> - The predicate rule invoked to test the elements.
118	#
119	# Examples:
120	# For a predicate that holds for the elements of the set { a b c } the
121	# following conditions hold:
122	# { a }, { a d }, { !d }, { !d !e }, { a !d }, { b !e !f }
123	# The following conditions don't hold:
124	# { }, { d }, { d e }, { !a }, { !a b }, { !d e } { a b !c !d }
125
126	local hasPositive ;
127	local hasNegative ;
128	local positiveMatch ;
129	local condition ;
130	for condition in $(conditions) {
131		switch $(condition) {
132			case !* :
133			{
134				hasNegative = 1 ;
135				condition = [ Match "!(.*)" : $(condition) ] ;
136				if [ $(predicate) $(condition) ] {
137					return ;
138				}
139			}
140			case * :
141			{
142				hasPositive = 1 ;
143				if [ $(predicate) $(condition) ] {
144					positiveMatch = 1 ;
145				}
146			}
147		}
148	}
149
150	if $(hasPositive) {
151		return $(positiveMatch) ;
152	}
153	return $(hasNegative) ;
154}
155
156
157rule SetPlatformCompatibilityFlagVariables
158{
159	# SetPlatformCompatibilityFlagVariables <platform var> : <var prefix>
160	#	: <platform kind> [ : other platforms ] ;
161
162	local platformVar = $(1) ;
163	local platform = $($(platformVar)) ;
164	local varPrefix = $(2) ;
165	local platformKind = $(3) ;
166	local otherPlatforms = $(4) ;
167
168	if ! $(platform) {
169		ECHO "Variable $(platformVar) not set. Please run ./configure or" ;
170		EXIT "specify it manually." ;
171	}
172
173	# special case: Haiku libbe.so built for testing under BeOS
174	if $(platform) = libbe_test {
175		platform = $(HOST_PLATFORM) ;
176	}
177
178	$(varPrefix)_PLATFORM_BEOS_COMPATIBLE = ;
179	$(varPrefix)_PLATFORM_BONE_COMPATIBLE = ;
180	$(varPrefix)_PLATFORM_DANO_COMPATIBLE = ;
181	$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE = ;
182
183	switch $(platform)
184	{
185		case r5 :
186		{
187			$(varPrefix)_PLATFORM_BEOS_COMPATIBLE = true ;
188		}
189
190		case bone :
191		{
192			$(varPrefix)_PLATFORM_BONE_COMPATIBLE = true ;
193		}
194
195		case dano :
196		{
197			$(varPrefix)_PLATFORM_DANO_COMPATIBLE = true ;
198		}
199
200		case haiku_host :
201		{
202			$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE = true ;
203		}
204
205		case haiku :
206		{
207			$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE = true ;
208		}
209
210		case host :
211			# not compatible to anything
212
213		case * :
214		{
215			if ! ( $(platform) in $(otherPlatforms) ) {
216				Exit Unsupported $(platformKind) platform: $(platform) ;
217			}
218		}
219	}
220
221	# set lesser flags, e.g. "DANO" for "HAIKU" and "BEOS" for "BONE"
222	$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE
223		?= $($(varPrefix)_PLATFORM_HAIKU_COMPATIBLE) ;
224	$(varPrefix)_PLATFORM_DANO_COMPATIBLE
225		?= $($(varPrefix)_PLATFORM_HAIKU_COMPATIBLE) ;
226	$(varPrefix)_PLATFORM_BONE_COMPATIBLE
227		?= $($(varPrefix)_PLATFORM_DANO_COMPATIBLE) ;
228	$(varPrefix)_PLATFORM_BEOS_COMPATIBLE
229		?= $($(varPrefix)_PLATFORM_BONE_COMPATIBLE) ;
230
231	# set the machine friendly flags
232	$(varPrefix)_PLATFORM_(haiku)_COMPATIBLE
233		?= $($(varPrefix)_PLATFORM_HAIKU_COMPATIBLE) ;
234	$(varPrefix)_PLATFORM_(haiku_host)_COMPATIBLE
235		?= $($(varPrefix)_PLATFORM_HAIKU_COMPATIBLE) ;
236	$(varPrefix)_PLATFORM_(dano)_COMPATIBLE
237		?= $($(varPrefix)_PLATFORM_DANO_COMPATIBLE) ;
238	$(varPrefix)_PLATFORM_(bone)_COMPATIBLE
239		?= $($(varPrefix)_PLATFORM_BONE_COMPATIBLE) ;
240	$(varPrefix)_PLATFORM_(r5)_COMPATIBLE
241		?= $($(varPrefix)_PLATFORM_BEOS_COMPATIBLE) ;
242
243	$(varPrefix)_PLATFORM_(libbe_test)_COMPATIBLE
244		?= $($(varPrefix)_PLATFORM_BEOS_COMPATIBLE) ;
245}
246
247rule FAnalyzeGCCVersion
248{
249	# FAnalyzeGCCVersion <rawVersionVariable> ;
250	#
251	local varName = $(1) ;
252	local rawVersion = $($(varName)) ;
253
254	if ! $(rawVersion) {
255		ECHO "Variable $(varName) not set. Please run ./configure or" ;
256		EXIT "specify it manually." ;
257	}
258
259	local version = ;
260	# split the raw version string at `.' and `-' characters
261	while $(rawVersion) {
262		local split = [ Match "([^.-]*)[.-](.*)" : $(rawVersion) ] ;
263		if $(split) {
264			version += $(split[1]) ;
265			rawVersion = $(split[2]) ;
266		} else {
267			version += $(rawVersion) ;
268			rawVersion = ;
269		}
270	}
271
272	return $(version) ;
273}
274
275rule SetIncludePropertiesVariables prefix : suffix
276{
277	# SetIncludePropertiesVariables <prefix> : <suffix> ;
278	#
279	suffix = $(suffix:E=) ;
280	if $($(prefix)_GCC_VERSION$(suffix)[1]) < 4 {
281		$(prefix)_INCLUDES_SEPARATOR$(suffix) = -I- ;
282		$(prefix)_LOCAL_INCLUDES_OPTION$(suffix) = -I ;
283		$(prefix)_SYSTEM_INCLUDES_OPTION$(suffix) = -I ;
284	} else {
285		$(prefix)_INCLUDES_SEPARATOR$(suffix) = ;
286		$(prefix)_LOCAL_INCLUDES_OPTION$(suffix) = "-iquote " ;
287		$(prefix)_SYSTEM_INCLUDES_OPTION$(suffix) = "-I " ;
288	}
289}
290
291
292#pragma mark -
293
294rule SetPlatformForTarget
295{
296	# SetPlatformForTarget <target> : <platform> ;
297
298	PLATFORM on $(1) = $(2) ;
299}
300
301rule SetSubDirPlatform
302{
303	# SetSubDirPlatform <platform> ;
304
305	PLATFORM = $(1) ;
306}
307
308rule SetSupportedPlatformsForTarget
309{
310	# SetSupportedPlatformsForTarget <target> : <platforms> ;
311
312	SUPPORTED_PLATFORMS on $(1) = $(2) ;
313}
314
315rule SetSubDirSupportedPlatforms
316{
317	# SetSubDirSupportedPlatforms <platforms> ;
318
319	SUPPORTED_PLATFORMS = $(1) ;
320}
321
322rule AddSubDirSupportedPlatforms
323{
324	# AddSubDirSupportedPlatforms <platforms> ;
325
326	SUPPORTED_PLATFORMS += $(1) ;
327}
328
329rule SetSubDirSupportedPlatformsBeOSCompatible
330{
331	# SetSubDirSupportedPlatformsBeOSCompatible ;
332
333	SUPPORTED_PLATFORMS = $(HAIKU_BEOS_COMPATIBLE_PLATFORMS) ;
334}
335
336rule IsPlatformSupportedForTarget
337{
338	# IsPlatformSupportedForTarget <target> [ : <platform> ]
339	#
340
341	on $(1) {
342		if $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
343			return true ;
344		} else {
345			return ;
346		}
347	}
348}
349
350rule InheritPlatform
351{
352	# InheritPlatform <children> : <parent> ;
353	# PLATFORM and SUPPORTED_PLATFORMS are set on <children> to their value
354	# on <parent>.
355	#
356	local children = $(1) ;
357	local parent = $(2) ;
358
359	on $(parent) {
360		PLATFORM on $(children) = $(PLATFORM) ;
361		SUPPORTED_PLATFORMS on $(children) = $(SUPPORTED_PLATFORMS) ;
362	}
363}
364
365rule SubDirAsFlags
366{
367	SUBDIRASFLAGS += $(<) ;
368}
369