aboutsummaryrefslogtreecommitdiff
path: root/bpkg/pkg-bindist.cli
blob: cdbb10c14a6df848daa84ab3a9a7792dd230bc7b (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
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
// file      : bpkg/pkg-bindist.cli
// license   : MIT; see accompanying LICENSE file

include <map>;

include <bpkg/configuration.cli>;

"\section=1"
"\name=bpkg-pkg-bindist"
"\summary=generate binary distribution package"

namespace bpkg
{
  {
    "<options> <dir> <vars> <pkg>",

    "\h|SYNOPSIS|

     \c{\b{bpkg pkg-bindist}|\b{bindist} [\b{--output-root}|\b{-o} <dir>] [<options>] [<vars>] <pkg>...}

     \h|DESCRIPTION|

     The \cb{pkg-bindist} command generates a binary distribution package for
     the specified package. If additional packages are specified, then they
     are bundled in the same distribution package. All the specified packages
     must have been previously configured with \l{bpkg-pkg-build(1)} or
     \l{bpkg-pkg-configure(1)}. For some system package managers a directory
     for intermediate files and subdirectories as well as the resulting binary
     package may have to be specified explicitly with the
     \c{\b{--output-root}|\b{-o}} option.

     Underneath, this command roughly performs the following steps: First it
     installs the specified packages similar to the \l{bpkg-pkg-install(1)}
     command except that it may override the installation locations (via the
     \cb{config.install.*} variables) to match the distribution's layout. Then
     it generates any necessary distribution package metadata files based on
     the information from the package \cb{manifest} files. Finally, it invokes
     the distribution-specified command to produce the binary package. Unless
     overrident with the \cb{--architecture} and \cb{--distribution} options,
     the binary package is generated for the host architecture using the
     host's standard system package manager. Additional command line variables
     (<vars>, normally \cb{config.*}) can be passed to the build system during
     the installation step. See distribution-specific description sections
     below for details and invocation examples.

     The specified packages may have dependencies and the default behavior is
     to not bundle them but rather to specify them as dependencies in the
     corresponding distribution package metadata, if applicable. This default
     behavior can be overridden with the \cb{--recursive} option (see the
     option description for the available modes). Note, however, that
     dependencies that are satisfied by system packages are always specified
     as dependencies in the distribution package metadata.
     "
  }

  // Place distribution-specific options into separate classes in case one day
  // we want to only pass their own options to each implementation.
  //
  class pkg_bindist_debian_options
  {
    "\h|DEBIAN DESCRIPTION|

     The Debian binary packages are generated by producing the standard
     \cb{debian/control}, \cb{debian/rules}, and other package metadata files
     and then invoking \cb{dpkg-buildpackage(1)} to build the binary package
     from that. In particular, the \cb{debian/rules} implemenation is based on
     the \cb{dh(1)} command sequencer. While this approach is normally used to
     build packages from source, this implementation \"pretends\" that this is
     what's happening by overriding a number of \cb{dh} targets to invoke the
     \cb{build2} build system on the required packages directly in their
     \cb{bpkg} configuration locations.

     The \cb{dpkg-dev} (or \cb{build-essential}) and \cb{debhelper} Debian
     packages must be installed before invocation. Typical invocation:

     \
     bpkg build libhello
     bpkg test libhello
     bpkg bindist -o /tmp/output/ libhello
     \

     Unless the \cb{--recursive} option is specified, dependencies of the
     specified package are translated to dependencies in the resulting binary
     package using names and versions that refer to packages that would be
     generated by the \cb{pkg-bindist} command (called \"non-native\"
     packages). If instead you would like certain dependencies to refer to
     binary packages provided by the distribution (called \"native\"
     packages), then you need to arrange for them to be built as system (see
     \l{bpkg-pkg-build(1)} for details). For example, if our \cb{libhello} has
     a dependency on \cb{libsqlite3} and we would like the binary package for
     \cb{libhello} to refer to \cb{libsqlite3} from Debian (or alike), then
     the \cb{pkg-build} command would need to be (\cb{--sys-install} is
     optional):

     \
     bpkg build --sys-install libhello ?sys:libsqlite3
     \

     Such a package with native dependencies can then be installed (including
     any missing native dependencies) using the \cb{apt} or \cb{apt-get}
     \cb{install} command. Note that the specified \cb{.deb} file must include
     a directory separator (\c{/}) in order to be recognized as a file rather
     than a package name. For example:

     \
     apt-get install ./libhello_1.2.3-0~debian11_amd64.deb \
                     ./libhello-dev_1.2.3-0~debian11_amd64.deb
     \

     See \l{bpkg#bindist-mapping-debian-produce Debian Package Mapping for
     Production} for details on \cb{bpkg} to Debian package name and version
     mapping.
     "

    "\h|PKG-BINDIST DEBIAN OPTIONS|"

    bool --debian-prepare-only
    {
      "Prepare all the package metadata files (\cb{control}, \cb{rules}, etc)
       but do not invoke \cb{bpkg-buildpackage} to generate the binary
       package, printing its command line instead unless requested to be
       quiet. Implies \cb{--keep-output}."
    }

    string --debian-buildflags = "assign"
    {
      "<mode>",
      "Package build flags (\cb{dpkg-buildflags}) usage mode. Valid <mode>
       values are \cb{assign} (use the build flags instead of configured),
       \cb{append} (use the build flags in addition to configured, putting
       them last), \cb{prepend} (use the build flags in addition to
       configured, putting them first), and \cb{ignore} (ignore build
       flags). The default mode is \cb{assign}. Note that compiler mode
       options, if any, are used as configured."
    }

    strings --debian-maint-option
    {
      "<o>",
      "Alternative options to specify in the \cb{DEB_BUILD_MAINT_OPTIONS}
       variable of the \cb{rules} file. To specify multiple maintainer options
       repeat this option and/or specify them as a single value separated
       with spaces."
    }

    strings --debian-build-option
    {
      "<o>",
      "Additional option to pass to the \cb{dpkg-buildpackage} program. Repeat
       this option to specify multiple build options."
    }

    string --debian-build-meta
    {
      "<data>",
      "Alternative build metadata to include in the binary package version.
       If empty value is specified, then no build metadata is included. By
       default, the build metadata is the \cb{ID} and \cb{VERSION_ID}
       components from \cb{os-release(5)}, for example, \cb{debian10} in
       version \cb{1.2.3-0~debian10}. See also \cb{--os-release-*}."
    }

    string --debian-section
    {
      "<v>",
      "Alternative \cb{Section} \cb{control} file field value for the main
       binary package. The default is either \cb{libs} or \cb{devel},
       depending on the package type."
    }

    string --debian-priority
    {
      "<v>",
      "Alternative \cb{Priority} \cb{control} file field value. The default
       is \cb{optional}."
    }

    string --debian-maintainer
    {
      "<v>",
      "Alternative \cb{Maintainer} \cb{control} file field value. The
       default is the \cb{package-email} value from package \cb{manifest}."
    }

    string --debian-architecture
    {
      "<v>",
      "Alternative \cb{Architecture} \cb{control} file field value for
       the main binary package. The default is \cb{any}."
    }

    string --debian-main-langdep
    {
      "<v>",
      "Override the language runtime dependencies (such as \cb{libc6},
       \cb{libstdc++6}, etc) in the \cb{Depends} \cb{control} file field
       value of the main binary package."
    }

    string --debian-dev-langdep
    {
      "<v>",
      "Override the language runtime dependencies (such as \cb{libc-dev},
       \cb{libstdc++-dev}, etc) in the \cb{Depends} \cb{control} file field
       value of the development (\cb{-dev}) binary package."
    }

    string --debian-main-extradep
    {
      "<v>",
      "Extra dependencies to add to the \cb{Depends} \cb{control} file field
       value of the main binary package."
    }

    string --debian-dev-extradep
    {
      "<v>",
      "Extra dependencies to add to the \cb{Depends} \cb{control} file field
       value of the development (\cb{-dev}) binary package."
    }
  };

  class pkg_bindist_archive_options
  {
    "\h|ARCHIVE DESCRIPTION|

     The installation archive binary packages are generated by invoking the
     \cb{build2} build system on the required packages directly in their
     \cb{bpkg} configuration locations and installing them into the binary
     package directory using the \cb{config.install.chroot} mechanism. Then
     this directory is packaged with \cb{tar} or \cb{zip} to produce one or
     more binary package archives. The installation directory layout and
     the package archives to generate can be specified with the
     \cb{--archive-install-*} and \cb{--archive-type} options (also refer
     to their documentation for defaults).

     The binary package directory (the top-level directory inside the
     archive) as well as the archive file base (the file name without
     the extension) are the same and have the following form:

     \c{\i{package}-\i{version}-\i{build_metadata}}

     Where \ci{package} is the package name and \ci{version} is the \cb{bpkg}
     package version. Unless overridden with the \cb{--archive-build-meta}
     option, \ci{build_metadata} has the following form:

     \c{\i{cpu}-\i{os}[-\i{langrt}...]}

     Where \ci{cpu} is the target CPU (for example, \cb{x86_64}), \ci{os} is
     the \cb{ID} and \cb{VERSION_ID} components from \cb{os-release(5)} (or
     equivalent, for example, \cb{debian11} or \cb{windows10}), and
     \ci{langrt} are the language runtimes as mapped by the
     \cb{--archive-lang*} options (for example, \cb{gcc12}, \cb{msvc17.4}).

     For example, given the following invocation on Debian 11:

     \
     bpkg build libhello
     bpkg test libhello
     bpkg bindist              \
       -o /tmp/output/         \
       --distribution=archive  \
       --archive-lang cc=gcc12 \
       libhello
     \

     We will end up with the package archive in the following form:

     \
     libhello-1.2.3-x86_64-debian11-gcc12.tar.xz
     \

     The recommended language runtime id format is the runtime name followed
     by the version, for example, \cb{gcc12} or \cb{msvc17.4}. Note that its
     purpose is not to provide a precise specification of requirements but
     rather to help the user of a binary package to pick the appropriate
     variant. Refer to the \cb{--archive-lang*} options documentation for
     details on the mapping semantics.

     Instead of mapping languages individually you can specify entire build
     metadata as a single value with the \cb{--archive-build-meta}, for
     example:

     \
     bpkg bindist                              \
       -o /tmp/output/                         \
       --distribution=archive                  \
       --archive-build-meta=x86_64-linux-glibc
       libhello
     \

     This will produce the package archive in the following form:

     \
     libhello-1.2.3-x86_64-linux-glibc.tar.xz
     \

     To install the binary package from archive simply unpack it using
     \cb{tar} or \cb{zip}. You can use the \cb{--strip-components} \cb{tar}
     option to remove the top-level package directory (the same can be
     achieved for \cb{zip} archives by using \cb{bsdtar} on Windows). For
     example, to unpack the package contents so that they end up in
     \cb{/usr/local/}:

     \
     sudo tar -xf libhello-1.2.3-x86_64-debian11-gcc12.tar.xz \
        -C / --strip-components=1
     \

     The installation archive package can be generated for a target other than
     the host by specifying the target triplet with the \cb{--architecture}
     option. In this case the \cb{bpkg} configuration is assumed to be
     appropriately configured for cross-compiling to the specified target. You
     will also need to explicitly specify the \cb{--archive-install-root}
     option (or \cb{--archive-install-config}) as well as the
     \cb{--os-release-id} option (and likely want to specify other
     \cb{--os-release-*} options). For example, for cross-compiling from Linux
     to Windows using the MinGW GCC toolchain:

     \
     bpkg bindist                        \
       --distribution=archive            \
       --architecture=x86_64-w64-mingw32 \
       --os-release-id=windows           \
       --os-release-name=Windows         \
       --os-release-version-id=10        \
       --archive-install-root /          \
       --archive-lang cc=mingw_w64_gcc12 \
       ...
     \
     "

    "\h|PKG-BINDIST ARCHIVE OPTIONS|"

    bool --archive-prepare-only
    {
      "Prepare all the package contents but do not create the binary package
       archive, printing its directory instead unless requested to be quiet.
       Implies \cb{--keep-output}."
    }

    strings --archive-type
    {
      "<ext>",
      "Archive type to create specified as a file extension, for example,
       \cb{tar.xz}, \cb{tar.gz}, \cb{tar}, \cb{zip}. Repeat this option to
       generate multiple archive types. If unspecified, then a default type
       appropriate for the target operating system is used, currently \cb{zip}
       for Windows and \cb{tar.xz} for POSIX. Note, however, that these
       defaults may change in the future."
    }

    std::map<string, string> --archive-lang
    {
      "<ln>=<rt>",
      "Map interface language name <ln> to runtime id <rt>. If no mapping is
       found for an interface language in this map, then fallback to the
       \cb{--archive-lang-impl} map. If still no mapping is found, then
       fail. If the information about an interface language is unimportant and
       should be ignored, then empty runtime id can be specified. Note that
       the mapping specified with this option is only considered if the
       package type is a library (for other package types all languages
       used are implementation)."
    }

    std::map<string, string> --archive-lang-impl
    {
      "<ln>=<rt>",
      "Map implementation language name <ln> to runtime id <rt>. If no mapping
       is found for an implementation language in this map, then assume
       the information about this implementation language is unimportant
       and ignore it (examples of such cases include static linking as well
       as a language runtime that is always present)."
    }

    string --archive-build-meta
    {
      "<data>",
      "Alternative build metadata to include after the version in the binary
       package directory and file names. If empty value is specified, then no
       build metadata is included."
    }

    dir_path --archive-install-root
    {
      "<d>",
      "Alternative installation root directory. The default is \cb{/usr/local/}
       on POSIX and \c{\b{C:\\}\i{project}\b{\\}} on Windows, where
       \ci{project} is the \l{bpkg#manifest-package-project \cb{project}}
       package manifest value."
    }

    bool --archive-install-config
    {
      "Use the installation directory layout (\cb{config.install.*} variables)
       as configured instead of overriding them with defaults appropriate for
       the target operating system. Note that this includes
       \cb{config.install.private} and \cb{config.bin.rpath} if needed for a
       private installation. Note also that the \cb{config.install.root} value
       is still overridden with the \cb{--archive-install-root} option value
       if specified."
    }
  };

  // NOTE: remember to add the corresponding `--class-doc ...=exclude-base`
  //       (both in bpkg/ and doc/) if adding a new base class.
  //
  class pkg_bindist_options: configuration_options,
                             pkg_bindist_debian_options,
                             pkg_bindist_archive_options
  {
    "\h|PKG-BINDIST COMMON OPTIONS|"

    string --distribution
    {
      "<name>",
      "Alternative system/distribution package manager to generate the binary
       package for. The valid <name> values are \cb{debian} (Debian and alike,
       such as Ubuntu, etc), \cb{fedora} (Fedora and alike, such as RHEL,
       CentOS, etc), and \cb{archive} (installation archive on any operating
       system). Note that some package managers may only be supported when
       running on certain host operating systems."
    }

    string --architecture
    {
      "<name>",
      "Alternative architecture to generate the binary package for. The
       valid <name> values are system/distribution package manager-specific.
       If unspecified, the host architecture is used."
    }

    string --recursive
    {
      "<mode>",
      "Bundle dependencies of the specified packages. The <mode> value can be
       either \cb{auto}, in which case only the required files from each
       dependency package are bundled, or \cb{full}, in which case all the
       files are bundled. Specifically, in the \cb{auto} mode any required
       files, for example, shared libraries, are pulled implicitly by the
       \cb{install} build system operation, for example, as part of
       installing an executable from one of the specified packages. In
       contrast, in the \cb{full} mode, each dependency package is
       installed explicitly and completely, as if they were specified
       as additional package on the command line. See also the \cb{--private}
       option."
    }

    bool --private
    {
      "Enable the private installation subdirectory functionality using the
       package name as the private subdirectory. This is primarily useful
       when bundling dependencies, such as shared libraries, of an executable
       that is being installed into a shared location, such as \cb{/usr/}.
       See the \cb{config.install.private} configuration variable
       documentation in the build system manual for details. This option only
       makes sense together with \cb{--recursive}."
    }

    dir_path --output-root|-o
    {
      "<dir>",
      "Directory for intermediate files and subdirectories as well as the
       resulting binary package. Note that this option may be required for
       some system package managers and may not be specified for others."
    }

    bool --wipe-output
    {
      "Wipe the output root directory (either specified with \ci{--output-root}
       or system package manager-specific) clean before using it to generate
       the binary package."
    }

    bool --keep-output
    {
      "Keep intermediate files in the output root directory (either specified
       with \ci{--output-root} or system package manager-specific) that were
       used to generate the binary package. This is primarily useful for
       troubleshooting."
    }

    string --os-release-id
    {
      "<v>",
      "Override the \cb{ID} component in \cb{os-release(5)} or equivalent.
       Note that unlike the rest of the \cb{--os-release-*} options, this
       option suppresses automatic detection of the host operating system
       inormation."
    }

    string --os-release-version-id
    {
      "<v>",
      "Override the \cb{VERSION_ID} component in \cb{os-release(5)} or
       equivalent."
    }

    string --os-release-name
    {
      "<v>",
      "Override the \cb{NAME} component in \cb{os-release(5)} or equivalent."
    }
  };

  "
   \h|DEFAULT OPTIONS FILES|

   See \l{bpkg-default-options-files(1)} for an overview of the default
   options files. For the \cb{pkg-bindist} command the search start
   directory is the configuration directory. The following options files are
   searched for in each directory and, if found, loaded in the order listed:

   \
   bpkg.options
   bpkg-pkg-bindist.options
   \

   The following \cb{pkg-bindist} command options cannot be specified in the
   default options files:

   \
   --directory|-d
   \
  "
}