summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--.github/workflows/codecov.yml2
-rw-r--r--Makefile10
-rw-r--r--build/header.mk2
-rwxr-xr-xconfigure141
-rw-r--r--docs/BUILDING.md200
6 files changed, 221 insertions, 138 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 57f59f4..e47600b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -107,7 +107,7 @@ jobs:
gmake \
oniguruma
jobs=$(sysctl -n hw.ncpu)
- MAKE=gmake ./configure
+ ./configure MAKE=gmake
gmake -j$jobs check TEST_FLAGS="--sudo --verbose=skipped"
netbsd:
@@ -198,5 +198,5 @@ jobs:
PATH="/usr/xpg4/bin:$PATH"
chown -R action:staff .
jobs=$(getconf NPROCESSORS_ONLN)
- sudo -u action MAKE=gmake ./configure
+ sudo -u action ./configure MAKE=gmake
sudo -u action gmake -j$jobs check TEST_FLAGS="--sudo --verbose=skipped"
diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml
index bb68927..6aaace6 100644
--- a/.github/workflows/codecov.yml
+++ b/.github/workflows/codecov.yml
@@ -25,7 +25,7 @@ jobs:
- name: Generate coverage
run: |
- ./configure GCOV=y
+ ./configure --enable-gcov
make -j$(nproc) check TEST_FLAGS="--sudo"
gcov -abcfpu obj/*/*.o
diff --git a/Makefile b/Makefile
index cd8bb55..8a8ec6b 100644
--- a/Makefile
+++ b/Makefile
@@ -164,11 +164,11 @@ distcheck:
.PHONY: distcheck
# Per-distcheck configuration
-DISTCHECK_CONFIG_asan := ASAN=y UBSAN=y
-DISTCHECK_CONFIG_msan := MSAN=y UBSAN=y CC=clang
-DISTCHECK_CONFIG_tsan := TSAN=y UBSAN=y CC=clang
+DISTCHECK_CONFIG_asan := --enable-asan --enable-ubsan
+DISTCHECK_CONFIG_msan := --enable-msan --enable-ubsan CC=clang
+DISTCHECK_CONFIG_tsan := --enable-tsan --enable-ubsan CC=clang
DISTCHECK_CONFIG_m32 := EXTRA_CFLAGS="-m32" PKG_CONFIG_LIBDIR=/usr/lib32/pkgconfig
-DISTCHECK_CONFIG_release := RELEASE=y
+DISTCHECK_CONFIG_release := --enable-release
${DISTCHECKS}::
@${MKDIR} $@
@@ -195,7 +195,7 @@ install::
${MSG} "[INST] completions/bfs.zsh" \
${INSTALL} -m644 completions/bfs.zsh ${DEST_PREFIX}/share/zsh/site-functions/_bfs
${Q}${MKDIR} ${DEST_PREFIX}/share/fish/vendor_completions.d
- ${MSG} "[INST] completions/bfs.fish" \
+ ${MSG} "[INST] completions/bfs.fish" \
${INSTALL} -m644 completions/bfs.fish ${DEST_PREFIX}/share/fish/vendor_completions.d/bfs.fish
uninstall::
diff --git a/build/header.mk b/build/header.mk
index 951f09b..a9157ad 100644
--- a/build/header.mk
+++ b/build/header.mk
@@ -53,7 +53,7 @@ gen/config.h: ${PKG_HEADERS} ${HEADERS}
@printf '#define BFS_CONFIG_H\n' >>$@
@cat ${.ALLSRC} >>$@
@printf '#endif // BFS_CONFIG_H\n' >>$@
- @cat ${.ALLSRC:%=%.log} >$@.log
+ @cat ${.ALLSRC:%=%.log} >gen/config.log
${VCAT} $@
.PHONY: gen/config.h
diff --git a/configure b/configure
index 830628a..d42dec3 100755
--- a/configure
+++ b/configure
@@ -7,75 +7,117 @@
set -eu
-help() {
- cat <<EOF
-Usage: $0 [-j<N>] [CC=...] [CFLAGS=...] [...]
+# Default to `make`
+MAKE="${MAKE:-make}"
-Compiler configuration:
+# Pass -j$(nproc) unless MAKEFLAGS is set
+if [ "${MAKEFLAGS+y}" ]; then
+ j=""
+else
+ j="-j$({ nproc || sysctl -n hw.ncpu || getconf _NPROCESSORS_ONLN || echo 1; } 2>/dev/null)"
+fi
+
+for arg; do
+ case "$arg" in
+ -h|--help)
+ cat <<EOF
+Usage:
+
+ \$ $0 [--enable-*|--disable-*] [CC=...] [CFLAGS=...] [...]
+ \$ $MAKE $j
+
+Variables set in the environment or on the command line will be picked up:
+ MAKE
+ The make implementation to use
CC
The C compiler to use
- CPPFLAGS
- C preprocessor flags
- CFLAGS
- C compiler flags
- LDFLAGS
- Linker flags
- LDLIBS
+
+ CPPFLAGS="-I... -D..."
+ CFLAGS="-W... -f..."
+ LDFLAGS="-L... -Wl,..."
+ Preprocessor/compiler/linker flags
+
+ LDLIBS="-l... -l..."
Dynamic libraries to link
- EXTRA_CPPFLAGS
- EXTRA_CFLAGS
- EXTRA_LDFLAGS
- EXTRA_LDLIBS
+ EXTRA_{CPPFLAGS,CFLAGS,LDFLAGS,LDLIBS}
Adds to the default flags, instead of replacing them
-Build profiles:
+The default flags result in a plain debug build. Other build profiles include:
- RELEASE=y
+ --enable-release
Enable optimizations, disable assertions
- ASAN=y
- LSAN=y
- MSAN=y
- TSAN=y
- UBSAN=y
+ --enable-{asan,lsan,msan,tsan,ubsan}
Enable sanitizers
- GCOV=y
+ --enable-gcov
Enable code coverage instrumentation
-External dependencies:
-
- PKG_CONFIG
- The pkg-config binary to use
+External dependencies are auto-detected by default, but you can --enable or
+--disable them manually:
- USE_LIBACL=[y|n]
- USE_LIBCAP=[y|n]
- USE_LIBSELINUX=[y|n]
- USE_LIBURIG=[y|n]
- USE_ONIGURUMA=[y|n]
- Enable or disable external dependencies
+ --enable-libacl --disable-libacl
+ --enable-libcap --disable-libcap
+ --enable-libselinux --disable-libselinux
+ --enable-liburing --disable-liburing
+ --enable-oniguruma --disable-oniguruma
-Packaging configuration:
+Packaging:
- PREFIX
+ --prefix=/path
Set the installation prefix (default: /usr)
- MANDIR
- Set the man page directory (default: \$PREFIX/share/man)
-EOF
-}
-for arg; do
- case "$arg" in
- --help)
- help
+This script is a thin wrapper around a makefile-based configuration system.
+Any other arguments will be passed directly to the $MAKE invocation, e.g.
+
+ \$ $0 $j V=1
+EOF
exit 0
;;
+
+ --enable-*|--disable-*)
+ case "$arg" in
+ --enable-*) yn=y ;;
+ --disable-*) yn=n ;;
+ esac
+
+ name="${arg#--*able-}"
+ NAME=$(printf '%s' "$name" | tr 'a-z-' 'A-Z_')
+ case "$name" in
+ libacl|libcap|libselinux|liburing|oniguruma)
+ shift
+ set -- "$@" "USE_$NAME=$yn"
+ ;;
+ release|asan|lsan|msan|tsan|ubsan|lint|gcov)
+ shift
+ set -- "$@" "$NAME=$yn"
+ ;;
+ *)
+ printf 'error: Unrecognized option "%s"\n\n' "$arg" >&2
+ printf 'Run %s --help for more information.\n' "$0" >&2
+ exit 1
+ ;;
+ esac
+ ;;
+
+ --prefix=*)
+ shift
+ set -- "$@" "PREFIX=${arg#*=}"
+ ;;
+
+ MAKE=*)
+ MAKE="${arg#*=}"
+ shift
+ ;;
+
+ # make flag (-j2) or variable (CC=clang)
-*|*=*)
- continue # make flag (-j2) or variable (CC=clang)
+ continue
;;
+
*)
printf 'error: Unrecognized option "%s"\n\n' "$arg" >&2
- help >&2
+ printf 'Run %s --help for more information.\n' "$0" >&2
exit 1
;;
esac
@@ -89,10 +131,7 @@ for f in Makefile build completions docs src tests; do
test -e "$f" || ln -s "$DIR/$f" "$f"
done
-# Infer -jN unless MAKEFLAGS is set
-j=
-if ! [ "${MAKEFLAGS+y}" ]; then
- j="-j$({ nproc || sysctl -n hw.ncpu || getconf _NPROCESSORS_ONLN || echo 1; } 2>/dev/null)"
-fi
+# Set MAKEFLAGS to -j$(nproc) if it's unset
+export MAKEFLAGS="${MAKEFLAGS-$j}"
-${MAKE:-make} $j -rf build/config.mk "$@"
+$MAKE -rf build/config.mk "$@"
diff --git a/docs/BUILDING.md b/docs/BUILDING.md
index db5d721..cb33c51 100644
--- a/docs/BUILDING.md
+++ b/docs/BUILDING.md
@@ -1,104 +1,101 @@
Building `bfs`
==============
-Compiling
----------
-
A simple invocation of
$ ./configure
$ make
should build `bfs` successfully.
-As usual with `make`, you can run a [parallel build](https://www.gnu.org/software/make/manual/html_node/Parallel.html) with `-j`.
-For example, to use all your cores, run `make -j$(nproc)`.
-### Targets
-| Command | Description |
-|------------------|---------------------------------------------------------------|
-| `make` | Builds just the `bfs` binary |
-| `make all` | Builds everything, including the tests (but doesn't run them) |
-| `make check` | Builds everything, and runs the tests |
-| `make install` | Installs `bfs` (with man page, shell completions, etc.) |
-| `make uninstall` | Uninstalls `bfs` |
-| `make clean` | Delete the build products |
-| `make distclean` | Delete all generated files, including the build configuration |
+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 configuration system provides a few shorthand flags for handy configurations:
-
-| Command | Description |
-|-------------------------|-------------------------------------------------------------|
-| `./configure RELEASE=y` | Build `bfs` with optimizations, LTO, and without assertions |
-| `./configure ASAN=y` | Enable [AddressSanitizer] |
-| `./configure LSAN=y` | Enable [LeakSanitizer] |
-| `./configure MSAN=y` | Enable [MemorySanitizer] |
-| `./configure TSAN=y` | Enable [ThreadSanitizer] |
-| `./configure UBSAN=y` | Enable [UndefinedBehaviorSanitizer] |
-| `./configure GCOV=y` | Enable [code coverage] |
-
-[AddressSanitizer]: https://github.com/google/sanitizers/wiki/AddressSanitizer
-[LeakSanitizer]: https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#stand-alone-mode
-[MemorySanitizer]: https://github.com/google/sanitizers/wiki/MemorySanitizer
-[ThreadSanitizer]: https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual
-[UndefinedBehaviorSanitizer]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
-[code coverage]: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html
-
-You can combine multiple profiles (e.g. `./configure ASAN=y UBSAN=y`), but not all of them will work together.
-
-### Flags
-
-Other flags can be specified on the `./configure` command line or in the environment.
-Here are some of the common ones; check the [`Makefile`](/Makefile) for more.
-
-| Flag | Description |
-|-------------------------------------|----------------------------------------------------|
-| `CC` | The C compiler to use, e.g. `./configure CC=clang` |
-| `CFLAGS`<br>`EXTRA_CFLAGS` | Override/add to the default compiler flags |
-| `LDFLAGS`<br>`EXTRA_LDFLAGS` | Override/add to the linker flags |
-| `USE_LIBACL`<br>`USE_LIBCAP`<br>... | Enable/disable [optional dependencies] |
-| `TEST_FLAGS` | `tests.sh` flags for `make check` |
-| `DESTDIR` | The root directory for `make install` |
-| `PREFIX` | The installation prefix (default: `/usr`) |
-| `MANDIR` | The man page installation directory |
-
-[optional dependencies]: #dependencies
+The default flags result in a plain debug build.
+Other build profiles can be enabled:
-### Dependencies
+<pre>
+--enable-release
+ Enable optimizations, disable assertions
-`bfs` depends on some system libraries for some of its features.
-These dependencies are optional, and can be turned off in `./configure` if necessary by setting the appropriate variable to `n` (e.g. `./configure USE_ONIGURUMA=n`).
+--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
-| Dependency | Platforms | `./configure` flag |
-|--------------|------------|--------------------|
-| [libacl] | Linux only | `USE_LIBACL` |
-| [libcap] | Linux only | `USE_LIBCAP` |
-| [liburing] | Linux only | `USE_LIBURING` |
-| [libselinux] | Linux only | `USE_LIBSELINUX` |
-| [Oniguruma] | All | `USE_ONIGURUMA` |
+--enable-<a href="https://gcc.gnu.org/onlinedocs/gcc/gcov/introduction-to-gcov.html">gcov</a>
+ Enable code coverage instrumentation
+</pre>
-[libacl]: https://savannah.nongnu.org/projects/acl
-[libcap]: https://sites.google.com/site/fullycapable/
-[libselinux]: https://github.com/SELinuxProject/selinux
-[liburing]: https://github.com/axboe/liburing
-[Oniguruma]: https://github.com/kkos/oniguruma
+You can combine multiple profiles (e.g. `./configure --enable-asan --enable-ubsan`), but not all of them will work together.
-### Dependency tracking
+### Dependencies
-The build system automatically tracks header dependencies with the `-M` family of compiler options (see `DEPFLAGS` in [`build/deps.mk`](/build/deps.mk)).
-So if you edit a header file, `make` will rebuild the necessary object files ensuring they don't go out of sync.
+`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:
-We also add a dependency on the current configuration, so you can change configurations and rebuild without having to `make clean`.
-For example,
+<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>
- $ ./configure
- $ make
- $ ./configure RELEASE=y
- $ make
+[`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=""`).
-will build the project in debug mode and then rebuild it in release mode.
+[`pkg-config`]: https://www.freedesktop.org/wiki/Software/pkg-config/
### Out-of-tree builds
@@ -110,6 +107,53 @@ You can set up an out-of-tree build by running the `configure` script from anoth
$ 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
-------