Skip to content

Commit

Permalink
build: add configure script
Browse files Browse the repository at this point in the history
This serves three purposes:
 - let you bake configuration into build/config.* so that you don't
   need to specify the same arguments to make repeatedly
 - provide a somewhat familiar interface to builders
 - provide more documentation for bits of the build configuration
   which there was no place to document (notably Make variables
   overridden by the user, which were documented only
   intermittently in comments in the top-level GNUmakefile).

It is *not* generated by Autoconf but is a short and hopefully
comprehensible shell script.

Internally it's fairly boring.

Overrides of makefile variables go into a new config-vars.mk, which is
written as a unit, since their construction is very cheap and they don't
need the variable-by-variable, test-by- test construction process used for
variables that end up in config.{mk,h}.

Some of the help (for all the Makeconfig overrides) is printed by calling
"make help-overrides", which ultimately derives it from the Makeconfig
itself.  (Unfortunately I can't see a way to generate the actual
write_config_var invocations from the same place, so there's still a bit of
extra work to do when you add new Makeconfig tests.)

The rest of the "make help" -- and really most of the configure script -- is
duplicative of stuff already in the GNUmakefile, but I can't see a way to
automate its generation without ending up with *way* more automation than we
have duplicated code here.

In the GNUmakefile, the biggest impact is making all the paths normal
recursively evaluated variables, so that they can pick up
configure-generated paths (which are defined later), and moving most of the
rest of the non-configure-modified variables down below the inclusion of
config-vars.mk.  This gives the desired properties for defaulting:

 - doing nothing causes the assignments in the Makefile to kick in
 - defining stuff via configure causes them to be overridden by
   further assignments in the config-vars.mk (which values are then
   picked up by the moved-down assignments
 - passing stuff on the make command line does what that normally
   does, and suppresses the corresponding in-makefile variable
   assignments, both in GNUmakefile itself and in config-vars.mk,
   thus overriding both the defaults and configure-generated paths

Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
  • Loading branch information
nickalcock committed Nov 29, 2023
1 parent e500192 commit daa20dc
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 38 deletions.
76 changes: 43 additions & 33 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,10 @@ $(if $(subst sparc64-linux,,$(subst aarch64-linux,,$(subst x86_64-linux,,$(ARCHO
$(if $(filter %-linux,$(ARCHOS)),, \
$(error "Error: DTrace only supports Linux"))

# Variables overridable by the command line and configure scripts.

CFLAGS ?= -O2 -Wall -pedantic -Wno-unknown-pragmas
LDFLAGS ?=
BITNESS := 64
NATIVE_BITNESS_ONLY := $(shell echo 'int main (void) { }' | gcc -x c -o /dev/null -m32 - 2>/dev/null || echo t)
ARCHINC := $(subst sparc64,sparc,$(subst aarch64,arm64,$(subst x86_64,i386,$(ARCH))))
INVARIANT_CFLAGS := -std=gnu99 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 $(if $(NATIVE_BITNESS_ONLY),-DNATIVE_BITNESS_ONLY) -D_DT_VERSION=\"$(VERSION)\"
CPPFLAGS += -Iinclude -Iuts/common -Iinclude/$(ARCHINC) -I$(objdir)

export CC = gcc
override CFLAGS += $(INVARIANT_CFLAGS)
PREPROCESS = $(CC) -E
export BPFC = bpf-unknown-none-gcc

BPFCPPFLAGS += -D$(subst sparc64,__sparc,$(subst aarch64,__aarch64__,$(subst x86_64,__amd64,$(ARCH))))
BPFCFLAGS ?= -O2 -Wall -Wno-unknown-pragmas
export BPFLD = bpf-unknown-none-ld

# The first non-system uid on this system.
USER_UID=$(shell grep '^UID_MIN' /etc/login.defs | awk '{print $$2;}')
Expand Down Expand Up @@ -83,30 +71,52 @@ KERNELARCH := $(subst sparc64,sparc,$(subst aarch64,arm64,$(subst x86_64,x86,$(A

# Paths.

prefix = /usr
prefix ?= /usr
export objdir := $(abspath build)
LIBDIR := $(prefix)/lib$(BITNESS)
INSTLIBDIR := $(DESTDIR)$(LIBDIR)
BINDIR := $(prefix)/bin
INSTBINDIR := $(DESTDIR)$(BINDIR)
INCLUDEDIR := $(prefix)/include
INSTINCLUDEDIR := $(DESTDIR)$(INCLUDEDIR)
SBINDIR := $(prefix)/sbin
INSTSBINDIR := $(DESTDIR)$(SBINDIR)
UDEVDIR := $(prefix)/lib/udev/rules.d
INSTUDEVDIR := $(DESTDIR)$(UDEVDIR)
SYSTEMDUNITDIR := $(prefix)/lib/systemd/system
INSTSYSTEMDUNITDIR := $(DESTDIR)$(SYSTEMDUNITDIR)
DOCDIR := $(prefix)/share/doc/dtrace-$(VERSION)
INSTDOCDIR := $(DESTDIR)$(DOCDIR)
MANDIR := $(prefix)/share/man/man8
INSTMANDIR := $(DESTDIR)$(MANDIR)
TESTDIR := $(prefix)/lib$(BITNESS)/dtrace/testsuite
INSTTESTDIR := $(DESTDIR)$(TESTDIR)
LIBDIR = $(prefix)/lib$(BITNESS)
INSTLIBDIR = $(DESTDIR)$(LIBDIR)
BINDIR = $(prefix)/bin
INSTBINDIR = $(DESTDIR)$(BINDIR)
INCLUDEDIR = $(prefix)/include
INSTINCLUDEDIR = $(DESTDIR)$(INCLUDEDIR)
SBINDIR = $(prefix)/sbin
INSTSBINDIR = $(DESTDIR)$(SBINDIR)
UDEVDIR = $(prefix)/lib/udev/rules.d
INSTUDEVDIR = $(DESTDIR)$(UDEVDIR)
SYSTEMDUNITDIR = $(prefix)/lib/systemd/system
INSTSYSTEMDUNITDIR = $(DESTDIR)$(SYSTEMDUNITDIR)
DOCDIR = $(prefix)/share/doc/dtrace-$(VERSION)
INSTDOCDIR = $(DESTDIR)$(DOCDIR)
MANDIR = $(prefix)/share/man/man8
INSTMANDIR = $(DESTDIR)$(MANDIR)
TESTDIR = $(prefix)/lib$(BITNESS)/dtrace/testsuite
INSTTESTDIR = $(DESTDIR)$(TESTDIR)
TARGETS =

DTRACE ?= $(objdir)/dtrace

# configure overrides (themselves overridden by explicit command-line options).

-include $(objdir)/config-vars.mk

# Variables derived from the above.

BITNESS := 64
NATIVE_BITNESS_ONLY := $(shell echo 'int main (void) { }' | gcc -x c -o /dev/null -m32 - 2>/dev/null || echo t)
ARCHINC := $(subst sparc64,sparc,$(subst aarch64,arm64,$(subst x86_64,i386,$(ARCH))))

INVARIANT_CFLAGS := -std=gnu99 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 $(if $(NATIVE_BITNESS_ONLY),-DNATIVE_BITNESS_ONLY) -D_DT_VERSION=\"$(VERSION)\"
CPPFLAGS += -Iinclude -Iuts/common -Iinclude/$(ARCHINC) -I$(objdir)

export CC = gcc
override CFLAGS += $(INVARIANT_CFLAGS)
PREPROCESS = $(CC) -E
export BPFC = bpf-unknown-none-gcc

BPFCPPFLAGS += -D$(subst sparc64,__sparc,$(subst aarch64,__aarch64__,$(subst x86_64,__amd64,$(ARCH))))
BPFCFLAGS ?= -O2 -Wall -Wno-unknown-pragmas
export BPFLD = bpf-unknown-none-ld

all::

# Include everything.
Expand Down
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ sudo make install

Some distributions install the BPF gcc and binutils under different names. You
can specify the executables to use using the **BPFC** and **BPFLD** variables.
E.g. on Debian you would use:
E.g. on Debian you could use:

```
make BPFC=bpf-gcc BPFLD=bpf-ld
Expand All @@ -209,11 +209,16 @@ make KERNELS="5.16.8"
as long as the source tree that kernel was built with remains where it was
when that kernel was installed.

See the GNUmakefile for more options (building translators against multiple
different kernels at once, building against kernel sources found in
different places, building against a kernel built with O=, etc.)
See `./configure --help`, `make help`, and the top-level GNUmakefile for a
full list of options (building translators against multiple different
kernels at once, building against kernel sources found in different places,
building against a kernel built with O=, installing in different places,
etc.)

'make help' might also be of interest.
Some of the options (e.g., those specifying paths) may need to be specified
when installing as well as when building. To avoid this, you can use the
configure script: it bakes variable settings into the makefile so that they
persist across multiple invocations, including `make install`.

## 3. Testing

Expand Down
143 changes: 143 additions & 0 deletions configure
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/bin/bash

set -e

write_make_var()
{
local val="$(printf "%s" "$2" | sed 's,^.*=,,')"

[[ ! -d build ]] && mkdir -p build

if [[ ! -f build/config-vars.mk ]]; then
echo 'Writing build/config-vars.mk'
echo '# This file is automatically generated.' > build/config-vars.mk
fi

printf '%s=%s\n' $1 "$val" >> build/config-vars.mk
}

write_config_var()
{
local val="$(printf "%s" "$2" | sed 's,^.*=,,')"

if [[ ! -d build/.config ]]; then
mkdir -p build/.config
touch build/.config/dir.stamp
echo 'Writing build/config.{h,mk}'
fi

case $val in
no) printf '# HAVE_%s undefined\n' $1 > build/.config/config.$1.mk
printf '/* #undef HAVE_%s */\n' $1 > build/.config/config.$1.h;;
yes|'') printf 'HAVE_%s=y\n' $1 > build/.config/config.$1.mk
printf '#define HAVE_%s 1\n' $1 > build/.config/config.$1.h;;
esac
}

rm -f build/config-vars.mk
rm -rf build/.config

help()
{
cat >&2 <<'EOF'
Installation paths:
--prefix=/usr Prefix of all installed paths
--objdir=build Build directory
--libdir=PREFIX/lib64 Library directory
--bindir=PREFIX/sbin Binary directory
--sbindir=PREFIX/sbin Alias for --bindir
--includedir=PREFIX/include #include directory
--mandir=PREFIX/share/man/man8 Manpage directory
--udevdir=PREFIX/lib/udev/rules.d udev rules directory
--systemd-unit-dir=PREFIX/lib/systemd/system systemd unit directory
--docdir=PREFIX/share/doc/dtrace Documentation directory
--testdir=LIBDIR/dtrace/testsuite Testsuite install directory
Options relating to the user environment (may need customization on
some systems, see GNUmakefile)
--user-uid=UID The first non-system uid on the system
--dumpcap-group=GROUP Group one must run as to invoke $DUMPCAP
--unpriv-uid=UID A uid suitable for unprivileged processes;
may be negative
--unpriv-home=/run/initramfs Non-writable directory to use as $HOME for
unprivileged processes
Options relating to kernels (for local builds against a running kernel
built locally, none of these should be needed):
--kernels="6.1 6.2 6.3" Space-separated list of kernel versions to
produce translators for
--kernel-mod-dir=DIR Directory used to search for kernel build trees
--kernel-src-dir=DIR Source location of kernel tree for local builds
--kernel-obj-dir=DIR O= passed to local kernels built with O=
Options controlling the compiler (pass on the command line):
CC C compiler (may be a cross-compiler)
CPP Preprocessor, by default $(CC) -E
CPPFLAGS Preprocessor flags
CFLAGS Compiler flags
LDFLAGS Linker flags
BPFC Cross-compiler to BPF
BPFCPPFLAGS BPF C preprocessor flags
BPFCFLAGS BPF C compiler flags
BPFLD BPF linker
EOF
make help-overrides
cat >&2 <<'EOF'
If passed to configure as command-line arguments, all the variables
above stick for future make invocations until "make clean".
EOF
}

for option in "$@"; do
case "$option" in
--help) help; exit 1;;
--prefix=*) write_make_var prefix "$option";;
--objdir=*) write_make_var objdir "$option";;
--libdir=*) write_make_var LIBDIR "$option";;
--bindir=*) write_make_var BINDIR "$option";;
--sbindir=*) write_make_var SBINDIR "$option";;
--includedir=*) write_make_var INCLUDEDIR "$option";;
--udevdir=*) write_make_var UDEVDIR "$option";;
--systemd-unit-dir=*) write_make_var SYSTEMDUNITDIR "$option";;
--docdir=*) write_make_var DOCDIR "$option";;
--mandir=*) write_make_var MANDIR "$option";;
--testdir=*) write_make_var TESTDIR "$option";;
CC=*) write_make_var CC "$option";;
CPP=*) write_make_var PREPROCESS "$option";;
CFLAGS=*) write_make_var CFLAGS "$option";;
CPPFLAGS=*) write_make_var CPPFLAGS "$option";;
LDFLAGS=*) write_make_var LDFLAGS "$option";;
BPFC=*) write_make_var BPFC "$option";;
BPFCPPFLAGS=*) write_make_var BPFCPPFLAGS "$option";;
BPFCFLAGS=*) write_make_var BPFCFLAGS "$option";;
BPFLD=*) write_make_var BPFLD "$option";;
--user-uid=*) write_make_var USER_UID "$option";;
--dumpcap-group=*) write_make_var DUMPCAP_GROUP "$option";;
--unpriv-uid=*) write_make_var UNPRIV_UID "$option";;
--unpriv-home=*) write_make_var UNPRIV_HOME "$option";;
--kernels=*) write_make_var KERNELS "$option";;
--kernel-mod-dir=*) write_make_var KERNEL_MOD_DIR "$option";;
--kernel-src-dir=*) write_make_var KERNEL_SRC_DIR "$option";;
--kernel-obj-dir=*) write_make_var KERNEL_OBJ_DIR "$option";;
HAVE_ELF_GETSHDRSTRNDX=*) write_config_var HAVE_ELF_GETSHDRSTRNDX "$option";;
HAVE_LIBCTF=*) write_config_var HAVE_LIBCTF "$option";;
HAVE_STRRSTR=*) write_config_var HAVE_STRRSTR "$option";;
HAVE_LIBSYSTEMD=*) write_config_var HAVE_LIBSYSTEMD "$option";;
HAVE_FUSE_LOG=*) write_config_var HAVE_FUSE_LOG "$option";;
HAVE_LIBFUSE3=*) write_config_var HAVE_LIBFUSE3 "$option";;
HAVE_FUSE_NUMA=*) write_config_var HAVE_FUSE_NUMA "$option";;
HAVE_CLOSE_RANGE=*) write_config_var HAVE_CLOSE_RANGE "$option";;
HAVE_GETTID=*) write_config_var HAVE_GETTID "$option";;
*) echo "Unknown option $option" >&2
exit 1;;
esac
done

exit 0

0 comments on commit daa20dc

Please sign in to comment.