[DTrace-devel] [PATCH 5/5] build: add configure script
Kris Van Hees
kris.van.hees at oracle.com
Tue Jan 2 19:29:52 UTC 2024
On Thu, Dec 21, 2023 at 01:49:19PM -0500, Kris Van Hees via DTrace-devel wrote:
> On Wed, Nov 29, 2023 at 04:08:29PM +0000, Nick Alcock wrote:
> > 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 at oracle.com>
> > ---
> > GNUmakefile | 76 +++++++++++++++------------
> > README.md | 15 ++++--
> > configure | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 202 insertions(+), 38 deletions(-)
> > create mode 100755 configure
> >
> > diff --git a/GNUmakefile b/GNUmakefile
> > index 619b709bf78e..c39aa0d2b587 100644
> > --- a/GNUmakefile
> > +++ b/GNUmakefile
> > @@ -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;}')
> > @@ -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.
> > diff --git a/README.md b/README.md
> > index 01bdf8173562..f3b0c5b7df1b 100644
> > --- a/README.md
> > +++ b/README.md
> > @@ -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
> > @@ -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
> >
> > diff --git a/configure b/configure
> > new file mode 100755
> > index 000000000000..187884a92067
> > --- /dev/null
> > +++ b/configure
> > @@ -0,0 +1,149 @@
> > +#!/bin/bash
> > +# Allow user overrides of configuration options.
> > +#
> > +# Oracle Linux DTrace.
> > +# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
> > +# Licensed under the Universal Permissive License v 1.0 as shown at
> > +# http://oss.oracle.com/licenses/upl.
> > +
> > +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}'
>
> This is a confusing message because it is not accurate. The script is actually
> writing to build/.config/config.$1.{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
>
> This is problematic because if I simply want to invoke configure --help to get
> the help output, I do not necessarily want my previous config to get deleted.
> Surely, some options like --help should *not* have any side effects like that.
>
> In fact, ideally, I would prefer a failed configure run (if that is in fact
> even possible with this tiny script) to leave any previous config in place.
> I.e. only replace any existing config if configure is successful.
>
> Right now, nothing that I see can cause a failure - which is also interesting
> because that means if I have something wrong in my tree and e.g. config-vars.mk
> is not writable, it does not seem an error will be reported. In this version,
> obviously, the rm statements above would yield an error but since they really
> shouldn't be there IMHO, once they are removed, failing commands do not seem
> to be considered - i.e. no error checking.
>
> > +
> > +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";;
Looking closer, these KERNEL_*_DIR variables do not actually get used by
anything in the makefiles or Build files. Instead, we have KERNELMODDIR, etc.
And I expect that we should have similar options for setting KERNELSRCNAME or
KERNELSRCSUFFIX or whatever it ends up being called.
> > + 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";;
>
> Have you considered introducing options for these list --with-* and --without-*,
> especially for things like libctf, libsystemd, and fuse? The others relate to
> functions that we have our own implementation for if the libraries do not
> provide one (or we cannot verify they do), so perhaps something lihe
> --with-own-* or --without-own-* could apply?
>
> That seems to be more configure-like and more consistent? Or allow both?
>
> > + *) echo "Unknown option $option" >&2
> > + exit 1;;
> > + esac
> > +done
> > +
> > +exit 0
> > +
> > --
> > 2.42.0.271.g85384428f1
> >
> >
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
More information about the DTrace-devel
mailing list