1# Build
2
3This `bc` attempts to be as portable as possible. It can be built on any
4POSIX-compliant system.
5
6To accomplish that, a POSIX-compatible, custom `configure.sh` script is used to
7select build options, compiler, and compiler flags and generate a `Makefile`.
8
9The general form of configuring, building, and installing this `bc` is as
10follows:
11
12```
13[ENVIRONMENT_VARIABLE=<value>...] ./configure.sh [build_options...]
14make
15make install
16```
17
18To get all of the options, including any useful environment variables, use
19either one of the following commands:
20
21```
22./configure.sh -h
23./configure.sh --help
24```
25
26***WARNING***: even though `configure.sh` supports both option types, short and
27long, it does not support handling both at the same time. Use only one type.
28
29To learn the available `make` targets run the following command after running
30the `configure.sh` script:
31
32```
33make help
34```
35
36See [Build Environment Variables][4] for a more detailed description of all
37accepted environment variables and [Build Options][5] for more detail about all
38accepted build options.
39
40## Windows
41
42On Windows, this `bc` can be built using Visual Studio or MSBuild.
43
44However, only one build configuration (besides Debug or Release) is supported:
45extra math and prompt enabled, history and NLS (locale support) disabled, with
46both calculators built.
47
48The library can also be built on Windows.
49
50### Visual Studio
51
52In Visual Studio, open up the solution file (`bc.sln` for `bc`, or `bcl.sln` for
53the library), select the desired configuration, and build.
54
55### MSBuild
56
57To build with MSBuild, first, *be sure that you are using the MSBuild that comes
58with Visual Studio*.
59
60To build `bc`, run the following from the root directory:
61
62```
63msbuild -property:Configuration=<config> bc.sln
64```
65
66where `<config>` is either one of `Debug` or `Release`.
67
68To build the library, run the following from the root directory:
69
70```
71msbuild -property:Configuration=<config> bcl.sln
72```
73
74where `<config>` is either one of `Debug` or `Release`.
75
76## POSIX-Compatible Systems
77
78Building `bc`, `dc`, and `bcl` (the library) is more complex than on Windows
79because many build options are supported.
80
81<a name="cross-compiling"/>
82
83### Cross Compiling
84
85To cross-compile this `bc`, an appropriate compiler must be present and assigned
86to the environment variable `HOSTCC` or `HOST_CC` (the two are equivalent,
87though `HOSTCC` is prioritized). This is in order to bootstrap core file(s), if
88the architectures are not compatible (i.e., unlike i686 on x86_64). Thus, the
89approach is:
90
91```
92HOSTCC="/path/to/native/compiler" ./configure.sh
93make
94make install
95```
96
97`HOST_CC` will work in exactly the same way.
98
99`HOSTCFLAGS` and `HOST_CFLAGS` can be used to set compiler flags for `HOSTCC`.
100(The two are equivalent, as `HOSTCC` and `HOST_CC` are.) `HOSTCFLAGS` is
101prioritized over `HOST_CFLAGS`. If neither are present, `HOSTCC` (or `HOST_CC`)
102uses `CFLAGS` (see [Build Environment Variables][4] for more details).
103
104It is expected that `CC` produces code for the target system and `HOSTCC`
105produces code for the host system. See [Build Environment Variables][4] for more
106details.
107
108If an emulator is necessary to run the bootstrap binaries, it can be set with
109the environment variable `GEN_EMU`.
110
111<a name="build-environment-variables"/>
112
113### Build Environment Variables
114
115This `bc` supports `CC`, `HOSTCC`, `HOST_CC`, `CFLAGS`, `HOSTCFLAGS`,
116`HOST_CFLAGS`, `CPPFLAGS`, `LDFLAGS`, `LDLIBS`, `PREFIX`, `DESTDIR`, `BINDIR`,
117`DATAROOTDIR`, `DATADIR`, `MANDIR`, `MAN1DIR`, `LOCALEDIR` `EXECSUFFIX`,
118`EXECPREFIX`, `LONG_BIT`, `GEN_HOST`, and `GEN_EMU` environment variables in
119`configure.sh`. Any values of those variables given to `configure.sh` will be
120put into the generated Makefile.
121
122More detail on what those environment variables do can be found in the following
123sections.
124
125#### `CC`
126
127C compiler for the target system. `CC` must be compatible with POSIX `c99`
128behavior and options. However, **I encourage users to use any C99 or C11
129compatible compiler they wish.**
130
131If there is a space in the basename of the compiler, the items after the first
132space are assumed to be compiler flags, and in that case, the flags are
133automatically moved into CFLAGS.
134
135Defaults to `c99`.
136
137### `HOSTCC` or `HOST_CC`
138
139C compiler for the host system, used only in [cross compiling][6]. Must be
140compatible with POSIX `c99` behavior and options.
141
142If there is a space in the basename of the compiler, the items after the first
143space are assumed to be compiler flags, and in that case, the flags are
144automatically moved into HOSTCFLAGS.
145
146Defaults to `$CC`.
147
148#### `CFLAGS`
149
150Command-line flags that will be passed verbatim to `CC`.
151
152Defaults to empty.
153
154#### `HOSTCFLAGS` or `HOST_CFLAGS`
155
156Command-line flags that will be passed verbatim to `HOSTCC` or `HOST_CC`.
157
158Defaults to `$CFLAGS`.
159
160#### `CPPFLAGS`
161
162Command-line flags for the C preprocessor. These are also passed verbatim to
163both compilers (`CC` and `HOSTCC`); they are supported just for legacy reasons.
164
165Defaults to empty.
166
167#### `LDFLAGS`
168
169Command-line flags for the linker. These are also passed verbatim to both
170compilers (`CC` and `HOSTCC`); they are supported just for legacy reasons.
171
172Defaults to empty.
173
174#### `LDLIBS`
175
176Libraries to link to. These are also passed verbatim to both compilers (`CC` and
177`HOSTCC`); they are supported just for legacy reasons and for cross compiling
178with different C standard libraries (like [musl][3]).
179
180Defaults to empty.
181
182#### `PREFIX`
183
184The prefix to install to.
185
186Can be overridden by passing the `--prefix` option to `configure.sh`.
187
188Defaults to `/usr/local`.
189
190#### `DESTDIR`
191
192Path to prepend onto `PREFIX`. This is mostly for distro and package
193maintainers.
194
195This can be passed either to `configure.sh` or `make install`. If it is passed
196to both, the one given to `configure.sh` takes precedence.
197
198Defaults to empty.
199
200#### `BINDIR`
201
202The directory to install binaries in.
203
204Can be overridden by passing the `--bindir` option to `configure.sh`.
205
206Defaults to `$PREFIX/bin`.
207
208#### `INCLUDEDIR`
209
210The directory to install header files in.
211
212Can be overridden by passing the `--includedir` option to `configure.sh`.
213
214Defaults to `$PREFIX/include`.
215
216#### `LIBDIR`
217
218The directory to install libraries in.
219
220Can be overridden by passing the `--libdir` option to `configure.sh`.
221
222Defaults to `$PREFIX/lib`.
223
224#### `DATAROOTDIR`
225
226The root directory to install data files in.
227
228Can be overridden by passing the `--datarootdir` option to `configure.sh`.
229
230Defaults to `$PREFIX/share`.
231
232#### `DATADIR`
233
234The directory to install data files in.
235
236Can be overridden by passing the `--datadir` option to `configure.sh`.
237
238Defaults to `$DATAROOTDIR`.
239
240#### `MANDIR`
241
242The directory to install manpages in.
243
244Can be overridden by passing the `--mandir` option to `configure.sh`.
245
246Defaults to `$DATADIR/man`
247
248#### `MAN1DIR`
249
250The directory to install Section 1 manpages in. Because both `bc` and `dc` are
251Section 1 commands, this is the only relevant section directory.
252
253Can be overridden by passing the `--man1dir` option to `configure.sh`.
254
255Defaults to `$MANDIR/man1`.
256
257#### `LOCALEDIR`
258
259The directory to install locales in.
260
261Can be overridden by passing the `--localedir` option to `configure.sh`.
262
263Defaults to `$DATAROOTDIR/locale`.
264
265#### `EXECSUFFIX`
266
267The suffix to append onto the executable names *when installing*. This is for
268packagers and distro maintainers who want this `bc` as an option, but do not
269want to replace the default `bc`.
270
271Defaults to empty.
272
273#### `EXECPREFIX`
274
275The prefix to append onto the executable names *when building and installing*.
276This is for packagers and distro maintainers who want this `bc` as an option,
277but do not want to replace the default `bc`.
278
279Defaults to empty.
280
281#### `LONG_BIT`
282
283The number of bits in a C `long` type. This is mostly for the embedded space.
284
285This `bc` uses `long`s internally for overflow checking. In C99, a `long` is
286required to be 32 bits. For this reason, on 8-bit and 16-bit microcontrollers,
287the generated code to do math with `long` types may be inefficient.
288
289For most normal desktop systems, setting this is unnecessary, except that 32-bit
290platforms with 64-bit longs may want to set it to `32`.
291
292Defaults to the default value of `LONG_BIT` for the target platform. For
293compliance with the `bc` spec, the minimum allowed value is `32`.
294
295It is an error if the specified value is greater than the default value of
296`LONG_BIT` for the target platform.
297
298#### `GEN_HOST`
299
300Whether to use `gen/strgen.c`, instead of `gen/strgen.sh`, to produce the C
301files that contain the help texts as well as the math libraries. By default,
302`gen/strgen.c` is used, compiled by `$HOSTCC` and run on the host machine. Using
303`gen/strgen.sh` removes the need to compile and run an executable on the host
304machine since `gen/strgen.sh` is a POSIX shell script. However, `gen/lib2.bc` is
305perilously close to 4095 characters, the max supported length of a string
306literal in C99 (and it could be added to in the future), and `gen/strgen.sh`
307generates a string literal instead of an array, as `gen/strgen.c` does. For most
308production-ready compilers, this limit probably is not enforced, but it could
309be. Both options are still available for this reason.
310
311If you are sure your compiler does not have the limit and do not want to compile
312and run a binary on the host machine, set this variable to "0". Any other value,
313or a non-existent value, will cause the build system to compile and run
314`gen/strgen.c`.
315
316Default is "".
317
318#### `GEN_EMU`
319
320The emulator to run bootstrap binaries under. This is only if the binaries
321produced by `HOSTCC` (or `HOST_CC`) need to be run under an emulator to work.
322
323Defaults to empty.
324
325<a name="build-options"/>
326
327### Build Options
328
329This `bc` comes with several build options, all of which are enabled by default.
330
331All options can be used with each other, with a few exceptions that will be
332noted below.
333
334**NOTE**: All long options with mandatory argumenst accept either one of the
335following forms:
336
337```
338--option arg
339--option=arg
340```
341
342#### Library
343
344To build the math library, use the following commands for the configure step:
345
346```
347./configure.sh -a
348./configure.sh --library
349```
350
351Both commands are equivalent.
352
353When the library is built, history, prompt, and locales are disabled, and the
354functionality for `bc` and `dc` are both enabled, though the executables are
355*not* built. This is because the library's options clash with the executables.
356
357To build an optimized version of the library, users can pass optimization
358options to `configure.sh` or include them in `CFLAGS`.
359
360The library API can be found in `manuals/bcl.3.md` or `man bcl` once the library
361is installed.
362
363The library is built as `bin/libbcl.a`.
364
365#### `bc` Only
366
367To build `bc` only (no `dc`), use any one of the following commands for the
368configure step:
369
370```
371./configure.sh -b
372./configure.sh --bc-only
373./configure.sh -D
374./configure.sh --disable-dc
375```
376
377Those commands are all equivalent.
378
379***Warning***: It is an error to use those options if `bc` has also been
380disabled (see below).
381
382#### `dc` Only
383
384To build `dc` only (no `bc`), use either one of the following commands for the
385configure step:
386
387```
388./configure.sh -d
389./configure.sh --dc-only
390./configure.sh -B
391./configure.sh --disable-bc
392```
393
394Those commands are all equivalent.
395
396***Warning***: It is an error to use those options if `dc` has also been
397disabled (see above).
398
399<a name="build-history"/>
400
401#### History
402
403To disable signal handling, pass either the `-H` flag or the `--disable-history`
404option to `configure.sh`, as follows:
405
406```
407./configure.sh -H
408./configure.sh --disable-history
409```
410
411Both commands are equivalent.
412
413History is automatically disabled when building for Windows or on another
414platform that does not support the terminal handling that is required.
415
416***WARNING***: Of all of the code in the `bc`, this is the only code that is not
417completely portable. If the `bc` does not work on your platform, your first step
418should be to retry with history disabled.
419
420#### NLS (Locale Support)
421
422To disable locale support (use only English), pass either the `-N` flag or the
423`--disable-nls` option to `configure.sh`, as follows:
424
425```
426./configure.sh -N
427./configure.sh --disable-nls
428```
429
430Both commands are equivalent.
431
432NLS (locale support) is automatically disabled when building for Windows or on
433another platform that does not support the POSIX locale API or utilities.
434
435#### Prompt
436
437By default, `bc` and `dc` print a prompt when in interactive mode. They both
438have the command-line option `-P`/`--no-prompt`, which turns that off, but it
439can be disabled permanently in the build by passing the `-P` flag or the
440`--disable-prompt` option to `configure.sh`, as follows:
441
442```
443./configure.sh -P
444./configure.sh --disable-prompt
445```
446
447Both commands are equivalent.
448
449#### Locales
450
451By default, `bc` and `dc` do not install all locales, but only the enabled
452locales. If `DESTDIR` exists and is not empty, then they will install all of
453the locales that exist on the system. The `-l` flag or `--install-all-locales`
454option skips all of that and just installs all of the locales that `bc` and `dc`
455have, regardless. To enable that behavior, you can pass the `-l` flag or the
456`--install-all-locales` option to `configure.sh`, as follows:
457
458```
459./configure.sh -l
460./configure.sh --install-all-locales
461```
462
463Both commands are equivalent.
464
465#### Extra Math
466
467This `bc` has 7 extra operators:
468
469* `$` (truncation to integer)
470* `@` (set precision)
471* `@=` (set precision and assign)
472* `<<` (shift number left, shifts radix right)
473* `<<=` (shift number left and assign)
474* `>>` (shift number right, shifts radix left)
475* `>>=` (shift number right and assign)
476
477There is no assignment version of `$` because it is a unary operator.
478
479The assignment versions of the above operators are not available in `dc`, but
480the others are, as the operators `$`, `@`, `H`, and `h`, respectively.
481
482In addition, this `bc` has the option of outputting in scientific notation or
483engineering notation. It can also take input in scientific or engineering
484notation. On top of that, it has a pseudo-random number generator. (See the
485full manual for more details.)
486
487Extra operators, scientific notation, engineering notation, and the
488pseudo-random number generator can be disabled by passing either the `-E` flag
489or the `--disable-extra-math` option to `configure.sh`, as follows:
490
491```
492./configure.sh -E
493./configure.sh --disable-extra-math
494```
495
496Both commands are equivalent.
497
498This `bc` also has a larger library that is only enabled if extra operators and
499the pseudo-random number generator are. More information about the functions can
500be found in the Extended Library section of the full manual.
501
502#### Manpages
503
504To disable installing manpages, pass either the `-M` flag or the
505`--disable-man-pages` option to `configure.sh` as follows:
506
507```
508./configure.sh -M
509./configure.sh --disable-man-pages
510```
511
512Both commands are equivalent.
513
514#### Karatsuba Length
515
516The Karatsuba length is the point at which `bc` and `dc` switch from Karatsuba
517multiplication to brute force, `O(n^2)` multiplication. It can be set by passing
518the `-k` flag or the `--karatsuba-len` option to `configure.sh` as follows:
519
520```
521./configure.sh -k64
522./configure.sh --karatsuba-len 64
523```
524
525Both commands are equivalent.
526
527Default is `64`.
528
529***WARNING***: The Karatsuba Length must be a **integer** greater than or equal
530to `16` (to prevent stack overflow). If it is not, `configure.sh` will give an
531error.
532
533#### Install Options
534
535The relevant `autotools`-style install options are supported in `configure.sh`:
536
537* `--prefix`
538* `--bindir`
539* `--datarootdir`
540* `--datadir`
541* `--mandir`
542* `--man1dir`
543* `--localedir`
544
545An example is:
546
547```
548./configure.sh --prefix=/usr --localedir /usr/share/nls
549make
550make install
551```
552
553They correspond to the environment variables `$PREFIX`, `$BINDIR`,
554`$DATAROOTDIR`, `$DATADIR`, `$MANDIR`, `$MAN1DIR`, and `$LOCALEDIR`,
555respectively.
556
557***WARNING***: If the option is given, the value of the corresponding
558environment variable is overridden.
559
560***WARNING***: If any long command-line options are used, the long form of all
561other command-line options must be used. Mixing long and short options is not
562supported.
563
564### Optimization
565
566The `configure.sh` script will accept an optimization level to pass to the
567compiler. Because `bc` is orders of magnitude faster with optimization, I
568***highly*** recommend package and distro maintainers pass the highest
569optimization level available in `CC` to `configure.sh` with the `-O` flag or
570`--opt` option, as follows:
571
572```
573./configure.sh -O3
574./configure.sh --opt 3
575```
576
577Both commands are equivalent.
578
579The build and install can then be run as normal:
580
581```
582make
583make install
584```
585
586As usual, `configure.sh` will also accept additional `CFLAGS` on the command
587line, so for SSE4 architectures, the following can add a bit more speed:
588
589```
590CFLAGS="-march=native -msse4" ./configure.sh -O3
591make
592make install
593```
594
595Building with link-time optimization (`-flto` in clang) can further increase the
596performance. I ***highly*** recommend doing so.
597
598I do **NOT*** recommend building with `-march=native`; doing so reduces this
599`bc`'s performance.
600
601Manual stripping is not necessary; non-debug builds are automatically stripped
602in the link stage.
603
604### Debug Builds
605
606Debug builds (which also disable optimization if no optimization level is given
607and if no extra `CFLAGS` are given) can be enabled with either the `-g` flag or
608the `--debug` option, as follows:
609
610```
611./configure.sh -g
612./configure.sh --debug
613```
614
615Both commands are equivalent.
616
617The build and install can then be run as normal:
618
619```
620make
621make install
622```
623
624### Stripping Binaries
625
626By default, when `bc` and `dc` are not built in debug mode, the binaries are
627stripped. Stripping can be disabled with either the `-T` or the
628`--disable-strip` option, as follows:
629
630```
631./configure.sh -T
632./configure.sh --disable-strip
633```
634
635Both commands are equivalent.
636
637The build and install can then be run as normal:
638
639```
640make
641make install
642```
643
644### Binary Size
645
646When built with both calculators, all available features, and `-Os` using
647`clang` and `musl`, the executable is 140.4 kb (140,386 bytes) on `x86_64`. That
648isn't much for what is contained in the binary, but if necessary, it can be
649reduced.
650
651The single largest user of space is the `bc` calculator. If just `dc` is needed,
652the size can be reduced to 107.6 kb (107,584 bytes).
653
654The next largest user of space is history support. If that is not needed, size
655can be reduced (for a build with both calculators) to 119.9 kb (119,866 bytes).
656
657There are several reasons that history is a bigger user of space than `dc`
658itself:
659
660* `dc`'s lexer and parser are *tiny* compared to `bc`'s because `dc` code is
661  almost already in the form that it is executed in, while `bc` has to not only
662  adjust the form to be executable, it has to parse functions, loops, `if`
663  statements, and other extra features.
664* `dc` does not have much extra code in the interpreter.
665* History has a lot of const data for supporting `UTF-8` terminals.
666* History pulls in a bunch of more code from the `libc`.
667
668The next biggest user is extra math support. Without it, the size is reduced to
669124.0 kb (123,986 bytes) with history and 107.6 kb (107,560 bytes) without
670history.
671
672The reasons why extra math support is bigger than `dc`, besides the fact that
673`dc` is small already, are:
674
675* Extra math supports adds an extra math library that takes several kilobytes of
676  constant data space.
677* Extra math support includes support for a pseudo-random number generator,
678  including the code to convert a series of pseudo-random numbers into a number
679  of arbitrary size.
680* Extra math support adds several operators.
681
682The next biggest user is `dc`, so if just `bc` is needed, the size can be
683reduced to 128.1 kb (128,096 bytes) with history and extra math support, 107.6
684kb (107,576 bytes) without history and with extra math support, and 95.3 kb
685(95,272 bytes) without history and without extra math support.
686
687*Note*: all of these binary sizes were compiled using `musl` `1.2.0` as the
688`libc`, making a fully static executable, with `clang` `9.0.1` (well,
689`musl-clang` using `clang` `9.0.1`) as the compiler and using `-Os`
690optimizations. These builds were done on an `x86_64` machine running Gentoo
691Linux.
692
693### Testing
694
695The default test suite can be run with the following command:
696
697```
698make test
699```
700
701To test `bc` only, run the following command:
702
703```
704make test_bc
705```
706
707To test `dc` only, run the following command:
708
709```
710make test_dc
711```
712
713This `bc`, if built, assumes a working, GNU-compatible `bc`, installed on the
714system and in the `PATH`, to generate some tests, unless the `-G` flag or
715`--disable-generated-tests` option is given to `configure.sh`, as follows:
716
717```
718./configure.sh -G
719./configure.sh --disable-generated-tests
720```
721
722After running `configure.sh`, build and run tests as follows:
723
724```
725make
726make test
727```
728
729This `dc` also assumes a working, GNU-compatible `dc`, installed on the system
730and in the `PATH`, to generate some tests, unless one of the above options is
731given to `configure.sh`.
732
733To generate test coverage, pass the `-c` flag or the `--coverage` option to
734`configure.sh` as follows:
735
736```
737./configure.sh -c
738./configure.sh --coverage
739```
740
741Both commands are equivalent.
742
743***WARNING***: Both `bc` and `dc` must be built for test coverage. Otherwise,
744`configure.sh` will give an error.
745
746[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
747[2]: https://www.gnu.org/software/bc/
748[3]: https://www.musl-libc.org/
749[4]: #build-environment-variables
750[5]: #build-options
751[6]: #cross-compiling
752