xref: /haiku/build/jam/FileRules (revision a085e81e62d7a860f809b4fb7c7bf5654c396985)
1rule SymLink
2{
3	# SymLink <target> : <source> : <makeDefaultDependencies> ;
4	# Links <target> to <source>.
5	# <source> is the exact link contents. No binding is done.
6	# <makeDefaultDependencies> If true, <target> will be made a dependency
7	# of the `all' pseudo target, i.e. it will be made by default, and removed
8	# on `jam clean'.
9
10	local target = $(1) ;
11	local source = $(2) ;
12	local makeDefaultDependencies = $(3) ;
13	if ! $(makeDefaultDependencies) {
14		makeDefaultDependencies = true ;
15	}
16	LINKCONTENTS on $(target) = $(source) ;
17	SymLink1 $(target) ;
18	if $(makeDefaultDependencies) = true {
19		LocalDepends files : $(target) ;
20		LocalClean clean : $(target) ;
21	}
22}
23
24actions SymLink1
25{
26	$(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)"
27}
28
29rule RelSymLink
30{
31	# RelSymLink <link> : <link target> : <makeDefaultDependencies> ;
32	# Creates a relative symbolic link from <link> to <link target>.
33	# <link> and <link target> can be usual targets. They may have a grist
34	# and don't need to have any dirname. Their LOCATE variables are used to
35	# find their locations.
36	# <makeDefaultDependencies> If true (which is the default), <link> will be
37	# made a dependency of the `files' pseudo target, i.e. it will be made by
38	# default, and removed on `jam clean'.
39
40	local target = $(1) ;
41	local source = $(2) ;
42	local makeDefaultDependencies = $(3) ;
43	local targetDir = [ on $(target) FDirName $(LOCATE[1]) $(target:D) ] ;
44	local sourceDir = [ on $(source) FDirName $(LOCATE[1]) $(source:D) ] ;
45	local sourcePath = $(source:G=) ;
46	sourcePath = $(sourcePath:D=$(sourceDir)) ;
47	local targetDirComponents = [ FSplitPath $(targetDir) ] ;
48	local sourceComponents = [ FSplitPath $(sourcePath) ] ;
49
50	SymLink $(target)
51		: [ FRelPath $(targetDirComponents) : $(sourceComponents) ]
52		: $(makeDefaultDependencies) ;
53	NOUPDATE $(target) ;
54	Depends $(target) : $(source) ;
55}
56
57rule AbsSymLink
58{
59	# AbsSymLink <link> : <link target> : <link dir>
60	#			: <makeDefaultDependencies> ;
61	# Creates an absolute symbolic link from <link> to <link target>.
62	# <link> and <link target> must be usual targets. If <link dir> is
63	# given, then it is set as LOCATE directory on <link>.
64	# <makeDefaultDependencies> If true (which is the default), <link> will be
65	# made a dependency of the `files' pseudo target, i.e. it will be made by
66	# default, and removed on `jam clean'.
67
68	local makeDefaultDependencies = $(4) ;
69	if ! $(makeDefaultDependencies) {
70		makeDefaultDependencies = true ;
71	}
72
73	Depends $(1) : $(2) ;
74	if $(3) {
75		MakeLocate $(1) : $(3) ;
76	}
77	SEARCH on $(2) += $(SEARCH_SOURCE) ;
78	if $(makeDefaultDependencies) = true {
79		LocalDepends files : $(1) ;
80		LocalClean clean : $(1) ;
81	}
82}
83
84actions AbsSymLink
85{
86	target="$(2)"
87	case "$target" in
88		/*) ;;
89		*) target=`pwd`/"$target";;
90	esac
91	$(RM) "$(1)" && $(LN) -s "$target" "$(1)"
92}
93
94rule HaikuInstall installAndUninstall : dir : sources : installgrist
95	: installRule : targets
96{
97	# Usage: HaikuInstall <[ install [ and uninstall ] pseudotarget ]>
98	#	: <directory> : <sources to install> : [ <installgrist> ]
99	#	: [ <install rule> ] : [ <targets> ] ;
100
101	local install = $(installAndUninstall[1]) ;
102	install ?= install ;
103	local uninstall = $(installAndUninstall[2]) ;
104	uninstall ?= un$(install) ;
105	installgrist ?= $(INSTALLGRIST) ;
106	installRule ?= Install ;
107
108	targets ?= $(sources) ;
109	targets = $(targets:G=$(installgrist)) ;
110
111	NotFile $(install) ;
112	NotFile $(uninstall) ;
113	Depends $(install) : $(targets) ;
114	Clean $(uninstall) : $(targets) ;
115
116	SEARCH on $(sources) += $(SEARCH_SOURCE) ;
117	MakeLocate $(targets) : $(dir) ;
118
119	local source ;
120	for source in $(sources) {
121		local target = $(targets[1]) ;
122		targets = $(targets[2-]) ;
123
124		Depends $(target) : $(source) ;
125		$(installRule) $(target) : $(source) ;
126
127		if [ on $(target) return $(MODE) ] {
128			Chmod $(target) ;
129		}
130
131		if $(OWNER) && $(CHOWN) {
132			Chown $(target) ;
133			OWNER on $(target) = $(OWNER) ;
134		}
135
136		if $(GROUP) && $(CHGRP) {
137			Chgrp $(target) ;
138			GROUP on $(target) = $(GROUP) ;
139		}
140	}
141}
142
143rule InstallAbsSymLinkAdapter
144{
145	# InstallAbsSymLinkAdapter <link> : <link target>
146	if ! [ on $(2) return $(TARGET) ] {
147		TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
148	}
149	AbsSymLink $(1) : $(2) : : false ;
150}
151
152rule HaikuInstallAbsSymLink
153{
154	# Usage: HaikuInstallAbsSymLink <[ install [ and uninstall ] pseudotarget ]>
155	#							   : <directory> : <sources to install>
156	#							   : [ <installgrist> ] ;
157	HaikuInstall $(1) : $(2) : $(3) : $(4) : InstallAbsSymLinkAdapter ;
158}
159
160rule InstallRelSymLinkAdapter
161{
162	# InstallRelSymLinkAdapter <link> : <link target>
163	if ! [ on $(2) return $(TARGET) ] {
164		TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
165	}
166	RelSymLink $(1) : $(2) : false ;
167}
168
169rule HaikuInstallRelSymLink
170{
171	# Usage: HaikuInstallRelSymLink <[ install [ and uninstall ] pseudotarget ]>
172	#							   : <directory> : <sources to install>
173	#							   : [ <installgrist> ] ;
174	HaikuInstall $(1) : $(2) : $(3) : $(4) : InstallRelSymLinkAdapter ;
175}
176
177
178rule UnarchiveObjects
179{
180	# UnarchiveObjects <target objects> : <static object>
181
182	MakeLocateArch $(1) ;
183	Depends $(1) : $(2) ;
184	SEARCH on $(2) = $(SEARCH_SOURCE) ;
185}
186
187actions UnarchiveObjects
188{
189	( cd $(1[1]:D) && $(TARGET_AR) $(TARGET_UNARFLAGS) "$(2)" $(1:BS) )
190}
191
192
193rule ExtractArchive directory : entries : archiveFile : grist
194{
195	# ExtractArchive <directory> : <entries> : <archiveFile> [ : <grist> ]
196	#
197	# Extract the archive file target <archiveFile> to directory <directory>.
198	# The rule can be called multiple times for different <entries> for the same
199	# <directory> and <archiveFile> combo.
200	#
201	# <directory> - The directory into which to extract the archive file. The
202	#               directory is created by this rule and it is the target
203	#               that the extract action is associated with.
204	# <entries>   - The entries of the archive file one is interested in. The
205	#               rule always extracts the complete archive file, from the
206	#               given entries the rule creates targets (using <grist>)
207	#               representing the extracted entries. Those targets are
208	#               returned by the rule.
209	# <archiveFile> - The archive file target to extract.
210	# <grist>     - The grist used to create targets from <entries>. Defaults to
211	#               "extracted".
212
213	grist ?= extracted ;
214
215	# Turn the entries into targets to build.
216	local targets ;
217	local entry ;
218	for entry in $(entries) {
219		local target = $(entry:G=$(grist)) ;
220		targets += $(target) ;
221	}
222
223	LOCATE on $(targets) = $(directory:G=) ;
224	Depends $(targets) : $(directory) $(archiveFile) ;
225	NoUpdate $(targets) ;
226
227	# one-time initialization for the main target (the directory)
228	if ! [ on $(directory) return $(INITIALIZED) ] {
229		# make sure the parent dir exists
230		local parentDir = $(directory:PG=dir) ;
231		Depends $(directory) : $(parentDir) ;
232		MkDir $(parentDir) ;
233
234		NoUpdate $(directory) ;
235		Depends $(directory) : $(archiveFile) ;
236		switch $(archiveFile:S)
237		{
238			case .zip :
239				ExtractZipArchive1 $(directory) : $(archiveFile) ;
240
241			case .tgz :
242				ExtractTarArchive1 $(directory) : $(archiveFile) ;
243
244			case .hpkg :
245				Depends $(directory) : <build>package ;
246				ExtractHPKGArchive1 $(directory)
247					: <build>package $(archiveFile) ;
248
249			case "" :
250				Exit "ExtractArchive: No archive passed" ;
251
252			case * :
253				Exit "ExtractArchive: Unhandled archive extension:"
254					"$(archiveFile:S)" ;
255		}
256		INITIALIZED on $(directory) = 1 ;
257	}
258
259	return $(targets) ;
260}
261
262
263actions ExtractZipArchive1
264{
265	mkdir -p $(1)
266	unzip -q -u -o -d $(1) $(2)
267}
268
269
270actions ExtractTarArchive1
271{
272	mkdir -p $(1)
273	tar -C $(1) -xf $(2)
274}
275
276
277actions ExtractHPKGArchive1
278{
279	mkdir -p "$(1)"
280	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
281	$(2[1]) extract -C "$(1)" "$(2[2])"
282}
283
284
285rule ObjectReference
286{
287	# ObjectReference <reference object> : <source object>
288	# Makes <reference object> refer to the same file as <source object>.
289	# The filenames must of course be identical.
290	# <source object> must have already been LOCATEd.
291
292	local ref = $(1) ;
293	local source = $(2) ;
294	if $(ref) != $(source) {
295		Depends $(ref) : $(source) ;
296		LOCATE on $(ref) = [ on $(source) return $(LOCATE) ] ;
297	}
298}
299
300rule ObjectReferences
301{
302	# ObjectReferences <source objects>
303	# Creates local references to <source objects>, i.e. identifiers with the
304	# current grist referring to the same files. <source objects> must have
305	# already been LOCATEd.
306
307	local source ;
308	for source in $(1) {
309		ObjectReference [ FGristFiles $(source) ] : $(source) ;
310	}
311}
312
313rule CopySetHaikuRevision target : source
314{
315	# CopySetHaikuRevision <target> : <source>
316	#
317	# Copy <source> to <target>, writing the SVN revision of the working root
318	# directory into the haiku revision section of <target>.
319	#
320	# <target> - Output file target. Gristed and located target.
321	# <source> - ELF object to be copied. Gristed and located target.
322
323	# If existent, make the target depend on the .svn/entries file in the
324	# root directory, so it gets updated when the revision changes due to
325	# "svn up".
326	if [ Glob [ FDirName $(HAIKU_TOP) .svn ] : entries ] {
327		local svnEntries = <haiku-rootdir-svn>entries ;
328		SEARCH on $(svnEntries) = [ FDirName $(HAIKU_TOP) .svn ] ;
329		Depends $(target) : $(svnEntries) ;
330	} else if [ Glob [ FDirName $(HAIKU_TOP) .git ] : index ] {
331		local gitIndex = <haiku-rootdir-git>index ;
332		SEARCH on $(gitIndex) = [ FDirName $(HAIKU_TOP) .git ] ;
333		Depends $(target) : $(gitIndex) ;
334	} else if [ Glob [ FDirName $(HAIKU_TOP) .hg ] : store ] {
335		local hgStore = <haiku-rootdir-hg>store ;
336		SEARCH on $(hgStore) = [ FDirName $(HAIKU_TOP) .hg ] ;
337		Depends $(target) : $(hgStore) ;
338	}
339
340	PropagateContainerUpdateTargetFlags $(target) : $(source) ;
341
342	Depends $(target) : <build>copyattr <build>set_haiku_revision $(source) ;
343	CopySetHaikuRevision1 $(target)
344		: <build>copyattr <build>set_haiku_revision $(source) ;
345}
346
347actions CopySetHaikuRevision1
348{
349	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
350
351	. $(HAIKU_TOP)/build/scripts/determine_haiku_revision
352	determineHaikuRevision $(HAIKU_TOP) $(HAIKU_BUILD_OUTPUT_DIR)
353
354	$(2[1]) --data $(2[3]) $(1) &&
355	$(2[2]) $(1) ${revision}
356}
357
358rule DataFileToSourceFile sourceFile : dataFile : dataVariable : sizeVariable
359{
360	sourceFile = [ FGristFiles $(sourceFile) ] ;
361	MakeLocateCommonPlatform $(sourceFile) ;
362
363	sizeVariable ?= $(dataVariable)Size ;
364
365	DATA_VARIABLE on $(sourceFile) = $(dataVariable) ;
366	SIZE_VARIABLE on $(sourceFile) = $(sizeVariable) ;
367
368	Depends $(sourceFile) : <build>data_to_source $(dataFile) ;
369	DataFileToSourceFile1 $(sourceFile) : <build>data_to_source $(dataFile) ;
370	LocalClean clean : $(sourceFile) ;
371}
372
373actions DataFileToSourceFile1
374{
375	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
376	$(2[1]) $(DATA_VARIABLE) $(SIZE_VARIABLE) $(2[2]) $(1)
377}
378
379rule DownloadLocatedFile target : url
380{
381	URL on $(target) = $(url) ;
382
383	DownloadLocatedFile1 $(target) ;
384}
385
386actions DownloadLocatedFile1
387{
388	wget -O "$(1)" $(URL)
389}
390
391rule DownloadFile file : url
392{
393	file = $(file:G=download) ;
394
395	# Request the download only once.
396	if [ on $(file) return $(HAIKU_FILE_DOWNLOAD) ] {
397		return $(file) ;
398	}
399
400	HAIKU_FILE_DOWNLOAD on $(file) = 1 ;
401
402	MakeLocate $(file) : $(HAIKU_DOWNLOAD_DIR) ;
403	DownloadLocatedFile $(file) : $(url) ;
404
405	return $(file) ;
406}
407
408