1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
|
<!--
Copyright 2001 Steven Knight
-->
<para>
The "Native Python" interface is the interface
that the actual &SCons; utility will present to users.
Because it exposes the Python Build Engine API,
&SCons; users will have direct access to the complete
functionality of the Build Engine.
In contrast, a different user interface such as a GUI
may choose to only use, and present to the end-user,
a subset of the Build Engine functionality.
</para>
<section id="sect-config">
<title>Configuration files</title>
<para>
&SCons; configuration files are simply Python scripts that invoke
methods to specify target files to be built, rules for building the
target files, and dependencies. Common build rules are available by
default and need not be explicitly specified in the configuration
files.
</para>
<para>
By default, the &SCons; utility searches for a file named
&SConstruct;, &Sconstruct; or &sconstruct (in that order) in the
current directory, and reads its configuration from the first file
found. A <option>-f</option> command-line option exists to read a
different file name.
</para>
</section>
<section id="sect-syntax">
<title>Python syntax</title>
<para>
Because &SCons; configuration files are Python scripts, normal Python
syntax can be used to generate or manipulate lists of targets or
dependencies:
</para>
<programlisting>
sources = ['aaa.c', 'bbb.c', 'ccc.c']
env.Make('bar', sources)
</programlisting>
<para>
Python flow-control can be used to iterate through invocations of
build rules:
</para>
<programlisting>
objects = ['aaa.o', 'bbb.o', 'ccc.o']
for obj in objects:
src = replace(obj, '.o', '.c')
env.Make(obj, src)
</programlisting>
<para>
or to handle more complicated conditional invocations:
</para>
<programlisting>
# only build 'foo' on Linux systems
if sys.platform == 'linux1':
env.Make('foo', 'foo.c')
</programlisting>
<para>
Because &SCons; configuration files are Python scripts, syntax errors
will be caught by the Python parser. Target-building does not begin
until after all configuration files are read, so a syntax error will
not cause a build to fail half-way.
</para>
</section>
<section id="sect-subsidiary">
<title>Subsidiary configuration Files</title>
<para>
A configuration file can instruct &SCons; to read up subsidiary
configuration files. Subsidiary files are specified explicitly in a
configuration file via the &SConscript; method. As usual, multiple
file names may be specified with white space separation, or in an
array:
</para>
<programlisting>
SConscript('other_file')
SConscript('file1 file2')
SConscript(['file3', 'file4'])
SConscript(['file name with white space'])
</programlisting>
<para>
An explicit <literal>sconscript</literal> keyword may be used:
</para>
<programlisting>
SConscript(sconscript = 'other_file')
</programlisting>
<para>
Including subsidiary configuration files is recursive: a configuration
file included via &SConscript; may in turn &SConscript; other
configuration files.
</para>
</section>
<section id="sect-scoping">
<title>Variable scoping in subsidiary files</title>
<para>
When a subsidiary configuration file is read, it is given its own
namespace; it does not have automatic access to variables from the parent
configuration file.
</para>
<para>
Any variables (not just &SCons; objects) that are to be shared between configuration files must be
explicitly passed in the &SConscript; call
using the &Export method:
</para>
<programlisting>
env = Environment()
debug = Environment(CCFLAGS = '-g')
installdir = '/usr/bin'
SConscript('src/SConscript', Export(env=env, debug=debug, installdir=installdir))
</programlisting>
<REMARK>
The <literal>env=env</literal> stuff bugs me
because it imposes extra work on the normal
case where you <emphasis>don't</emphasis> rename
the variables.
Can we simplify the &Export; method
so that a string
without a keyword assignment
is split into variables that are passed
through transparently?
Equivalent to the above example:
<literal>SConscript('src/SConscript', Export('env debug installdir'))</literal>
</REMARK>
<para>
Which may be specified explicitly using a keyword argument:
</para>
<programlisting>
env = Environment()
debug = Environment(CCFLAGS = '-g')
installdir = '/usr/bin'
SConscript(sconscript = 'src/SConscript',
export = Export(env=env, debug=debug, installdir=installdir))
</programlisting>
<para>
Explicit variable-passing provides control over exactly what is available
to a subsidiary file, and avoids unintended side effects of changes in
one configuration file affecting other far-removed configuration files
(a very hard-to-debug class of build problem).
</para>
</section>
<section id="sect-hierarchy">
<title>Hierarchical builds</title>
<para>
The &SConscript; method is so named because, by convention, subsidiary
configuration files in subdirectories are named &SConscript;:
</para>
<programlisting>
SConscript('src/SConscript')
SConscript('lib/build_me')
</programlisting>
<para>
When a subsidiary configuration file is read from a subdirectory, all
of that configuration file's targets and build rules are interpreted
relative to that directory (as if &SCons; had changed its working
directory to that subdirectory). This allows for easy support of
hierarchical builds of directory trees for large projects.
</para>
</section>
<section id="sect-sharing">
<title>Sharing &consenvs;</title>
<para>
&SCons; will allow users to share &consenvs, as well as other &SCons;
objects and Python variables, by importing them from a central, shared
repository using normal Python syntax:
</para>
<programlisting>
from LocalEnvironments import optimized, debug
optimized.Make('foo', 'foo.c')
debug.Make('foo-d', 'foo.c')
</programlisting>
<para>
The expectation is that some local tool-master, integrator or
administrator will be responsible for assembling environments (creating
the &Builder; objects that specify the tools, options, etc.) and make
these available for sharing by all users.
</para>
<para>
The modules containing shared &consenvs;
(<literal>LocalEnvironments</literal> in the above example) can be
checked in and controlled with the rest of the source files. This
allows a project to track the combinations of tools and command-line
options that work on different platforms, at different times, and with
different tool versions, by using already-familiar revision control
tools.
</para>
</section>
<section id="sect-help">
<title>Help</title>
<para>
The &SCons; utility provides a &Help; function to allow the writer
of a &SConstruct; file to provide help text that is specific to
the local build tree:
</para>
<programlisting>
Help("""
Type:
scons . build and test everything
scons test build the software
scons src run the tests
scons web build the web pages
""")
</programlisting>
<para>
This help text is displayed in response to the <option>-h</option>
command-line option. Calling the &Help; function more than once is an
error.
</para>
</section>
<section id="sect-debug">
<title>Debug</title>
<para>
&SCons; supports several command-line options for printing extra
information with which to debug build problems.
</para>
<REMARK>
These need to be specified and explained
beyond what the man page will have.
</REMARK>
<!-- BEGIN HTML -->
<para>
See the -d, -p, -pa, and -pw options
in the <!--<A HREF="#sccons_Man_page">man page</A>-->, below.
All of these options make use of call-back functions to
<!--<A HREF="reference.html#Customizing_output">control the output</A>-->
printed by the Build Engine.
</para>
<!-- END HTML -->
</section>
|