aboutsummaryrefslogtreecommitdiff
path: root/build2/b.cli
blob: a6e1abc25159703fdda71c406713c6532e319974 (plain)
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
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
// file      : build2/b.cli
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license   : MIT; see accompanying LICENSE file

include <build2/types.hxx>;

"\section=1"
"\name=b"
"\summary=build system driver"

namespace build2
{
  {
    "<options> <variables> <buildspec>",

    "\h|SYNOPSIS|

     \cb{b --help}\n
     \cb{b --version}\n
     \c{\b{b} [<options>] [<variables>] [<buildspec>]}

     \h|DESCRIPTION|

     The \cb{build2} driver performs a set of meta-operations on operations on
     targets according to the build specification, or <buildspec> for short.
     This process can be controlled by specifying driver <options> and build
     system <variables>.

     Note that <options>, <variables>, and <buildspec> fragments can be
     specified in any order. To avoid treating an argument that starts with
     \cb{'-'} as an option, add the \cb{'--'} separator. To avoid treating an
     argument that contains \cb{'='} as a variable, add the second \cb{'--'}
     separator."
  }

  // For usage it's nice to see the list of options on the first page. So
  // let's not put this "extended" description into usage.
  //
  {
    "<meta-operation> <operation> <target> <parameters> <src-base>",
    "",

    "The buildspec has the following form:

     \c{<meta-operation>(<operation>...(<target>...[,<parameters>]))...}

     All components in the buildspec can be omitted. If <meta-operation> is
     omitted, then it defaults to \cb{perform}. If <operation> is omitted,
     then it defaults to the default operation for this meta-operation. For
     \cb{perform} it is \cb{update}. Finally, if <target> is omitted, then it
     defaults to the current working directory. Some operations and
     meta-operations may take additional <parameters>. For example:

     \
     b                       # perform(update(./))
     b foo/                  # perform(update(foo/))
     b foo/ bar/             # perform(update(foo/ bar/))
     b update                # perform(update(./))
     b 'clean(../)'          # perform(clean(../))
     b perform               # perform(update(./))
     b configure             # configure(?(./))
     b 'configure(../)'      # configure(?(../))
     b clean update          # perform(clean(./) update(./))
     b configure update      # configure(?(./)) perform(update(./))
     b 'create(conf/, cxx)'  # create(?(conf/), cxx)
     \

     Notice the question mark used to show the (imaginary) default operation
     for the \cb{configure} meta-operation. For \cb{configure} the default
     operation is \"all operations\". That is, it will configure all the
     operations for the specified target.

     You can also \"generate\" multiple operations for the same set of targets.
     Compare:

     \
     b 'clean(foo/ bar/)' 'update(foo/ bar/)'
     b '{clean update}(foo/ bar/)'
     \

     Some more useful buildspec examples:

     \
     b '{clean update}(...)'        # rebuild
     b '{clean update clean}(...)'  # make sure builds
     b '{clean test clean}(...)'    # make sure passes tests
     b '{clean disfigure}(...)'     # similar to distclean
     \

     In POSIX shells parenthesis are special characters and must be quoted
     when used in a buildspec. Besides being an inconvenience in itself,
     quoting also inhibits path auto-completion. To help with this situation a
     shortcut syntax is available for executing a single operation or
     meta-operation, for example:

     \
     b clean: foo/ bar/                # clean(foo/ bar/)
     b configure: src/@out/            # configure(src/@out/)
     b create: conf/, cxx              # create(conf/, cxx)
     b configure: config.cxx=g++ src/  # configure(src/) config.cxx=g++
     \

     To activate the shortcut syntax the first buildspec argument must start
     with an operation or meta-operation name and end with a colon (\cb{:}).
     To transform the shortcut syntax to the normal buildspec syntax the colon
     is replaced with the opening parenthesis (\cb{(}), the rest of the
     buildspec arguments are treated as is, and the final closing parenthesis
     (\cb{)}) is added.

     For each <target> the driver expects to find \cb{buildfile} either in the
     target's directory or, if the directory is part of the \cb{out} tree
     (\cb{out_base}), in the corresponding \cb{src} directory (\cb{src_base}).

     For example, assuming \cb{foo/} is the source directory of a project:

     \
     b foo/              # out_base=src_base=foo/
     b foo-out/          # out_base=foo-out/ src_base=foo/
     b foo-out/exe{foo}  # out_base=foo-out/ src_base=foo/
     \

     An exception to this requirement is a directory target in which case,
     provided the directory has subdirectories, an \i{implied} \cb{buildfile}
     with the following content is assumed:

     \
     # Implied directory buildfile: build all subdirectories.
     #
     ./: */
     \

     In the above example, we assumed that the \cb{build2} driver was able to
     determine the association between \cb{out_base} and \cb{src_base}. In
     case \cb{src_base} and \cb{out_base} are not the same directory, this is
     achieved in one of two ways: the \cb{config} module (which implements the
     \cb{configure}, \cb{disfigure}, and \cb{create} meta-operations) saves
     this association as part of the configuration process. If, however, the
     association hasn't been saved, then we have to specify \cb{src_base}
     explicitly using the following extended <target> syntax:

     \c{<src-base>/@<target>}

     Continuing with the previous example:

     \
     b foo/@foo-out/exe{foo}  # out_base=foo-out/ src_base=foo/
     \

     Normally, you would need to specify \cb{src_base} explicitly only once,
     during configuration. For example, a typical usage would be:

     \
     b 'configure(foo/@foo-out/)'  # src_base is saved
     b foo-out/                    # no need to specify src_base
     b 'clean(foo-out/exe{foo})'   # no need to specify src_base
     \

     The ability to specify \cb{build2} variables as part of the command line
     is normally used to pass configuration values, for example:

     \
     b config.cxx=clang++ config.cxx.coptions=-O3
     \

     Similar to buildspec, POSIX shells often inhibit path auto-completion on
     the right hand side of a variable assignment. To help with this situation
     the assignment can be broken down into three separate command line
     arguments, for example:

     \
     b config.import.libhello = ../libhello/
     \

     The build system has the following built-in and pre-defined
     meta-operations:

     \dl|

     \li|\cb{perform}

         Perform an operation.|

     \li|\cb{configure}

         Configure all operations supported by a project and save the result
         in the project's \cb{build/config.build} file. Implemented by the
         \cb{config} module. For example:

         \
         b config.cxx=clang++ config.cxx.coptions=-O3 \
           config.install.root=/usr/local config.install.root.sudo=sudo \
           configure
         \

         |

     \li|\cb{disfigure}

         Disfigure all operations supported by a project and remove the
         project's \cb{build/config.build} file. Implemented by the
         \cb{config} module.|

     \li|\cb{create}

         Create and configure a \i{configuration} project. Implemented by the
         \cb{config} module.

         Normally a \cb{build2} project is created manually by writing the
         \cb{bootstrap.build} and \cb{config.build} files, adding source
         files, and so on. However, a special kind of project, which we call
         \i{configuration}, is often useful. Such a project doesn't have any
         source files of its own. Instead, it serves as an amalgamation for
         building other projects as part of it. Doing it this way has two
         major benefits: sub-projects automatically resolve their imports
         to other projects in the amalgamation and sub-projects inherits their
         configuration from the amalgamation (which means if we want to change
         something, we only need to do it in one place).

         As an example, let's assume we have two C++ projects: the
         \cb{libhello} library in \cb{libhello/} and the \cb{hello} executable
         that imports it in \cb{hello/}. And we want to build \cb{hello} with
         \cb{clang++}.

         One way to do it would be to configure and build each project in its
         own directory, for example:

         \
         b 'configure(libhello/@libhello-clang/)' config.cxx=clang++
         b 'configure(hello/@hello-clang/)' config.cxx=clang++ \
           config.import.libhello=libhello-clang/
         \

         The two drawbacks, as mentioned above, are the need to explicitly
         resolve the import and having to make changes in multiple places
         should, for example, we want to switch from \cb{clang++} to \cb{g++}.

         We can, however, achieve the same end result but without any of the
         drawbacks using the configuration project:

         \
         b 'create(clang/, cxx)' config.cxx=clang++ # Creates clang/.
         b 'configure(libhello/@clang/libhello/)'
         b 'configure(hello/@clang/hello/)'
         \

         The targets passed to the \cb{create} meta-operation must be
         directories which should either not exist or be empty. For each
         such directory \cb{create} first initializes a project as described
         below and then configures it by executing the \cb{configure}
         meta-operation.

         The first optional parameter to \cb{create} is the list of modules to
         load in \cb{root.build}. By default, \cb{create} appends \cb{.config}
         to the names of these modules so that only their configurations are
         loaded. You can override this behavior by specifying the period
         (\cb{.})  after the module name. You can also instruct \cb{create} to
         use the optional module load by prefixing the module name with the
         question mark (\cb{?}).

         The second optional parameter is the list of modules to load in
         \cb{bootstrap.build}. If not specified, then the \cb{test} and
         \cb{install} modules are loaded by default. The \cb{config} module
         is always loaded first.

         Besides creating project's \cb{bootstrap.build} and \cb{root.build},
         \cb{create} also writes the root \cb{buildfile} with the following
         contents:

         \
         ./: {*/ -build/}
         \

         If used, this \cb{buildfile} will build all the sub-projects
         currently present in the configuration.|

     \li|\cb{dist}

         Prepare a distribution containing all files necessary to perform all
         operations in a project. Implemented by the \cb{dist} module.||

     The build system has the following built-in and pre-defined operations:

     \dl|

     \li|\cb{update}

         Update a target.|

     \li|\cb{clean}

         Clean a target.|

     \li|\cb{test}

         Test a target. Performs \cb{update} as a pre-operation. Implemented by
         the \cb{test} module.|

     \li|\cb{install}

         Install a target. Performs \cb{update} as a pre-operation. Implemented
         by the \cb{install} module.||

     Note that buildspec and command line variable values are treated as
     \cb{buildfile} fragments and so can use quoting and escaping as well as
     contain variable expansions and evaluation contexts. However, to be more
     usable on various platforms, escaping in these two situations is limited
     to the \i{effective sequences} of \cb{\\'}, \cb{\\\"}, \cb{\\\\},
     \cb{\\$}, and \cb{\\(} with all other sequences interpreted as is.
     Together with double-quoting this is sufficient to represent any value.
     For example:

     \
     b config.install.root=c:\projects\install
     b \"config.install.root='c:\Program Files (x86)\test\'\"
     b 'config.cxx.poptions=-DFOO_STR=\"foo\"'
     \
     "
  }

  class options
  {
    "\h|OPTIONS|"

    bool -v
    {
      "Print actual commands being executed. This is equivalent to
       \cb{--verbose 2}."
    }

    bool -V
    {
      "Print all underlying commands being executed. This is equivalent to
       \cb{--verbose 3}."
    }

    bool --quiet|-q
    {
      "Run quietly, only printing error messages. This is equivalent to
       \cb{--verbose 0}."
    }

    uint16_t --verbose = 1
    {
      "<level>",
      "Set the diagnostics verbosity to <level> between 0 and 6. Level 0
       disables any non-error messages while level 6 produces lots of
       information, with level 1 being the default. The following additional
       types of diagnostics are produced at each level:

       \ol|

       \li|High-level information messages.|

       \li|Essential underlying commands being executed.|

       \li|All underlying commands being executed.|

       \li|Information that could be helpful to the user.|

       \li|Information that could be helpful to the developer.|

       \li|Even more detailed information, including state dumps.||"
    }

    size_t --jobs|-j
    {
      "<num>",
      "Number of active jobs to perform in parallel. This includes both the
       number of active threads inside the build system as well as the number
       of external commands (compilers, linkers, etc) started but not yet
       finished. If this option is not specified or specified with the \c{0}
       value, then the number of available hardware threads is used."
    }

    size_t --max-jobs|-J
    {
      "<num>",
      "Maximum number of jobs (threads) to create. The default is 16x the
       number of active jobs (\c{--jobs|j}) on 32-bit architectures and 32x
       on 64-bit. See the build system scheduler implementation for details."
    }

    size_t --queue-depth|-Q = 4
    {
      "<num>",
      "The queue depth as a multiplier over the number of active jobs.
       Normally we want a deeper queue if the jobs take long (for example,
       compilation) and shorter if they are quick (for example, simple tests).
       The default is 4. See the build system scheduler implementation for
       details."
    }

    bool --serial-stop|-s
    {
      "Run serially and stop at the first error. This mode is useful to
       investigate build failures that are caused by build system errors
       rather than compilation errors. Note that if you don't want to keep
       going but still want parallel execution, add \c{--jobs|-j} (for example
       \c{-j 0} for default concurrency)."
    }

    bool --no-column
    {
      "Don't print column numbers in diagnostics."
    }

    bool --no-line
    {
      "Don't print line and column numbers in diagnostics."
    }

    path --buildfile = "buildfile"
    {
      "<path>",
      "The alternative file to read build information from. The default is
       \cb{buildfile}. If <path> is '\cb{-}', then read from \cb{STDIN}. Note
       that this option only affects the files read as part of the buildspec
       processing. Specifically, it has no effect on the \cb{source} and
       \cb{include} directives. As a result, this option is primarily intended
       for testing rather than changing the build file names in real projects."
    }

    path --config-guess
    {
      "<path>",
      "The path to the \cb{config.guess(1)} script that should be used to
       guess the host machine triplet. If this option is not specified, then
       \cb{b} will fall back on to using the target it was built for as host."
    }

    path --config-sub
    {
      "<path>",
      "The path to the \cb{config.sub(1)} script that should be used to
       canonicalize machine triplets. If this option is not specified, then
       \cb{b} will use its built-in canonicalization support which should
       be sufficient for commonly-used platforms."
    }

    string --pager // String to allow empty value.
    {
      "<path>",
      "The pager program to be used to show long text. Commonly used pager
       programs are \cb{less} and \cb{more}. You can also specify additional
       options that should be passed to the pager program with
       \cb{--pager-option}. If an empty string is specified as the pager
       program, then no pager will be used. If the pager program is not
       explicitly specified, then \cb{b} will try to use \cb{less}. If it
       is not available, then no pager will be used."
    }

    strings --pager-option
    {
      "<opt>",
      "Additional option to be passed to the pager program. See \cb{--pager}
       for more information on the pager program. Repeat this option to
       specify multiple pager options."
    }

    bool --help {"Print usage information and exit."}
    bool --version {"Print version and exit."}
  };

  "\h|EXIT STATUS|

  Non-zero exit status is returned in case of an error.
  "

  "\h|ENVIRONMENT|

  The \cb{HOME} environment variable is used to determine the user's home
  directory. If it is not set, then \cb{getpwuid(3)} is used instead. This
  value is used to shorten paths printed in diagnostics by replacing the home
  directory with \cb{~/}. It is also made available to \cb{buildfile}'s as the
  \cb{build.home} variable.
  "
}