summaryrefslogtreecommitdiffstats
path: root/docs/BUILDING.md
blob: cb33c5126479672a025fe2d63268f581d31d0246 (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
Building `bfs`
==============

A simple invocation of

    $ ./configure
    $ make

should build `bfs` successfully.


Configuration
-------------

```console
$ ./configure --help
Usage:

  $ ./configure [--enable-*|--disable-*] [CC=...] [CFLAGS=...] [...]
  $ make

...
```

### Variables

Variables set in the environment or on the command line will be picked up:
These variables specify binaries to run during the configuration and build process:

<pre>
<b>MAKE</b>=<i>make</i>
    <a href="https://en.wikipedia.org/wiki/Make_(software)">make</a> implementation
<b>CC</b>=<i>cc</i>
    C compiler
<b>INSTALL</b>=<i>install</i>
    Copy files during <i>make install</i>
<b>MKDIR</b>="<i>mkdir -p</i>"
    Create directories
<b>PKG_CONFIG</b>=<i>pkg-config</i>
    Detect external libraries and required build flags
<b>RM</b>="<i>rm -f</i>"
    Delete files
</pre>

These flags will be used by the build process:

<pre>
<b>CPPFLAGS</b>="<i>-I... -D...</i>"
<b>CFLAGS</b>="<i>-W... -f...</i>"
<b>LDFLAGS</b>="<i>-L... -Wl,...</i>"
    Preprocessor/compiler/linker flags

<b>LDLIBS</b>="<i>-l... -l...</i>"
    Dynamic libraries to link

<b>EXTRA_</b>{<b>CPPFLAGS</b>,<b>CFLAGS</b>,<b>LDFLAGS</b>,<b>LDLIBS</b>}="<i>...</i>"
    Adds to the default flags, instead of replacing them
</pre>

### Build profiles

The default flags result in a plain debug build.
Other build profiles can be enabled:

<pre>
--enable-release
    Enable optimizations, disable assertions

--enable-<a href="https://github.com/google/sanitizers/wiki/AddressSanitizer">asan</a>
--enable-<a href="https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#stand-alone-mode">lsan</a>
--enable-<a href="https://github.com/google/sanitizers/wiki/MemorySanitizer">msan</a>
--enable-<a href="https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual">tsan</a>
--enable-<a href="https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html">ubsan</a>
    Enable sanitizers

--enable-<a href="https://gcc.gnu.org/onlinedocs/gcc/gcov/introduction-to-gcov.html">gcov</a>
    Enable code coverage instrumentation
</pre>

You can combine multiple profiles (e.g. `./configure --enable-asan --enable-ubsan`), but not all of them will work together.

### Dependencies

`bfs` depends on some system libraries for some of its features.
External dependencies are auto-detected by default, but you can `--enable` or `--disable` them manually:

<pre>
--enable-<a href="https://savannah.nongnu.org/projects/acl">libacl</a>      --disable-libacl
--enable-<a href="https://sites.google.com/site/fullycapable/">libcap</a>      --disable-libcap
--enable-<a href="https://github.com/SELinuxProject/selinux">libselinux</a>  --disable-libselinux
--enable-<a href="https://github.com/axboe/liburing">liburing</a>    --disable-liburing
--enable-<a href="https://github.com/kkos/oniguruma">oniguruma</a>   --disable-oniguruma
</pre>

[`pkg-config`] is used, if available, to detect these libraries and any additional build flags they may require.
If this is undesireable, disable it by setting `PKG_CONFIG` to the empty string (`./configure PKG_CONFIG=""`).

[`pkg-config`]: https://www.freedesktop.org/wiki/Software/pkg-config/

### Out-of-tree builds

You can set up an out-of-tree build by running the `configure` script from another directory, for example:

    $ mkdir out
    $ cd out
    $ ../configure
    $ make


Building
--------

### Targets

The [`Makefile`](/Makefile) supports several different build targets:

<pre>
make
    The default target; builds just the <i>bfs</i> binary
make <b>all</b>
    Builds everything, including the tests (but doesn't run them)

make <b>check</b>
    Builds everything, and runs all tests
make <b>unit-tests</b>
    Builds and runs the unit tests
make <b>integration-tests</b>
    Builds and runs the integration tests
make <b>distcheck</b>
    Builds and runs the tests in multiple different configurations

make <b>install</b>
    Installs bfs globally
make <b>uninstall</b>
    Uninstalls bfs

make <b>clean</b>
    Deletes all built files
make <b>distclean</b>
    Also deletes files generated by ./configure
</pre>


Troubleshooting
---------------

If the build fails or behaves unexpectedly, start by enabling verbose mode:

    $ ./configure V=1
    $ make V=1

This will print the generated configuration and the exact commands that are executed.

You can also check the file `gen/config.log`, which contains any errors from commands run during the configuration phase.


Testing
-------

`bfs` comes with an extensive test suite which can be run with

    $ make check

The test harness is implemented in the file [`tests/tests.sh`](/tests/tests.sh).
Individual test cases are found in `tests/*/*.sh`.
Most of them are *snapshot tests* which compare `bfs`'s output to a known-good copy saved under the matching `tests/*/*.out`.

You can pass the name of a particular test case (or a few) to run just those tests.
For example:

    $ ./tests/tests.sh posix/basic

If you need to update the reference snapshot, pass `--update`.
It can be handy to generate the snapshot with a different `find` implementation to ensure the output is correct, for example:

    $ ./tests/tests.sh posix/basic --bfs=find --update

But keep in mind, other `find` implementations may not be correct.
To my knowledge, no other implementation passes even the POSIX-compatible subset of the tests:

    $ ./tests/tests.sh --bfs=find --posix
    ...
    tests passed: 90
    tests skipped: 3
    tests failed: 6

Run

    $ ./tests/tests.sh --help

for more details.

### Validation

A more thorough testsuite is run by the [CI](https://github.com/tavianator/bfs/actions) and to validate releases.
It builds `bfs` in multiple configurations to test for latent bugs, memory leaks, 32-bit compatibility, etc.
You can run it yourself with

    $ make distcheck

Some of these tests require `sudo`, and will prompt for your password if necessary.