From 1e30a0244cc691a0d0cdd6b515e2a2b099774f04 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sat, 7 Mar 2026 11:18:51 -0500 Subject: [PATCH 01/17] configure: don't use 'echo -n' under /bin/sh It's not POSIX-compatible. Use printf instead. Changelog-None --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 0cd88749dc92..cd66c46ba27e 100755 --- a/configure +++ b/configure @@ -134,7 +134,7 @@ check_command() name="$1" shift 1 - echo -n "checking for $name... " + printf 'checking for %s... ' "${name}" if "$@" >/dev/null 2>&1 Date: Sat, 7 Mar 2026 12:07:58 -0500 Subject: [PATCH 02/17] configure: be consistent in writing status output to stderr Changelog-None --- configure | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/configure b/configure index cd66c46ba27e..a79e14dd910e 100755 --- a/configure +++ b/configure @@ -134,12 +134,12 @@ check_command() name="$1" shift 1 - printf 'checking for %s... ' "${name}" + printf 'checking for %s... ' "${name}" >&2 if "$@" >/dev/null 2>&1 &2 return 0 fi - echo 'not found' + echo 'not found' >&2 return 1 } @@ -277,9 +277,9 @@ usage() add_var() { if [ -n "$2" ]; then - echo "Setting $1... $2" + echo "Setting $1... $2" >&2 else - echo "$1 not found" + echo "$1 not found" >&2 fi echo "$1=$2" >> $CONFIG_VAR_FILE.$$ [ -z "$3" ] || echo "#define $1 $2" >> "$3" @@ -334,10 +334,10 @@ for opt in "$@"; do --disable-fuzzing) FUZZING=0;; --enable-rust) RUST=1;; --disable-rust) RUST=0;; - --help|-h) usage;; + --help|-h) usage >&2;; *) echo "Unknown option '$opt'" >&2 - usage + usage >&2 ;; esac done @@ -347,7 +347,7 @@ set_defaults if [ "$ASAN" = "1" ]; then if [ "$VALGRIND" = "1" ]; then - echo "Address sanitizer (ASAN) and valgrind cannot be enabled at the same time" + echo "Address sanitizer (ASAN) and valgrind cannot be enabled at the same time" >&2 exit 1 fi @@ -381,16 +381,16 @@ else fi # We assume warning flags don't affect congfigurator that much! -printf 'Compiling %s...' "${CONFIGURATOR}" +printf 'Compiling %s...' "${CONFIGURATOR}" >&2 $CC ${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS $LDFLAGS -o $CONFIGURATOR $CONFIGURATOR.c -echo "done" +echo "done" >&2 if [ "$CLANG_COVERAGE" = "1" ]; then case "$CC" in (*"clang"*) ;; (*) - echo "Clang coverage requires building with CC=clang." + echo "Clang coverage requires building with CC=clang." >&2 exit 1 ;; esac @@ -401,7 +401,7 @@ if [ "$FUZZING" = "1" ]; then (*"clang"*) ;; (*) - echo "Fuzzing is currently only supported with clang." + echo "Fuzzing is currently only supported with clang." >&2 exit 1 ;; esac From 10d612b98849ef0481d2dcae284eb121dfc52c29 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Tue, 11 Aug 2026 10:13:14 -0400 Subject: [PATCH 03/17] configure: fix quoting mistake in setting DEFAULT_CWARNFLAGS in usage() The code intends to pass "$DEFAULT_COPTFLAGS" and "$DEBUGBUILD" as arguments $1 and $4 to default_cwarnflags(), but it had mistakenly doubled the double- quotes, which would have caused the values of those variables to be subjected to word splitting after substitution. Remove the extra double-quote marks. Changelog-None --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index a79e14dd910e..6ea01f0cb159 100755 --- a/configure +++ b/configure @@ -236,7 +236,7 @@ usage() set_defaults DEFAULT_COPTFLAGS="$(default_coptflags $DEBUGBUILD)" # We assume we have a modern gcc. - DEFAULT_CWARNFLAGS="$(default_cwarnflags ""$DEFAULT_COPTFLAGS"" 1 1 ""$DEBUGBUILD"")" + DEFAULT_CWARNFLAGS="$(default_cwarnflags "$DEFAULT_COPTFLAGS" 1 1 "$DEBUGBUILD")" usage_with_default "CC" "$CC" usage_with_default "CWARNFLAGS" "$DEFAULT_CWARNFLAGS" usage_with_default "COPTFLAGS" "$DEFAULT_COPTFLAGS" From 2a1ff8bad5143f063a910035d67398f207e315c8 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sun, 23 Aug 2026 20:31:23 -0400 Subject: [PATCH 04/17] Makefile: don't show config.vars on the LD line in show-flags This was apparently a copy-paste mistake. The example link command line shown by the 'show-flags' target shouldn't include $^ since 'show-flags' has no prerequisites that are actually object files or libraries. The inclusion of $^ was causing the example command line to contain "config.vars", which makes no sense. Remove the $^. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 20d4aedff053..cb5f2b824f9d 100644 --- a/Makefile +++ b/Makefile @@ -331,7 +331,7 @@ endif show-flags: config.vars @$(ECHO) "CC: $(CC) $(CFLAGS) -c -o" - @$(ECHO) "LD: $(LINK.o) $(filter-out %.a,$^) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) -o" + @$(ECHO) "LD: $(LINK.o) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) -o" # We will re-generate, but we won't generate for the first time! ccan/config.h config.vars &: configure ccan/tools/configurator/configurator.c From 8b659a3def672e26ebfbe994a6952e2e89e0efea Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Thu, 20 Aug 2026 12:33:55 -0400 Subject: [PATCH 05/17] build: allow overriding CFLAGS, CPPFLAGS, and LDFLAGS Pass these flags variables when building configurator and tests. Makefile now *prepends* its default CFLAGS, CPPFLAGS, and LDFLAGS to the environment-supplied flags. This allows the user to override individual flags by setting these variables through configure, without disturbing all the rest of the flags that Makefile wants by default. Changelog-None --- Makefile | 20 ++++++++++++-------- configure | 25 ++++++++++++++++--------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index cb5f2b824f9d..483a093d7203 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,14 @@ BOLTVERSION := $(DEFAULT_BOLTVERSION) -include config.vars +# Save flags inherited from environment (or config.vars) before we start munging them +CFLAGS_FROM_ENV := $(CFLAGS) +CFLAGS = +CPPFLAGS_FROM_ENV := $(CPPFLAGS) +CPPFLAGS = +LDFLAGS_FROM_ENV := $(LDFLAGS) +LDFLAGS = + # Use Homebrew LLVM toolchain for fuzzing support on macOS ifeq ($(OS),Darwin) export PATH := /opt/homebrew/opt/llvm/bin:$(PATH) @@ -289,8 +297,10 @@ PKG_CONFIG_PATH := $(SQLITE_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH) endif endif -CPPFLAGS += -DCLN_NEXT_VERSION="\"$(CLN_NEXT_VERSION)\"" -DPKGLIBEXECDIR="\"$(pkglibexecdir)\"" -DBINDIR="\"$(bindir)\"" -DPLUGINDIR="\"$(plugindir)\"" -DCCAN_TAL_NEVER_RETURN_NULL=1 -CFLAGS = $(CPPFLAGS) $(CWARNFLAGS) $(CDEBUGFLAGS) $(COPTFLAGS) -I $(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I . -I$(CPATH) $(SQLITE3_CFLAGS) $(SODIUM_CFLAGS) $(POSTGRES_INCLUDE) $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) -DSHACHAIN_BITS=48 -DJSMN_PARENT_LINKS $(PIE_CFLAGS) $(COMPAT_CFLAGS) $(CSANFLAGS) +# Put the environment-inherited flags *last* so the user has the final say. +CPPFLAGS += -DCLN_NEXT_VERSION="\"$(CLN_NEXT_VERSION)\"" -DPKGLIBEXECDIR="\"$(pkglibexecdir)\"" -DBINDIR="\"$(bindir)\"" -DPLUGINDIR="\"$(plugindir)\"" -DCCAN_TAL_NEVER_RETURN_NULL=1 $(CPPFLAGS_FROM_ENV) +CFLAGS = $(CPPFLAGS) $(CWARNFLAGS) $(CDEBUGFLAGS) $(COPTFLAGS) -I $(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I . -I$(CPATH) $(SQLITE3_CFLAGS) $(SODIUM_CFLAGS) $(POSTGRES_INCLUDE) $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) -DSHACHAIN_BITS=48 -DJSMN_PARENT_LINKS $(PIE_CFLAGS) $(COMPAT_CFLAGS) $(CSANFLAGS) $(CFLAGS_FROM_ENV) +LDFLAGS += $(PIE_LDFLAGS) $(CSANFLAGS) $(COPTFLAGS) $(LDFLAGS_FROM_ENV) # If CFLAGS is already set in the environment of make (to whatever value, it # does not matter) then it would export it to subprocesses with the above value @@ -302,8 +312,6 @@ unexport CFLAGS # We can get configurator to run a different compile cmd to cross-configure. CONFIGURATOR_CC := $(CC) -LDFLAGS += $(PIE_LDFLAGS) $(CSANFLAGS) $(COPTFLAGS) - ifeq ($(STATIC),1) # For MacOS, Jacob Rapoport changed this to: # -L/usr/local/lib -lsqlite3 -lz -Wl,-lm -lpthread -ldl $(COVFLAGS) @@ -313,10 +321,6 @@ else LDLIBS = -L$(CPATH) -lm $(SQLITE3_LDLIBS) $(COVFLAGS) endif -ifeq ($(HAVE_FUNCTION_SECTIONS),1) -LDLIBS += -Wl,--gc-sections -endif - # If we have the postgres client library we need to link against it as well ifeq ($(HAVE_POSTGRES),1) LDLIBS += $(POSTGRES_LDLIBS) diff --git a/configure b/configure index 6ea01f0cb159..036836d3f01a 100755 --- a/configure +++ b/configure @@ -241,6 +241,9 @@ usage() usage_with_default "CWARNFLAGS" "$DEFAULT_CWARNFLAGS" usage_with_default "COPTFLAGS" "$DEFAULT_COPTFLAGS" usage_with_default "CDEBUGFLAGS" "$CDEBUGFLAGS" + usage_with_default "CFLAGS" "$CFLAGS" + usage_with_default "CPPFLAGS" "$CPPFLAGS" + usage_with_default "LDFLAGS" "$LDFLAGS" if [ "$(uname -s)" = "Darwin" ]; then echo " Note: On macOS, -g is used instead of -g3 for libbacktrace compatibility" fi @@ -314,6 +317,9 @@ for opt in "$@"; do CWARNFLAGS=*) CWARNFLAGS="${opt#CWARNFLAGS=}";; CDEBUGFLAGS=*) CDEBUGFLAGS="${opt#CDEBUGFLAGS=}";; COPTFLAGS=*) COPTFLAGS="${opt#COPTFLAGS=}";; + CFLAGS=*) CFLAGS="${opt#CFLAGS=}";; + CPPFLAGS=*) CPPFLAGS="${opt#CPPFLAGS=}";; + LDFLAGS=*) LDFLAGS="${opt#LDFLAGS=}";; PYTEST=*) PYTEST="${opt#PYTEST=}";; --prefix=*) PREFIX="${opt#--prefix=}";; --enable-debugbuild) DEBUGBUILD=1;; @@ -371,18 +377,17 @@ EOF fi # We call this first, so we can make sure configurator runs with it as a sanity check! -if have_function_sections $CC "${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS"; then - HAVE_FUNCTION_SECTIONS=1 - LDFLAGS="-Wl,--gc-sections" +if have_function_sections $CC "${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS $CFLAGS $CPPFLAGS"; then + case "$LDFLAGS" in + *'--gc-sections'*) ;; + *) LDFLAGS="-Wl,--gc-sections $LDFLAGS";; + esac COPTFLAGS="$COPTFLAGS -ffunction-sections" -else - HAVE_FUNCTION_SECTIONS=0 - LDFLAGS= fi # We assume warning flags don't affect congfigurator that much! printf 'Compiling %s...' "${CONFIGURATOR}" >&2 -$CC ${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS $LDFLAGS -o $CONFIGURATOR $CONFIGURATOR.c +$CC ${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS $CFLAGS $CPPFLAGS $LDFLAGS -o $CONFIGURATOR $CONFIGURATOR.c echo "done" >&2 if [ "$CLANG_COVERAGE" = "1" ]; then @@ -432,7 +437,7 @@ fi # Clean up on exit. trap "rm -f $CONFIG_VAR_FILE.$$*" 0 -$CONFIGURATOR --extra-tests --autotools-style --var-file=$CONFIG_VAR_FILE.$$ --header-file=$CONFIG_HEADER.$$ --configurator-cc="$CONFIGURATOR_CC" --wrapper="$CONFIGURATOR_WRAPPER" "$CC" ${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS $CSANFLAGS -I$CPATH -L$LIBRARY_PATH $SQLITE3_CFLAGS $SODIUM_CFLAGS $POSTGRES_INCLUDE < Date: Sat, 7 Mar 2026 08:28:31 -0500 Subject: [PATCH 06/17] Makefile: use standard variables for compiling and linking C programs Make predefines variables COMPILE.c and LINK.c, providing the default commands for compiling and linking C programs: COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) Use these variables where appropriate. A few points of interest: * Using $(LINK.o) to link a C program is not correct, as it does not pass $(CFLAGS) to the linker driver. Passing $(CFLAGS) may be necessary for correct operation. For instance, -m32 can be specified in CFLAGS to build for a 32-bit ABI on a 64-bit-native system, and -flto can be specified in CFLAGS to enable link-time optimization. The linker driver needs to be told both of these in order to produce correct output. * CFLAGS is not supposed to subsume CPPFLAGS. The latter are logically the flags for the C preprocessor, while the former are the flags for the C compiler. The standard COMPILE.c variable incorporates both sets of flags since it invokes both the preprocessor and the compiler with one command. The standard LINK.c variable also incorporates both since it can be used to preprocess, compile, and link a C program all in one shot. In its more typical usage (linking precompiled object files), the linker driver accepts but makes no use of any preprocessor flags supplied to it. * CFLAGS logically shouldn't include any -D, -U, or -I options, as those are meant for the preprocessor and not the compiler. Move such flags to CPPFLAGS. Changelog-None --- Makefile | 124 ++++++++++++++++++++++++------------------------- tools/Makefile | 2 +- 2 files changed, 63 insertions(+), 63 deletions(-) diff --git a/Makefile b/Makefile index 483a093d7203..8c71df2683a6 100644 --- a/Makefile +++ b/Makefile @@ -298,9 +298,9 @@ endif endif # Put the environment-inherited flags *last* so the user has the final say. -CPPFLAGS += -DCLN_NEXT_VERSION="\"$(CLN_NEXT_VERSION)\"" -DPKGLIBEXECDIR="\"$(pkglibexecdir)\"" -DBINDIR="\"$(bindir)\"" -DPLUGINDIR="\"$(plugindir)\"" -DCCAN_TAL_NEVER_RETURN_NULL=1 $(CPPFLAGS_FROM_ENV) -CFLAGS = $(CPPFLAGS) $(CWARNFLAGS) $(CDEBUGFLAGS) $(COPTFLAGS) -I $(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I . -I$(CPATH) $(SQLITE3_CFLAGS) $(SODIUM_CFLAGS) $(POSTGRES_INCLUDE) $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) -DSHACHAIN_BITS=48 -DJSMN_PARENT_LINKS $(PIE_CFLAGS) $(COMPAT_CFLAGS) $(CSANFLAGS) $(CFLAGS_FROM_ENV) -LDFLAGS += $(PIE_LDFLAGS) $(CSANFLAGS) $(COPTFLAGS) $(LDFLAGS_FROM_ENV) +CPPFLAGS += -DCLN_NEXT_VERSION="\"$(CLN_NEXT_VERSION)\"" -DPKGLIBEXECDIR="\"$(pkglibexecdir)\"" -DBINDIR="\"$(bindir)\"" -DPLUGINDIR="\"$(plugindir)\"" -DCCAN_TAL_NEVER_RETURN_NULL=1 -I$(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I. -I$(CPATH) $(POSTGRES_INCLUDE) -DSHACHAIN_BITS=48 -DJSMN_PARENT_LINKS $(COMPAT_CFLAGS) $(CPPFLAGS_FROM_ENV) +CFLAGS = $(CWARNFLAGS) $(CDEBUGFLAGS) $(COPTFLAGS) $(SQLITE3_CFLAGS) $(SODIUM_CFLAGS) $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) $(PIE_CFLAGS) $(CSANFLAGS) $(CFLAGS_FROM_ENV) +LDFLAGS += $(PIE_LDFLAGS) $(LDFLAGS_FROM_ENV) # If CFLAGS is already set in the environment of make (to whatever value, it # does not matter) then it would export it to subprocesses with the above value @@ -334,8 +334,8 @@ FORCE: endif show-flags: config.vars - @$(ECHO) "CC: $(CC) $(CFLAGS) -c -o" - @$(ECHO) "LD: $(LINK.o) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) -o" + @$(ECHO) "CC: $(COMPILE.c) -o" + @$(ECHO) "LD: $(LINK.c) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) -o" # We will re-generate, but we won't generate for the first time! ccan/config.h config.vars &: configure ccan/tools/configurator/configurator.c @@ -343,7 +343,7 @@ ccan/config.h config.vars &: configure ccan/tools/configurator/configurator.c ./configure --reconfigure %.o: %.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) # tools/update-mocks.sh does nasty recursive make, must not do this! ifeq ($(SUPPRESS_GENERATION),1) @@ -802,7 +802,7 @@ $(ALL_TEST_PROGRAMS) $(ALL_FUZZ_TARGETS): %: %.o # (as per EXTERNAL_LDLIBS) so we filter them out here. We have to put the other # .a files (if any) at the end of the link line. $(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS): - @$(call VERBOSE, "ld $@", $(LINK.o) $(filter-out %.a,$^) $(filter-out external/%,$(filter %.a,$^)) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $($(@)_LDLIBS) -o $@) + @$(call VERBOSE, "ld $@", $(LINK.c) $(filter-out %.a,$^) $(filter-out external/%,$(filter %.a,$^)) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $($(@)_LDLIBS) -o $@) ifeq ($(OS),Darwin) @$(call VERBOSE, "dsymutil $@", dsymutil $@) endif @@ -823,7 +823,7 @@ endif endif $(ALL_FUZZ_TARGETS): - @$(call VERBOSE, "ld $@", $(LINK.o) $(filter-out %.a,$^) libcommon.a libccan.a $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $(FUZZ_LDFLAGS) -o $@) + @$(call VERBOSE, "ld $@", $(LINK.c) $(filter-out %.a,$^) libcommon.a libccan.a $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $(FUZZ_LDFLAGS) -o $@) ifeq ($(OS),Darwin) @$(call VERBOSE, "dsymutil $@", dsymutil $@) endif @@ -1089,113 +1089,113 @@ clightning-$(VERSION)-$(DISTRO).tar.xz: install endif ccan-breakpoint.o: $(CCANDIR)/ccan/breakpoint/breakpoint.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-base64.o: $(CCANDIR)/ccan/base64/base64.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-tal.o: $(CCANDIR)/ccan/tal/tal.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-tal-str.o: $(CCANDIR)/ccan/tal/str/str.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-tal-link.o: $(CCANDIR)/ccan/tal/link/link.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-tal-path.o: $(CCANDIR)/ccan/tal/path/path.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-tal-grab_file.o: $(CCANDIR)/ccan/tal/grab_file/grab_file.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-take.o: $(CCANDIR)/ccan/take/take.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-list.o: $(CCANDIR)/ccan/list/list.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-asort.o: $(CCANDIR)/ccan/asort/asort.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-ptr_valid.o: $(CCANDIR)/ccan/ptr_valid/ptr_valid.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-read_write_all.o: $(CCANDIR)/ccan/read_write_all/read_write_all.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-str.o: $(CCANDIR)/ccan/str/str.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-opt.o: $(CCANDIR)/ccan/opt/opt.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-opt-helpers.o: $(CCANDIR)/ccan/opt/helpers.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-opt-parse.o: $(CCANDIR)/ccan/opt/parse.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-opt-usage.o: $(CCANDIR)/ccan/opt/usage.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-err.o: $(CCANDIR)/ccan/err/err.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-noerr.o: $(CCANDIR)/ccan/noerr/noerr.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-str-hex.o: $(CCANDIR)/ccan/str/hex/hex.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-crc32c.o: $(CCANDIR)/ccan/crc32c/crc32c.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-crypto-hmac.o: $(CCANDIR)/ccan/crypto/hmac_sha256/hmac_sha256.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-crypto-hkdf.o: $(CCANDIR)/ccan/crypto/hkdf_sha256/hkdf_sha256.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-crypto-shachain.o: $(CCANDIR)/ccan/crypto/shachain/shachain.c - @$(call VERBOSE, "cc $< -DSHACHAIN_BITS=48", $(CC) $(CFLAGS) -DSHACHAIN_BITS=48 -c -o $@ $<) + @$(call VERBOSE, "cc $< -DSHACHAIN_BITS=48", $(COMPILE.c) -DSHACHAIN_BITS=48 -o $@ $<) ccan-crypto-sha256.o: $(CCANDIR)/ccan/crypto/sha256/sha256.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-crypto-ripemd160.o: $(CCANDIR)/ccan/crypto/ripemd160/ripemd160.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-cdump.o: $(CCANDIR)/ccan/cdump/cdump.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-strmap.o: $(CCANDIR)/ccan/strmap/strmap.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-strset.o: $(CCANDIR)/ccan/strset/strset.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-crypto-siphash24.o: $(CCANDIR)/ccan/crypto/siphash24/siphash24.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-htable.o: $(CCANDIR)/ccan/htable/htable.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-ilog.o: $(CCANDIR)/ccan/ilog/ilog.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-intmap.o: $(CCANDIR)/ccan/intmap/intmap.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-isaac.o: $(CCANDIR)/ccan/isaac/isaac.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-isaac64.o: $(CCANDIR)/ccan/isaac/isaac64.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-time.o: $(CCANDIR)/ccan/time/time.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-timer.o: $(CCANDIR)/ccan/timer/timer.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-io-io.o: $(CCANDIR)/ccan/io/io.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-io-poll.o: $(CCANDIR)/ccan/io/poll.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-io-fdpass.o: $(CCANDIR)/ccan/io/fdpass/fdpass.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-pipecmd.o: $(CCANDIR)/ccan/pipecmd/pipecmd.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-mem.o: $(CCANDIR)/ccan/mem/mem.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-fdpass.o: $(CCANDIR)/ccan/fdpass/fdpass.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-bitops.o: $(CCANDIR)/ccan/bitops/bitops.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-rbuf.o: $(CCANDIR)/ccan/rbuf/rbuf.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-str-base32.o: $(CCANDIR)/ccan/str/base32/base32.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-utf8.o: $(CCANDIR)/ccan/utf8/utf8.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-bitmap.o: $(CCANDIR)/ccan/bitmap/bitmap.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-membuf.o: $(CCANDIR)/ccan/membuf/membuf.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-json_escape.o: $(CCANDIR)/ccan/json_escape/json_escape.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-json_out.o: $(CCANDIR)/ccan/json_out/json_out.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-closefrom.o: $(CCANDIR)/ccan/closefrom/closefrom.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-rune-rune.o: $(CCANDIR)/ccan/rune/rune.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) ccan-rune-coding.o: $(CCANDIR)/ccan/rune/coding.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) + @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) canned-gossmap: devtools/gossmap-compress DATE=`date +%Y-%m-%d` && devtools/gossmap-compress compress --output-node-map /tmp/gossip_store tests/data/gossip-store-$$DATE.compressed > tests/data/gossip-store-$$DATE-node-map && xz -9 tests/data/gossip-store-$$DATE-node-map && ls -l tests/data/gossip-store-$$DATE* diff --git a/tools/Makefile b/tools/Makefile index 2d86221df962..4ffac102af94 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -11,7 +11,7 @@ ALL_PROGRAMS += $(TOOLS) # We force make to relink this every time, to detect version changes. # Do it atomically, otherwise parallel builds can get upset! tools/headerversions: $(FORCE) tools/headerversions.o libccan.a - @trap "rm -f $@.tmp.$$$$" EXIT; $(LINK.o) tools/headerversions.o libccan.a $(LOADLIBES) $(LDLIBS) -o $@.tmp.$$$$ && mv -f $@.tmp.$$$$ $@ + @trap "rm -f $@.tmp.$$$$" EXIT; $(LINK.c) tools/headerversions.o libccan.a $(LOADLIBES) $(LDLIBS) -o $@.tmp.$$$$ && mv -f $@.tmp.$$$$ $@ $(TOOLS): libcommon.a From f8e5b135c20cca762ea4eab16486fbff7d2cca11 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sat, 7 Mar 2026 11:18:51 -0500 Subject: [PATCH 07/17] build: move -std=gnu11 to CPPFLAGS It doesn't logically belong in CDEBUGFLAGS. Changelog-None --- configure | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 036836d3f01a..761974ad5d79 100755 --- a/configure +++ b/configure @@ -170,10 +170,14 @@ set_defaults() # which matters since you might explicitly set of these blank. PREFIX=${PREFIX:-/usr/local} CC=${CC:-cc} + # A more compact way of setting the default value of a variable. + # Similar to the above, ":=" means assign if empty or unset; "=" means assign only if unset. + # The quotes suppress the globbing that would otherwise occur after variable expansion. + : "${CPPFLAGS=-std=gnu11}" # Detect macOS and use appropriate debug flags for libbacktrace compatibility if [ "$(uname -s)" = "Darwin" ]; then # Always override to avoid DWARF 5 - CDEBUGFLAGS="-std=gnu11 -g -gdwarf-4 -fno-standalone-debug -fstack-protector-strong" + CDEBUGFLAGS="-g -gdwarf-4 -fno-standalone-debug -fstack-protector-strong" # Set SDKROOT for macOS SDKROOT="$(xcrun --sdk macosx --show-sdk-path)" @@ -182,7 +186,7 @@ set_defaults() echo "Warning: dsymutil not found. Install Xcode Command Line Tools for better debug support." fi else - CDEBUGFLAGS=${CDEBUGFLAGS--std=gnu11 -g -fstack-protector-strong} + CDEBUGFLAGS=${CDEBUGFLAGS--g -fstack-protector-strong} fi DEBUGBUILD=${DEBUGBUILD:-0} COMPAT=${COMPAT:-1} From 4e29b7ea03a9d4afce8f77ad7657299ca69f164c Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Wed, 12 Aug 2026 01:07:40 -0400 Subject: [PATCH 08/17] configure: fix have_function_sections test Since we're linking a standalone program, we have to define main(). Changelog-None --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 761974ad5d79..f295258b7880 100755 --- a/configure +++ b/configure @@ -227,7 +227,7 @@ have_function_sections() TMPCFILE=$CONFIG_VAR_FILE.$$.c TMPOBJFILE=$CONFIG_VAR_FILE.$$.o - echo "int foo(void); int foo(void) { return 0; }" > $TMPCFILE + echo "int main(void); int main(void) { return 0; }" > $TMPCFILE # We *want* this to fail if we get a warning, hence use -Werror. $1 $2 -Werror -ffunction-sections -Wl,--gc-sections $TMPCFILE -o $TMPOBJFILE } From 26df57f6eb76b3b64fc3d328ff58eac9b87fedbb Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sat, 22 Aug 2026 17:09:34 -0400 Subject: [PATCH 09/17] fix two libwally-core #includes libwally-core's headers directory is present in the include search path, so its headers should not be included as #include but rather as #include . This matters when building CLN against a system-installed libwally-core, as the bundled copy in external/libwally-core might be absent. Changelog-None --- common/test/run-close_tx.c | 2 +- lightningd/test/run-close_tx_check.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/test/run-close_tx.c b/common/test/run-close_tx.c index 42a1cea40f76..f5196d0817ac 100644 --- a/common/test/run-close_tx.c +++ b/common/test/run-close_tx.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include static void test_create_simple_close_tx_basic(void) diff --git a/lightningd/test/run-close_tx_check.c b/lightningd/test/run-close_tx_check.c index 9b132647bc64..2ef9ff64551a 100644 --- a/lightningd/test/run-close_tx_check.c +++ b/lightningd/test/run-close_tx_check.c @@ -2,7 +2,7 @@ #include "../simple_close_control.c" #include #include -#include +#include #include /* AUTOGENERATED MOCKS START */ From baa1ce2ceb66c5d3977ec5e6c50b68fb10963c5f Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sun, 23 Aug 2026 16:54:23 -0400 Subject: [PATCH 10/17] build: manage installation targets with Make individually Rather than installing all build products monolithically, we can leverage Make's timestamp testing to update only the installed targets whose sources have been modified since the previous install. * Rather than doing 'for' loops in the shell to install build products, use Make's 'foreach' and 'eval' functions to define an explicit rule for each individual installation target file. Then these targets can be listed as prerequisites of the phony 'install-*' targets. * Specify the installation directories as order-only prerequisites of the targets that install into them. This way, Make will create these directories before installing into them only if they do not already exist. * As a happy side effect of letting Make decide which installation targets need to be installed, the user can now disable installation of certain targets just by clearing the source list variables (e.g., MANPAGES, DOC_DATA) on the 'make' command line. Previously, that would cause errors because Make would try to invoke $(INSTALL_DATA) with an empty list of source files. * The Python plugins $(PY_PLUGINS) (of which there are currently none) are handled specially since their entire containing directory needs to be installed. For each distinct directory containing any files listed in $(PY_PLUGINS), define a rule that touches the directory whenever it is older than any listed file contained within it. This ensures that the whole plugin directory will be re-installed whenever any plugin source file within it has changed. * Split the 'uninstall' target into 'uninstall-programs' and 'uninstall-data' to mirror the 'install' target. * Now that we have explicit lists of the installation target files, uninstallation is made simpler, becoming a single '$(RM) -r' command rather than numerous shell 'for' loops. * When uninstalling, also remove the installation target directories if the uninstallation vacated them. Changelog-None --- Makefile | 138 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 76 insertions(+), 62 deletions(-) diff --git a/Makefile b/Makefile index 8c71df2683a6..53acd756303a 100644 --- a/Makefile +++ b/Makefile @@ -342,6 +342,9 @@ ccan/config.h config.vars &: configure ccan/tools/configurator/configurator.c @if [ ! -f config.vars ]; then echo 'File config.vars not found: you must run ./configure before running make.' >&2; exit 1; fi ./configure --reconfigure +%/: + @$(MKDIR_P) $(@D) + %.o: %.c @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) @@ -950,10 +953,44 @@ fuzzunittest/%: % bolt-precheck # Commands MKDIR_P = mkdir -p +RMDIR_P = rmdir -p +CP_A = cp -a INSTALL = install INSTALL_PROGRAM = $(INSTALL) INSTALL_DATA = $(INSTALL) -m 644 +# $(1) = install command +# $(2) = installation source file +# $(3) = installation target file +define INSTALL_RULE_tmpl = +$(3): $(2) | $(dir $(3)) + @$$(call VERBOSE,"install $$@",$(1) $$< $$|) +endef + +# $(1) = install command +# $(2) = list of files to install to $(3) +# $(3) = installation target directory +install_targets = $(foreach f,$(2),$(let t,$(3)/$(notdir $(f)),$(eval $(call INSTALL_RULE_tmpl,$(1),$(f),$(t)))$(t))) + +# $(1) = list of files to install to $(2) +# $(2) = installation target directory +install_program_targets = $(call install_targets,$(INSTALL_PROGRAM),$(1),$(2)) +install_data_targets = $(call install_targets,$(INSTALL_DATA),$(1),$(2)) + +# Defines a rule that touches $(1) whenever it is older than any file listed in $(2). +define TOUCH_RULE_tmpl = +$(1): $(2) + @touch $(1) +endef + +# $(1) = list of files whose containing directories are to be installed to $(2) +# $(2) = installation target directory +# An installation target rule is defined for each distinct directory containing +# any file listed in $(1). A containing directory will be touched whenever any +# listed contained file is newer than it. The touched directory then will +# trigger a re-installation of the whole directory. +install_py_plugin_targets = $(foreach d,$(sort $(dir $(1))),$(let t,$(2)/$(notdir $(patsubst %/,%,$(d))),$(eval $(call TOUCH_RULE_tmpl,$(d),$(filter $(d)%,$(1))))$(eval $(call INSTALL_RULE_tmpl,$(RM) -r $$@ && $(CP_A),$(d),$(t)))$(t))) + # Tags needed by some package systems. PRE_INSTALL = : NORMAL_INSTALL = : @@ -962,28 +999,26 @@ PRE_UNINSTALL = : NORMAL_UNINSTALL = : POST_UNINSTALL = : -# Target to create directories. -installdirs: - @$(NORMAL_INSTALL) - $(MKDIR_P) $(DESTDIR)$(bindir) - $(MKDIR_P) $(DESTDIR)$(pkglibexecdir) - $(MKDIR_P) $(DESTDIR)$(plugindir) - $(MKDIR_P) $(DESTDIR)$(man1dir) - $(MKDIR_P) $(DESTDIR)$(man5dir) - $(MKDIR_P) $(DESTDIR)$(man7dir) - $(MKDIR_P) $(DESTDIR)$(man8dir) - $(MKDIR_P) $(DESTDIR)$(docdir) +$(DESTDIR)$(plugindir)/clnrest: uninstall-old-clnrest-plugin +uninstall-old-clnrest-plugin: + @[ -d $(DESTDIR)$(plugindir)/clnrest ] && $(RM) -r $(DESTDIR)$(plugindir)/clnrest + +$(DESTDIR)$(plugindir)/wss-proxy: uninstall-old-wss-proxy-plugin +uninstall-old-wss-proxy-plugin: + @[ -d $(DESTDIR)$(plugindir)/wss-proxy ] && $(RM) -r $(DESTDIR)$(plugindir)/wss-proxy + +.PHONY: uninstall-old-clnrest-plugin uninstall-old-wss-proxy-plugin # $(PLUGINS) is defined in plugins/Makefile. -install-program: installdirs $(BIN_PROGRAMS) $(PKGLIBEXEC_PROGRAMS) $(PLUGINS) $(PY_PLUGINS) +INSTALL_PROGRAM_TARGETS := \ + $(call install_program_targets,$(BIN_PROGRAMS),$(DESTDIR)$(bindir)) \ + $(call install_program_targets,$(PKGLIBEXEC_PROGRAMS),$(DESTDIR)$(pkglibexecdir)) \ + $(call install_program_targets,$(PLUGINS),$(DESTDIR)$(plugindir)) \ + $(call install_py_plugin_targets,$(PY_PLUGINS),$(DESTDIR)$(plugindir)) + +install-program: $(INSTALL_PROGRAM_TARGETS) @$(NORMAL_INSTALL) - $(INSTALL_PROGRAM) $(BIN_PROGRAMS) $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) $(PKGLIBEXEC_PROGRAMS) $(DESTDIR)$(pkglibexecdir) - @if [ -d "$(DESTDIR)$(plugindir)/clnrest" ]; then rm -rf $(DESTDIR)$(plugindir)/clnrest; fi - @if [ -d "$(DESTDIR)$(plugindir)/wss-proxy" ]; then rm -rf $(DESTDIR)$(plugindir)/wss-proxy; fi - [ -z "$(PLUGINS)" ] || $(INSTALL_PROGRAM) $(PLUGINS) $(DESTDIR)$(plugindir) - for PY in $(PY_PLUGINS); do DIR=`dirname $$PY`; DST=$(DESTDIR)$(plugindir)/`basename $$DIR`; if [ -d $$DST ]; then rm -rf $$DST; fi; $(INSTALL_PROGRAM) -d $$DIR; cp -a $$DIR $$DST ; done ifeq ($(OS),Darwin) # Install dSYM bundles alongside binaries on macOS for BIN in $(BIN_PROGRAMS); do if [ -d $$BIN.dSYM ]; then cp -a $$BIN.dSYM $(DESTDIR)$(bindir)/; fi; done @@ -997,13 +1032,15 @@ MAN7PAGES = $(filter %.7,$(MANPAGES)) MAN8PAGES = $(filter %.8,$(MANPAGES)) DOC_DATA = README.md LICENSE -install-data: installdirs $(MAN1PAGES) $(MAN5PAGES) $(MAN7PAGES) $(MAN8PAGES) $(DOC_DATA) +INSTALL_DATA_TARGETS := \ + $(call install_data_targets,$(MAN1PAGES),$(DESTDIR)$(man1dir)) \ + $(call install_data_targets,$(MAN5PAGES),$(DESTDIR)$(man5dir)) \ + $(call install_data_targets,$(MAN7PAGES),$(DESTDIR)$(man7dir)) \ + $(call install_data_targets,$(MAN8PAGES),$(DESTDIR)$(man8dir)) \ + $(call install_data_targets,$(DOC_DATA),$(DESTDIR)$(docdir)) + +install-data: $(INSTALL_DATA_TARGETS) @$(NORMAL_INSTALL) - $(INSTALL_DATA) $(MAN1PAGES) $(DESTDIR)$(man1dir) - $(INSTALL_DATA) $(MAN5PAGES) $(DESTDIR)$(man5dir) - $(INSTALL_DATA) $(MAN7PAGES) $(DESTDIR)$(man7dir) - $(INSTALL_DATA) $(MAN8PAGES) $(DESTDIR)$(man8dir) - $(INSTALL_DATA) $(DOC_DATA) $(DESTDIR)$(docdir) install: install-program install-data @@ -1023,44 +1060,21 @@ TESTPACK_EXTRAS := \ testpack.tar.gz: all-programs all-fuzz-programs all-test-programs default-targets (find * -path external -prune -o -path target -prune -o -newer config.vars -type f -print; ls $(TESTPACK_EXTRAS)) | tar --verbatim-files-from -T- -c --format=posix -f - | gzip -5 > $@ -uninstall: +uninstall-program: @$(NORMAL_UNINSTALL) - @for f in $(BIN_PROGRAMS); do \ - $(ECHO) rm -f $(DESTDIR)$(bindir)/`basename $$f`; \ - rm -f $(DESTDIR)$(bindir)/`basename $$f`; \ - done - @for f in $(PLUGINS); do \ - $(ECHO) rm -f $(DESTDIR)$(plugindir)/`basename $$f`; \ - rm -f $(DESTDIR)$(plugindir)/`basename $$f`; \ - done - @for f in $(PY_PLUGINS); do \ - $(ECHO) rm -rf $(DESTDIR)$(plugindir)/$$(basename $$(dirname $$f)); \ - rm -rf $(DESTDIR)$(plugindir)/$$(basename $$(dirname $$f)); \ - done - @for f in $(PKGLIBEXEC_PROGRAMS); do \ - $(ECHO) rm -f $(DESTDIR)$(pkglibexecdir)/`basename $$f`; \ - rm -f $(DESTDIR)$(pkglibexecdir)/`basename $$f`; \ - done - @for f in $(MAN1PAGES); do \ - $(ECHO) rm -f $(DESTDIR)$(man1dir)/`basename $$f`; \ - rm -f $(DESTDIR)$(man1dir)/`basename $$f`; \ - done - @for f in $(MAN5PAGES); do \ - $(ECHO) rm -f $(DESTDIR)$(man5dir)/`basename $$f`; \ - rm -f $(DESTDIR)$(man5dir)/`basename $$f`; \ - done - @for f in $(MAN7PAGES); do \ - $(ECHO) rm -f $(DESTDIR)$(man7dir)/`basename $$f`; \ - rm -f $(DESTDIR)$(man7dir)/`basename $$f`; \ - done - @for f in $(MAN8PAGES); do \ - $(ECHO) rm -f $(DESTDIR)$(man8dir)/`basename $$f`; \ - rm -f $(DESTDIR)$(man8dir)/`basename $$f`; \ - done - @for f in $(DOC_DATA); do \ - $(ECHO) rm -f $(DESTDIR)$(docdir)/`basename $$f`; \ - rm -f $(DESTDIR)$(docdir)/`basename $$f`; \ - done +ifneq ($(strip $(INSTALL_PROGRAM_TARGETS)),) + $(RM) -r $(INSTALL_PROGRAM_TARGETS) + $(RMDIR_P) $(sort $(dir $(INSTALL_PROGRAM_TARGETS))) 2>/dev/null || : +endif + +uninstall-data: + @$(NORMAL_UNINSTALL) +ifneq ($(strip $(INSTALL_DATA_TARGETS)),) + $(RM) -r $(INSTALL_DATA_TARGETS) + $(RMDIR_P) $(sort $(dir $(INSTALL_DATA_TARGETS))) 2>/dev/null || : +endif + +uninstall: uninstall-program uninstall-data installcheck: all-programs @rm -rf testinstall || true @@ -1076,7 +1090,7 @@ installcheck: all-programs version: @echo ${VERSION} -.PHONY: installdirs install-program install-data install uninstall \ +.PHONY: install-program install-data install uninstall-program uninstall-data uninstall \ installcheck ncc bin-tarball show-flags version # Make a tarball of opt/clightning/, optionally with label for distribution. From 271810b30568caadc224b12aeac79107a1ca46d5 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sun, 23 Aug 2026 21:18:34 -0400 Subject: [PATCH 11/17] configure: allow overriding library flags via environment vars Appropriate preprocessor and linker flags for libsodium, libsqlite3, and libpq (PostgreSQL client) are normally looked up automagically via pkg-config and pg_config, but advanced users may wish to override them. * For libsodium, disable automagic detection when SODIUM_CFLAGS and/or SODIUM_LDLIBS is set in the environment (even to an empty string). * For libsqlite3, disable automagic detection when SQLITE3_CFLAGS and/or SQLITE3_LDLIBS is set in the environment (even to an empty string). * For libpq, disable automagic detection when POSTGRES_INCLUDE and/or POSTGRES_LDLIBS is set in the environment (even to an empty string). Changelog-None --- configure | 63 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/configure b/configure index f295258b7880..91283bc5708d 100755 --- a/configure +++ b/configure @@ -20,14 +20,19 @@ LIBRARY_PATH=/usr/local/lib export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/usr/local/opt/sqlite/lib/pkgconfig fi -: ${PKG_CONFIG=pkg-config} - -# You can set PG_CONFIG in the environment to direct configure to call -# a specific 'pg_config' binary. If you set it to an empty string, then -# PostgreSQL support will be explicitly disabled, even if a 'pg_config' -# binary exists in your PATH. If you leave it unset, then the following -# line enables the automagic detection that most users want. -: ${PG_CONFIG=pg_config} +: "${PKG_CONFIG=pkg-config}" + +# You can set PG_CONFIG in the environment to direct configure to call a +# specific 'pg_config' binary. If you set it to an empty string, then automagic +# detection of PostgreSQL will be explicitly disabled even if a 'pg_config' +# binary exists in your PATH. However, fallback detection will still happen. +# You can disable PostgreSQL support entirely by setting POSTGRES_LDLIBS to an +# empty string, or you can set POSTGRES_INCLUDE and POSTGRES_LDLIBS (which +# specify options to pass to the C preprocessor and linker respectively) to +# attempt to build against a specific PostgreSQL installation. If you leave +# all three variables unset, then the following line enables the automagic +# detection that most users want. +: "${PG_CONFIG=pg_config}" usage_with_default() { @@ -417,25 +422,37 @@ if [ "$FUZZING" = "1" ]; then fi -SQLITE3_CFLAGS="" -SQLITE3_LDLIBS="-lsqlite3" -if command -v "${PKG_CONFIG}" >/dev/null; then - SQLITE3_CFLAGS="$("${PKG_CONFIG}" --silence-errors --cflags sqlite3 || :)" - SQLITE3_LDLIBS="$("${PKG_CONFIG}" --silence-errors --libs sqlite3 || :)" +# Setting SQLITE3_CFLAGS or SQLITE3_LDLIBS in the environment (even to an empty +# string) disables automagic detection via pkg-config as well as the fallback +# default values. +if [ -z "${SQLITE3_CFLAGS+x}" -a -z "${SQLITE3_LDLIBS+x}" ]; then + SQLITE3_LDLIBS="-lsqlite3" + if command -v "${PKG_CONFIG}" >/dev/null; then + SQLITE3_CFLAGS="$("${PKG_CONFIG}" --silence-errors --cflags sqlite3 || :)" + SQLITE3_LDLIBS="$("${PKG_CONFIG}" --silence-errors --libs sqlite3 || :)" + fi fi -SODIUM_CFLAGS="" -SODIUM_LDLIBS="-lsodium" -if command -v "${PKG_CONFIG}" >/dev/null; then - SODIUM_CFLAGS="$("${PKG_CONFIG}" --silence-errors --cflags libsodium || :)" - SODIUM_LDLIBS="$("${PKG_CONFIG}" --silence-errors --libs libsodium || :)" +# Setting SODIUM_CFLAGS or SODIUM_LDLIBS in the environment (even to an empty +# string) disables automagic detection via pkg-config as well as the fallback +# default values. +if [ -z "${SODIUM_CFLAGS+x}" -a -z "${SODIUM_LDLIBS+x}" ]; then + SODIUM_LDLIBS="-lsodium" + if command -v "${PKG_CONFIG}" >/dev/null; then + SODIUM_CFLAGS="$("${PKG_CONFIG}" --silence-errors --cflags libsodium || :)" + SODIUM_LDLIBS="$("${PKG_CONFIG}" --silence-errors --libs libsodium || :)" + fi fi -POSTGRES_INCLUDE="" -POSTGRES_LDLIBS="" -if command -v "${PG_CONFIG}" >/dev/null; then - POSTGRES_INCLUDE="-I$("${PG_CONFIG}" --includedir)" - POSTGRES_LDLIBS="-L$("${PG_CONFIG}" --libdir) -lpq" +# Setting POSTGRES_INCLUDE or POSTGRES_LDLIBS in the environment (even to an +# empty string) disables automagic detection via pg_config as well as the +# fallback default values. +if [ -z "${POSTGRES_INCLUDE+x}" -a -z "${POSTGRES_LDLIBS+x}" ]; then + POSTGRES_LDLIBS="-lpq" + if command -v "${PG_CONFIG}" >/dev/null; then + POSTGRES_INCLUDE="-I$("${PG_CONFIG}" --includedir)" + POSTGRES_LDLIBS="-L$("${PG_CONFIG}" --libdir) -lpq" + fi fi # Clean up on exit. From a4c6713d0ded29e30aa03c178df34d9a5f449165 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Mon, 24 Aug 2026 04:04:16 -0400 Subject: [PATCH 12/17] ccan: update configurator and ptr_valid to latest See: https://github.com/rustyrussell/ccan/pull/135 Changelog-None --- ccan/ccan/ptr_valid/ptr_valid.c | 38 +- ccan/ccan/ptr_valid/ptr_valid.h | 1 + ccan/ccan/ptr_valid/test/run-batch-cache.c | 41 + ccan/ccan/ptr_valid/test/run-child-flush.c | 75 ++ ccan/ccan/ptr_valid/test/run-errno.c | 44 ++ ccan/ccan/ptr_valid/test/run-realloc-leak.c | 131 ++++ ccan/tools/configurator/configurator.c | 783 ++++++++++---------- 7 files changed, 696 insertions(+), 417 deletions(-) create mode 100644 ccan/ccan/ptr_valid/test/run-batch-cache.c create mode 100644 ccan/ccan/ptr_valid/test/run-child-flush.c create mode 100644 ccan/ccan/ptr_valid/test/run-errno.c create mode 100644 ccan/ccan/ptr_valid/test/run-realloc-leak.c diff --git a/ccan/ccan/ptr_valid/ptr_valid.c b/ccan/ccan/ptr_valid/ptr_valid.c index 7931984023ce..ccde627be8a8 100644 --- a/ccan/ccan/ptr_valid/ptr_valid.c +++ b/ccan/ccan/ptr_valid/ptr_valid.c @@ -10,7 +10,7 @@ #include #include -#if HAVE_PROC_SELF_MAPS +#if !defined(HAVE_PROC_SELF_MAPS) || HAVE_PROC_SELF_MAPS static char *grab(const char *filename) { int ret, fd; @@ -28,9 +28,10 @@ static char *grab(const char *filename) while ((ret = read(fd, buffer + s, max - s)) > 0) { s += ret; if (s == max) { - buffer = realloc(buffer, max*2+1); - if (!buffer) - goto close; + char *nb = realloc(buffer, max*2+1); + if (!nb) + goto free; + buffer = nb; max *= 2; } } @@ -62,10 +63,14 @@ static struct ptr_valid_map *add_map(struct ptr_valid_map *map, unsigned long start, unsigned long end, bool is_write) { if (*num == *max) { + struct ptr_valid_map *newmap; *max *= 2; - map = realloc(map, sizeof(*map) * *max); - if (!map) + newmap = realloc(map, sizeof(*newmap) * *max); + if (!newmap) { + free(map); return NULL; + } + map = newmap; } map[*num].start = (void *)start; map[*num].end = (void *)end; @@ -182,9 +187,9 @@ static void run_child(int infd, int outfd) /* This is weird. */ if (read(infd, &size, sizeof(size)) != sizeof(size)) - exit(1); + _exit(1); if (read(infd, &is_write, sizeof(is_write)) != sizeof(is_write)) - exit(2); + _exit(2); for (i = 0; i < size; i++) { ret = p[i]; @@ -194,9 +199,9 @@ static void run_child(int infd, int outfd) /* If we're still here, the answer is "yes". */ if (write(outfd, &ret, 1) != 1) - exit(3); + _exit(3); } - exit(0); + _exit(0); } static bool create_child(struct ptr_valid_batch *batch) @@ -271,16 +276,22 @@ bool ptr_valid_batch(struct ptr_valid_batch *batch, char *start, *end; bool ret; - if ((intptr_t)p & (alignment - 1)) + if ((intptr_t)p & (alignment - 1)) { + errno = EFAULT; return false; + } start = (void *)((intptr_t)p & ~(getpagesize() - 1)); end = (void *)(((intptr_t)p + size - 1) & ~(getpagesize() - 1)); /* We cache single page hits. */ if (start == end) { - if (batch->last && batch->last == start) + if (batch->last && batch->last == start + && batch->last_write == write) { + if (!batch->last_ok) + errno = EFAULT; return batch->last_ok; + } } if (batch->num_maps) @@ -291,8 +302,11 @@ bool ptr_valid_batch(struct ptr_valid_batch *batch, if (start == end) { batch->last = start; batch->last_ok = ret; + batch->last_write = write; } + if (!ret) + errno = EFAULT; return ret; } diff --git a/ccan/ccan/ptr_valid/ptr_valid.h b/ccan/ccan/ptr_valid/ptr_valid.h index 3871cad8e7e4..ad9a2e9c7c3b 100644 --- a/ccan/ccan/ptr_valid/ptr_valid.h +++ b/ccan/ccan/ptr_valid/ptr_valid.h @@ -80,6 +80,7 @@ struct ptr_valid_batch { int to_child, from_child; void *last; bool last_ok; + bool last_write; }; /** diff --git a/ccan/ccan/ptr_valid/test/run-batch-cache.c b/ccan/ccan/ptr_valid/test/run-batch-cache.c new file mode 100644 index 000000000000..7f6a9b2bdf8a --- /dev/null +++ b/ccan/ccan/ptr_valid/test/run-batch-cache.c @@ -0,0 +1,41 @@ +/* Regression test: ptr_valid_batch()'s single-page cache ignores the + * read/write flag. On a read-only page, a cached read result makes + * ptr_valid_batch_write() claim the page is writable (and a cached + * write failure makes ptr_valid_batch_read() claim it is unreadable). + * Currently fails: not ok 2 and not ok 4. */ +#include +#include +/* Include the C files directly. */ +#include +#include +#include +#include + +int main(void) +{ + char *page; + struct ptr_valid_batch batch; + + plan_tests(4); + alarm(10); + + page = mmap(NULL, getpagesize(), PROT_READ, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + if (page == MAP_FAILED) + plan_skip_all("mmap failed"); + + /* A cached read hit must not validate a write on the same page. */ + ptr_valid_batch_start(&batch); + ok1(ptr_valid_batch_read(&batch, page)); + ok1(!ptr_valid_batch_write(&batch, page)); + ptr_valid_batch_end(&batch); + + /* A cached write miss must not invalidate a read either. */ + ptr_valid_batch_start(&batch); + ok1(!ptr_valid_batch_write(&batch, page)); + ok1(ptr_valid_batch_read(&batch, page)); + ptr_valid_batch_end(&batch); + + munmap(page, getpagesize()); + return exit_status(); +} diff --git a/ccan/ccan/ptr_valid/test/run-child-flush.c b/ccan/ccan/ptr_valid/test/run-child-flush.c new file mode 100644 index 000000000000..12507dafc6b1 --- /dev/null +++ b/ccan/ccan/ptr_valid/test/run-child-flush.c @@ -0,0 +1,75 @@ +/* Regression test: run_child() exits via exit() instead of _exit(), + * so in the no-/proc/self/maps fallback (containers/chroots without + * /proc) the child flushes stdio buffers it inherited from the parent + * a second time. We force the fallback by undefining + * HAVE_PROC_SELF_MAPS (same code path as /proc being unavailable). + * Currently fails: not ok 2. */ +#include +#include +#undef HAVE_PROC_SELF_MAPS +#define HAVE_PROC_SELF_MAPS 0 +/* Include the C files directly. */ +#include +#include +#include +#include +#include + +#if defined(__has_include) +#if __has_include() +#include +#define HAVE_VALGRIND_H 1 +#endif +#endif + +int main(void) +{ + char tmpl[] = "/tmp/ptr_valid-flush-XXXXXX"; + char *page; + int fd; + FILE *f; + long len; + +#ifdef HAVE_VALGRIND_H + /* valgrind's own child-exit path flushes the inherited buffer, + * masking the module's behavior. */ + if (RUNNING_ON_VALGRIND) { + plan_skip_all("valgrind perturbs stdio across fork"); + return exit_status(); + } +#endif + + plan_tests(2); + alarm(10); + + fd = mkstemp(tmpl); + if (fd < 0) + plan_skip_all("mkstemp failed"); + f = fdopen(fd, "w"); + if (!f) + plan_skip_all("fdopen failed"); + unlink(tmpl); + + /* Fully buffered stream with pending data at fork time. */ + setvbuf(f, NULL, _IOFBF, 4096); + fwrite("unflushed-data", 1, 14, f); + + page = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + if (page == MAP_FAILED) + plan_skip_all("mmap failed"); + + /* Creates the probing child; ptr_valid_batch_end() closes the + * pipe, the child sees EOF and calls exit(0), flushing its + * inherited copy of f's buffer. */ + ok1(ptr_valid_read(page)); + + /* The parent now flushes its own copy. */ + fflush(f); + len = ftell(f); + fclose(f); + munmap(page, getpagesize()); + + ok1(len == 14); + return exit_status(); +} diff --git a/ccan/ccan/ptr_valid/test/run-errno.c b/ccan/ccan/ptr_valid/test/run-errno.c new file mode 100644 index 000000000000..1c2fd4f4f4cd --- /dev/null +++ b/ccan/ccan/ptr_valid/test/run-errno.c @@ -0,0 +1,44 @@ +/* Regression test: ptr_valid.h documents "Sets errno to EFAULT on + * failure", but the /proc/self/maps path and the alignment check + * return false without setting errno. Currently fails all 3 tests. */ +#include +#include +/* Include the C files directly. */ +#include +#include +#include +#include +#include + +int main(void) +{ + char *page; + + plan_tests(3); + alarm(10); + + page = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + if (page == MAP_FAILED) + plan_skip_all("mmap failed"); + munmap(page, getpagesize()); + + /* Unmapped pointer (maps path). */ + errno = 0; + ok1(!ptr_valid_read(page) && errno == EFAULT); + + /* Misaligned pointer. */ + errno = 0; + ok1(!ptr_valid(page + 1, getpagesize(), 1, false) && errno == EFAULT); + + /* Read-only page, write check (maps path). */ + page = mmap(NULL, getpagesize(), PROT_READ, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + if (page == MAP_FAILED) + plan_skip_all("mmap failed"); + errno = 0; + ok1(!ptr_valid_write(page) && errno == EFAULT); + munmap(page, getpagesize()); + + return exit_status(); +} diff --git a/ccan/ccan/ptr_valid/test/run-realloc-leak.c b/ccan/ccan/ptr_valid/test/run-realloc-leak.c new file mode 100644 index 000000000000..a91a8fe7c232 --- /dev/null +++ b/ccan/ccan/ptr_valid/test/run-realloc-leak.c @@ -0,0 +1,131 @@ +/* Regression test: grab() and add_map() overwrite their pointer with + * realloc()'s return value, so a failed realloc leaks the old buffer. + * We interpose malloc/realloc/free by macro (this file includes + * ptr_valid.c directly) and inject a failure at each growth call. + * Currently fails: not ok 1 and not ok 2. */ +#include +#include +#include + +static void *live[64]; +static unsigned int nlive; +static size_t fail_realloc_size; + +static void track(void *p) +{ + if (p && nlive < sizeof(live)/sizeof(live[0])) + live[nlive++] = p; +} + +static void untrack(void *p) +{ + unsigned int i; + + for (i = 0; i < nlive; i++) { + if (live[i] == p) { + live[i] = live[--nlive]; + return; + } + } +} + +static void *my_malloc(size_t size) +{ + void *p; +#undef malloc + p = malloc(size); +#define malloc my_malloc + track(p); + return p; +} + +static void *my_realloc(void *old, size_t size) +{ + void *p; + uintptr_t o = (uintptr_t)old; + + if (fail_realloc_size && size == fail_realloc_size) + return NULL; +#undef realloc + p = realloc(old, size); +#define realloc my_realloc + if (p) { + untrack((void *)o); + track(p); + } + return p; +} + +static void my_free(void *p) +{ + if (p) + untrack(p); +#undef free + free(p); +#define free my_free +} + +#define malloc my_malloc +#define realloc my_realloc +#define free my_free +/* Include the C files directly. */ +#include +#undef malloc +#undef realloc +#undef free + +#include +#include +#include + +int main(void) +{ + char *region; + int i; + struct ptr_valid_batch batch; + + alarm(20); + + /* Silence "defined but not used" when ptr_valid.c's + * HAVE_PROC_SELF_MAPS-less build calls no malloc at all. */ + (void)my_malloc; + (void)my_realloc; + (void)my_free; + + /* Split a 1000-page mapping into alternating RO/RW VMAs so + * /proc/self/maps exceeds grab()'s initial 16k buffer and has + * more entries than add_map()'s initial 16 slots. + * + * Must resolve this (and plan accordingly) before the single + * plan_tests()/plan_skip_all() call tap allows. */ + region = mmap(NULL, 1000 * 4096, PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + if (region == MAP_FAILED) { + plan_skip_all("mmap failed"); + return exit_status(); + } + for (i = 0; i < 1000; i += 2) + if (mprotect(region + i * 4096, 4096, PROT_READ) != 0) { + plan_skip_all("mprotect failed"); + return exit_status(); + } + + plan_tests(2); + + /* grab(): fail the 16384 -> 32768 buffer growth. */ + fail_realloc_size = 32768 + 1; + nlive = 0; + ptr_valid_batch_start(&batch); + ptr_valid_batch_end(&batch); + ok1(nlive == 0); + + /* add_map(): fail the 16 -> 32 entry array growth. */ + fail_realloc_size = sizeof(struct ptr_valid_map) * 32; + nlive = 0; + ptr_valid_batch_start(&batch); + ptr_valid_batch_end(&batch); + ok1(nlive == 0); + + munmap(region, 1000 * 4096); + return exit_status(); +} diff --git a/ccan/tools/configurator/configurator.c b/ccan/tools/configurator/configurator.c index 085034fd0eec..e92561b3adf9 100644 --- a/ccan/tools/configurator/configurator.c +++ b/ccan/tools/configurator/configurator.c @@ -54,10 +54,12 @@ #define DEFAULT_FLAGS "-nologo -Zi -W4 -wd4200 " \ "-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS" #define DEFAULT_OUTPUT_EXE_FLAG "-Fe:" +#define DEFAULT_OUTPUT_OBJ_FLAG "-c -Fo:" #else #define DEFAULT_COMPILER "cc" #define DEFAULT_FLAGS "-g3 -ggdb -Wall -Wundef -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wold-style-definition" #define DEFAULT_OUTPUT_EXE_FLAG "-o" +#define DEFAULT_OUTPUT_OBJ_FLAG "-c -o" #endif #define OUTPUT_FILE "configurator.out" @@ -72,28 +74,35 @@ static const char *progname = ""; static int verbose; static bool like_a_libtool = false; +static const char *compiler = DEFAULT_COMPILER; +static const char *flags = DEFAULT_FLAGS; +static const char *output_exe_flag = DEFAULT_OUTPUT_EXE_FLAG; +static const char *output_obj_flag = DEFAULT_OUTPUT_OBJ_FLAG; +static const char *wrapper; struct test { const char *name; const char *desc; /* * Template style flags (pick one): + * STATIC_ASSERT: + * - fragment is a compile-time constant expression that must be true. * OUTSIDE_MAIN: - * - put a simple boilerplate main below it. + * - put a simple boilerplate main() below fragment. * DEFINES_FUNC: * - defines a static function called func; adds ref to avoid warnings * INSIDE_MAIN: - * - put this inside main(). + * - put fragment inside main(); implies EXECUTE. * DEFINES_EVERYTHING: * - don't add any boilerplate at all. * * Execution flags: * EXECUTE: - * - a runtime test; must compile, exit 0 means flag is set. + * - a runtime test; must compile, link, run, and exit 0 to pass. * MAY_NOT_COMPILE: - * - Only useful with EXECUTE: don't get upset if it doesn't compile. + * - Only useful with EXECUTE: don't abort if it doesn't compile. * : - * - a compile test, if it compiles must run and exit 0. + * - a compile test; must compile to pass. */ const char *style; const char *depends; @@ -110,269 +119,243 @@ static struct test *tests; static const struct test base_tests[] = { { "HAVE_32BIT_OFF_T", "off_t is 32 bits", - "DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" - "int main(void) {\n" - " return sizeof(off_t) == 4 ? 0 : 1;\n" - "}\n" }, + "enum { TEST = 1/(sizeof(off_t) == 4) };\n" }, { "HAVE_ALIGNOF", "__alignof__ support", - "INSIDE_MAIN", NULL, NULL, - "return __alignof__(double) > 0 ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "__alignof__(double) > 0" }, { "HAVE_ASPRINTF", "asprintf() declaration", - "DEFINES_FUNC", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#ifndef _GNU_SOURCE\n" "#define _GNU_SOURCE\n" "#endif\n" "#include \n" - "static char *func(int x) {" - " char *p;\n" - " if (asprintf(&p, \"%u\", x) == -1) \n" - " p = NULL;\n" - " return p;\n" - "}" }, + "int (*func)(char **, const char *, ...) = &asprintf;\n" }, { "HAVE_ATTRIBUTE_COLD", "__attribute__((cold)) support", - "DEFINES_FUNC", NULL, NULL, - "static int __attribute__((cold)) func(int x) { return x; }" }, + "DEFINES_EVERYTHING", NULL, NULL, + "int __attribute__((cold)) func(int);\n" }, { "HAVE_ATTRIBUTE_CONST", "__attribute__((const)) support", - "DEFINES_FUNC", NULL, NULL, - "static int __attribute__((const)) func(int x) { return x; }" }, + "DEFINES_EVERYTHING", NULL, NULL, + "int __attribute__((const)) func(int);\n" }, { "HAVE_ATTRIBUTE_DEPRECATED", "__attribute__((deprecated)) support", - "OUTSIDE_MAIN", NULL, NULL, - "int __attribute__((deprecated)) depr(int x);" }, + "DEFINES_EVERYTHING", NULL, NULL, + "int __attribute__((deprecated)) func(int);\n" }, { "HAVE_ATTRIBUTE_NONNULL", "__attribute__((nonnull)) support", - "DEFINES_FUNC", NULL, NULL, - "static char *__attribute__((nonnull)) func(char *p) { return p; }" }, + "DEFINES_EVERYTHING", NULL, NULL, + "int __attribute__((nonnull)) func(char *);\n" }, { "HAVE_ATTRIBUTE_RETURNS_NONNULL", "__attribute__((returns_nonnull)) support", - "DEFINES_FUNC", NULL, NULL, - "static const char *__attribute__((returns_nonnull)) func(void) { return \"hi\"; }" }, + "DEFINES_EVERYTHING", NULL, NULL, + "const char * __attribute__((returns_nonnull)) func(void);\n" }, { "HAVE_ATTRIBUTE_SENTINEL", "__attribute__((sentinel)) support", - "DEFINES_FUNC", NULL, NULL, - "static int __attribute__((sentinel)) func(int i, ...) { return i; }" }, + "DEFINES_EVERYTHING", NULL, NULL, + "int __attribute__((sentinel)) func(int, ...);\n" }, { "HAVE_ATTRIBUTE_PURE", "__attribute__((pure)) support", - "DEFINES_FUNC", NULL, NULL, - "static int __attribute__((pure)) func(int x) { return x; }" }, + "DEFINES_EVERYTHING", NULL, NULL, + "int __attribute__((pure)) func(int);\n" }, { "HAVE_ATTRIBUTE_MAY_ALIAS", "__attribute__((may_alias)) support", - "OUTSIDE_MAIN", NULL, NULL, - "typedef short __attribute__((__may_alias__)) short_a;" }, + "DEFINES_EVERYTHING", NULL, NULL, + "typedef short __attribute__((__may_alias__)) short_a;\n" }, { "HAVE_ATTRIBUTE_NORETURN", "__attribute__((noreturn)) support", - "DEFINES_FUNC", NULL, NULL, - "#include \n" - "static void __attribute__((noreturn)) func(int x) { exit(x); }" }, + "DEFINES_EVERYTHING", NULL, NULL, + "void __attribute__((noreturn)) func(void);\n" }, { "HAVE_ATTRIBUTE_PRINTF", "__attribute__ format printf support", - "DEFINES_FUNC", NULL, NULL, - "static void __attribute__((format(__printf__, 1, 2))) func(const char *fmt, ...) { (void)fmt; }" }, + "DEFINES_EVERYTHING", NULL, NULL, + "void __attribute__((format(__printf__, 1, 2))) func(const char *, ...);\n" }, { "HAVE_ATTRIBUTE_UNUSED", "__attribute__((unused)) support", - "OUTSIDE_MAIN", NULL, NULL, - "static int __attribute__((unused)) func(int x) { return x; }" }, + "DEFINES_EVERYTHING", NULL, NULL, + "int __attribute__((unused)) func(int);\n" }, { "HAVE_ATTRIBUTE_USED", "__attribute__((used)) support", - "OUTSIDE_MAIN", NULL, NULL, - "static int __attribute__((used)) func(int x) { return x; }" }, + "DEFINES_EVERYTHING", NULL, NULL, + "int __attribute__((used)) func(int);\n" }, { "HAVE_BACKTRACE", "backtrace() in ", - "DEFINES_FUNC", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" - "static int func(int x) {" - " void *bt[10];\n" - " return backtrace(bt, 10) < x;\n" - "}" }, + "int (*func)(void **, int) = &backtrace;\n" }, { "HAVE_BIG_ENDIAN", "big endian", - "INSIDE_MAIN|EXECUTE", NULL, NULL, + "DEFINES_EVERYTHING", "!HAVE_LITTLE_ENDIAN", NULL, + "#if defined(__BYTE_ORDER__)\n" + " enum { TEST = 1/(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) };\n" + "#elif defined(__GLIBC__)\n" + "# include \n" + " enum { TEST = 1/(__BYTE_ORDER == __BIG_ENDIAN) };\n" + "#elif !defined(_BIG_ENDIAN) && \\\n" + " !defined(__hppa) && !defined(__hppa__) && \\\n" + " !defined(__mips) && !defined(__mips__) && \\\n" + " !defined(_M_PPC) && !defined(__powerpc__) && !defined(__ppc__) && \\\n" + " !defined(__powerpc64__) && !defined(__ppc64__) && \\\n" + " !defined(__s390__) && !defined(__s390x__) \\\n" + " !defined(__sparc) && !defined(__sparc__)\n" + "# error\n" + "#endif\n" }, + { "HAVE_BIG_ENDIAN_RUNTIME", "big endian (runtime test)", + "INSIDE_MAIN|EXECUTE", "!HAVE_BIG_ENDIAN !HAVE_LITTLE_ENDIAN", NULL, "union { int i; char c[sizeof(int)]; } u;\n" "u.i = 0x01020304;\n" - "return u.c[0] == 0x01 && u.c[1] == 0x02 && u.c[2] == 0x03 && u.c[3] == 0x04 ? 0 : 1;" }, - { "HAVE_BSWAP_64", "bswap64 in byteswap.h", + "return u.c[0] == 0x01 && u.c[1] == 0x02 && u.c[2] == 0x03 && u.c[3] == 0x04 ? 0 : 1;", + NULL, "HAVE_BIG_ENDIAN" }, + { "HAVE_BSWAP_64", "bswap_64() in ", "DEFINES_FUNC", "HAVE_BYTESWAP_H", NULL, "#include \n" - "static int func(int x) { return bswap_64(x); }" }, + "static int func(int x) { return bswap_64(x); }\n" }, { "HAVE_BUILTIN_CHOOSE_EXPR", "__builtin_choose_expr support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_choose_expr(1, 0, \"garbage\");" }, + "STATIC_ASSERT", NULL, NULL, + "__builtin_choose_expr(1, 0, \"garbage\") == 0" }, { "HAVE_BUILTIN_CLZ", "__builtin_clz support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_clz(1) == (sizeof(int)*8 - 1) ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "__builtin_clz(1U)" }, { "HAVE_BUILTIN_CLZL", "__builtin_clzl support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_clzl(1) == (sizeof(long)*8 - 1) ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "__builtin_clzl(1UL)" }, { "HAVE_BUILTIN_CLZLL", "__builtin_clzll support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_clzll(1) == (sizeof(long long)*8 - 1) ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "__builtin_clzll(1ULL)" }, { "HAVE_BUILTIN_CTZ", "__builtin_ctz support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_ctz(1U << (sizeof(int)*8 - 1)) == (sizeof(int)*8 - 1) ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "!__builtin_ctz(1U)" }, { "HAVE_BUILTIN_CTZL", "__builtin_ctzl support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_ctzl(1UL << (sizeof(long)*8 - 1)) == (sizeof(long)*8 - 1) ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "!__builtin_ctzl(1UL)" }, { "HAVE_BUILTIN_CTZLL", "__builtin_ctzll support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_ctzll(1ULL << (sizeof(long long)*8 - 1)) == (sizeof(long long)*8 - 1) ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "!__builtin_ctzll(1ULL)" }, { "HAVE_BUILTIN_CONSTANT_P", "__builtin_constant_p support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_constant_p(1) ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "__builtin_constant_p(1)" }, { "HAVE_BUILTIN_EXPECT", "__builtin_expect support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_expect(argc == 1, 1) ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "__builtin_expect(sizeof(char) == 1, 1)" }, { "HAVE_BUILTIN_FFS", "__builtin_ffs support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_ffs(0) == 0 ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "!__builtin_ffs(0)" }, { "HAVE_BUILTIN_FFSL", "__builtin_ffsl support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_ffsl(0L) == 0 ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "!__builtin_ffsl(0L)" }, { "HAVE_BUILTIN_FFSLL", "__builtin_ffsll support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_ffsll(0LL) == 0 ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "!__builtin_ffsll(0LL)" }, { "HAVE_BUILTIN_POPCOUNT", "__builtin_popcount support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_popcount(255) == 8 ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "__builtin_popcount(255U) == 8" }, { "HAVE_BUILTIN_POPCOUNTL", "__builtin_popcountl support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_popcountl(255L) == 8 ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "__builtin_popcountl(255UL) == 8" }, { "HAVE_BUILTIN_POPCOUNTLL", "__builtin_popcountll support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_popcountll(255LL) == 8 ? 0 : 1;" }, + "STATIC_ASSERT", NULL, NULL, + "__builtin_popcountll(255ULL) == 8" }, { "HAVE_BUILTIN_TYPES_COMPATIBLE_P", "__builtin_types_compatible_p support", - "INSIDE_MAIN", NULL, NULL, - "return __builtin_types_compatible_p(char *, int) ? 1 : 0;" }, + "STATIC_ASSERT", NULL, NULL, + "!__builtin_types_compatible_p(char *, int)" }, { "HAVE_ICCARM_INTRINSICS", "", "DEFINES_FUNC", NULL, NULL, "#include \n" - "int func(int v) {\n" + "static int func(int v) {\n" " return __CLZ(__RBIT(v));\n" - "}" }, + "}\n" }, { "HAVE_BYTESWAP_H", "", - "OUTSIDE_MAIN", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" }, { "HAVE_CLOCK_GETTIME", "clock_gettime() declaration", - "DEFINES_FUNC", "HAVE_STRUCT_TIMESPEC", NULL, + "DEFINES_EVERYTHING", "HAVE_STRUCT_TIMESPEC", NULL, "#include \n" - "static struct timespec func(void) {\n" - " struct timespec ts;\n" - " clock_gettime(CLOCK_REALTIME, &ts);\n" - " return ts;\n" - "}\n" }, + "int (*func)(clockid_t, struct timespec *) = &clock_gettime;\n" }, { "HAVE_CLOCK_GETTIME_IN_LIBRT", "clock_gettime() in librt", - "DEFINES_FUNC", + "DEFINES_EVERYTHING", "HAVE_STRUCT_TIMESPEC !HAVE_CLOCK_GETTIME", "-lrt", "#include \n" - "static struct timespec func(void) {\n" - " struct timespec ts;\n" - " clock_gettime(CLOCK_REALTIME, &ts);\n" - " return ts;\n" - "}\n", + "int (*func)(clockid_t, struct timespec *) = &clock_gettime;\n", /* This means HAVE_CLOCK_GETTIME, too */ - "HAVE_CLOCK_GETTIME" }, + NULL, "HAVE_CLOCK_GETTIME" }, { "HAVE_COMPOUND_LITERALS", "compound literal support", - "INSIDE_MAIN", NULL, NULL, - "int *foo = (int[]) { 1, 2, 3, 4 };\n" - "return foo[0] ? 0 : 1;" }, - { "HAVE_FCHDIR", "fchdir support", - "DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE", NULL, NULL, - "#include \n" - "#include \n" - "#include \n" + "DEFINES_EVERYTHING", NULL, NULL, + "const int *foo = (int[]) { 1, 2, 3, 4 };\n" }, + { "HAVE_FCHDIR", "fchdir() declaration", + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" - "int main(void) {\n" - " int fd = open(\"..\", O_RDONLY);\n" - " return fchdir(fd) == 0 ? 0 : 1;\n" - "}\n" }, + "int (*func)(int) = &fchdir;\n" }, { "HAVE_ERR_H", "", - "DEFINES_FUNC", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" - "static void func(int arg) {\n" - " if (arg == 0)\n" - " err(1, \"err %u\", arg);\n" - " if (arg == 1)\n" - " errx(1, \"err %u\", arg);\n" - " if (arg == 3)\n" - " warn(\"warn %u\", arg);\n" - " if (arg == 4)\n" - " warnx(\"warn %u\", arg);\n" - "}\n" }, + "void (*func0)(int, const char *, ...) = &err;\n" + "void (*func1)(int, const char *, ...) = &errx;\n" + "void (*func2)(const char *, ...) = &warn;\n" + "void (*func3)(const char *, ...) = &warnx;\n" }, { "HAVE_FILE_OFFSET_BITS", "_FILE_OFFSET_BITS to get 64-bit offsets", - "DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE", - "HAVE_32BIT_OFF_T", NULL, + "DEFINES_EVERYTHING", "HAVE_32BIT_OFF_T", NULL, "#define _FILE_OFFSET_BITS 64\n" "#include \n" - "int main(void) {\n" - " return sizeof(off_t) == 8 ? 0 : 1;\n" - "}\n" }, + "enum { TEST = 1/(sizeof(off_t) == 8) };\n" }, { "HAVE_FOR_LOOP_DECLARATION", "for loop declaration support", - "INSIDE_MAIN", NULL, NULL, - "int ret = 1;\n" - "for (int i = 0; i < argc; i++) { ret = 0; };\n" - "return ret;" }, + "DEFINES_FUNC", NULL, NULL, + "static void func(void) { for (int i = 0; i < 1; ++i); }\n" }, { "HAVE_FLEXIBLE_ARRAY_MEMBER", "flexible array member support", - "OUTSIDE_MAIN", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "struct foo { unsigned int x; int arr[]; };" }, { "HAVE_GETPAGESIZE", "getpagesize() in ", - "DEFINES_FUNC", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" - "static int func(void) { return getpagesize(); }" }, + "int (*func)(void) = &getpagesize;\n" }, { "HAVE_ISBLANK", "isblank() in ", - "DEFINES_FUNC", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#ifndef _GNU_SOURCE\n" "#define _GNU_SOURCE\n" "#endif\n" "#include \n" - "static int func(void) { return isblank(' '); }" }, + "int (*func)(int) = &isblank;\n" }, { "HAVE_LITTLE_ENDIAN", "little endian", - "INSIDE_MAIN|EXECUTE", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, + "#if defined(__BYTE_ORDER__)\n" + " enum { TEST = 1/(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) };\n" + "#elif defined(__GLIBC__)\n" + "# include \n" + " enum { TEST = 1/(__BYTE_ORDER == __LITTLE_ENDIAN) };\n" + "#elif !defined(_LITTLE_ENDIAN) && \\\n" + " !defined(_M_ALPHA) && !defined(__alpha) && !defined(__alpha__) && \\\n" + " !defined(_M_AMD64) && !defined(__amd64) && !defined(__amd64__) && \\\n" + " !defined(_M_ARM) && !defined(__arm) && !defined(__arm__) && \\\n" + " !defined(_M_ARM64) && !defined(__aarch64) && !defined(__aarch64__) && \\\n" + " !defined(_M_IA64) && !defined(__ia64) && !defined(__ia64__) && \\\n" + " !defined(_M_IX86) && !defined(__i386) && !defined(__i386__) && \\\n" + " !defined(_M_X64) && !defined(__x86_64) && !defined(__x86_64__) && \\\n" + " !defined(__bfin) && !defined(__bfin__)\n" + "# error\n" + "#endif\n" }, + { "HAVE_LITTLE_ENDIAN_RUNTIME", "little endian (runtime test)", + "INSIDE_MAIN|EXECUTE", "!HAVE_BIG_ENDIAN !HAVE_LITTLE_ENDIAN", NULL, "union { int i; char c[sizeof(int)]; } u;\n" "u.i = 0x01020304;\n" - "return u.c[0] == 0x04 && u.c[1] == 0x03 && u.c[2] == 0x02 && u.c[3] == 0x01 ? 0 : 1;" }, - { "HAVE_MEMMEM", "memmem in ", - "DEFINES_FUNC", NULL, NULL, + "return u.c[0] == 0x04 && u.c[1] == 0x03 && u.c[2] == 0x02 && u.c[3] == 0x01 ? 0 : 1;", + NULL, "HAVE_LITTLE_ENDIAN" }, + { "HAVE_MEMMEM", "memmem() in ", + "DEFINES_EVERYTHING", NULL, NULL, "#ifndef _GNU_SOURCE\n" "#define _GNU_SOURCE\n" "#endif\n" "#include \n" - "static void *func(void *h, size_t hl, void *n, size_t nl) {\n" - "return memmem(h, hl, n, nl);" - "}\n", }, - { "HAVE_MEMRCHR", "memrchr in ", - "DEFINES_FUNC", NULL, NULL, + "void * (*func)(const void *, size_t, const void *, size_t) = &memmem;\n" }, + { "HAVE_MEMRCHR", "memrchr() in ", + "DEFINES_EVERYTHING", NULL, NULL, "#ifndef _GNU_SOURCE\n" "#define _GNU_SOURCE\n" "#endif\n" "#include \n" - "static void *func(void *s, int c, size_t n) {\n" - "return memrchr(s, c, n);" - "}\n", }, + "void * (*func)(const void *, int, size_t) = &memrchr;\n" }, { "HAVE_MMAP", "mmap() declaration", - "DEFINES_FUNC", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" - "static void *func(int fd) {\n" - " return mmap(0, 65536, PROT_READ, MAP_SHARED, fd, 0);\n" - "}" }, - { "HAVE_PROC_SELF_MAPS", "/proc/self/maps exists", - "DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE", NULL, NULL, - "#include \n" - "#include \n" - "#include \n" - "int main(void) {\n" - " return open(\"/proc/self/maps\", O_RDONLY) != -1 ? 0 : 1;\n" - "}\n" }, + "void * (*func)(void *, size_t, int, int, int, off_t) = &mmap;\n" }, { "HAVE_QSORT_R_PRIVATE_LAST", "qsort_r cmp takes trailing arg", - "DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#ifndef _GNU_SOURCE\n" "#define _GNU_SOURCE\n" "#endif\n" "#include \n" - "static int cmp(const void *lp, const void *rp, void *priv) {\n" - " *(unsigned int *)priv = 1;\n" - " return *(const int *)lp - *(const int *)rp; }\n" - "int main(void) {\n" - " int array[] = { 9, 2, 5 };\n" - " unsigned int called = 0;\n" - " qsort_r(array, 3, sizeof(int), cmp, &called);\n" - " return called && array[0] == 2 && array[1] == 5 && array[2] == 9 ? 0 : 1;\n" - "}\n" }, + "void (*func)(void *, size_t, size_t, int (*)(const void *, const void *, void *), void *) = &qsort_r;\n" }, { "HAVE_STRUCT_TIMESPEC", "struct timespec declaration", - "DEFINES_FUNC", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" - "static void func(void) {\n" - " struct timespec ts;\n" - " ts.tv_sec = ts.tv_nsec = 1;\n" - "}\n" }, + "const struct timespec ts = { .tv_sec = 1, .tv_nsec = 1 };\n" }, { "HAVE_SECTION_START_STOP", "__attribute__((section)) and __start/__stop", "DEFINES_FUNC", NULL, NULL, "static void *__attribute__((__section__(\"mysec\"))) p = &p;\n" @@ -381,35 +364,53 @@ static const struct test base_tests[] = { " return __stop_mysec - __start_mysec;\n" "}\n" }, { "HAVE_STACK_GROWS_UPWARDS", "stack grows upwards", - "DEFINES_EVERYTHING|EXECUTE", NULL, NULL, - "#include \n" - "static ptrdiff_t nest(const void *base, unsigned int i)\n" - "{\n" - " if (i == 0)\n" - " return (const char *)&i - (const char *)base;\n" - " return nest(base, i-1);\n" - "}\n" - "int main(int argc, char *argv[]) {\n" - " (void)argv;\n" - " return (nest(&argc, argc) > 0) ? 0 : 1;\n" - "}\n" }, + "DEFINES_EVERYTHING", NULL, NULL, + "#if !defined(__hppa)\n" + "# error\n" + "#endif\n" }, { "HAVE_STATEMENT_EXPR", "statement expression support", - "INSIDE_MAIN", NULL, NULL, - "return ({ int x = argc; x == argc ? 0 : 1; });" }, + "DEFINES_FUNC", NULL, NULL, + "static int func(void) { return ({ int x = 0; x == 0 ? 0 : 1; }); }\n" }, + { "HAVE_STATIC_ASSERT", "_Static_assert support", + "DEFINES_EVERYTHING", NULL, NULL, + "_Static_assert(1, \"OK\");\n" }, { "HAVE_SYS_FILIO_H", "", - "OUTSIDE_MAIN", NULL, NULL, /* Solaris needs this for FIONREAD */ + "DEFINES_EVERYTHING", NULL, NULL, /* Solaris needs this for FIONREAD */ "#include \n" }, { "HAVE_SYS_TERMIOS_H", "", - "OUTSIDE_MAIN", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" }, { "HAVE_SYS_UNISTD_H", "", - "OUTSIDE_MAIN", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" }, { "HAVE_TYPEOF", "__typeof__ support", - "INSIDE_MAIN", NULL, NULL, - "__typeof__(argc) i; i = argc; return i == argc ? 0 : 1;" }, - { "HAVE_UNALIGNED_ACCESS", "unaligned access to int", - "DEFINES_EVERYTHING|EXECUTE", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, + "static int i;\n" + "__typeof__(i) *p = &i;\n" }, + { "HAVE_EFFICIENT_UNALIGNED_ACCESS", "efficient unaligned memory access", + "DEFINES_EVERYTHING", NULL, NULL, + "#if !defined(_M_AMD64) && !defined(__amd64) && !defined(__amd64__) && \\\n" + " !defined(__ARM_FEATURE_UNALIGNED) && \\\n" + " !defined(_M_ARM64) && !defined(__aarch64) && !defined(__aarch64__) && \\\n" + " !defined(_M_IX86) && !defined(__i386) && !defined(__i386__) && \\\n" + " !defined(_M_PPC) && !defined(__powerpc__) && !defined(__ppc__) && \\\n" + " !defined(__powerpc64__) && !defined(__ppc64__) && \\\n" + " !defined(__s390__) && !defined(__s390x__) \\\n" + " !defined(_M_X64) && !defined(__x86_64) && !defined(__x86_64__)\n" + "# error\n" + "#endif\n", + NULL, "HAVE_UNALIGNED_ACCESS" }, + { "HAVE_NO_UNALIGNED_ACCESS", "known lack of unaligned memory access", + "DEFINES_EVERYTHING", "!HAVE_EFFICIENT_UNALIGNED_ACCESS", NULL, + "#if !defined(_M_ALPHA) && !defined(__alpha) && !defined(__alpha__) && \\\n" + " (!defined(_M_ARM) && !defined(__arm) && !defined(__arm__) || defined(__ARM_FEATURE_UNALIGNED)) && \\\n" + " !defined(__hppa) && !defined(__hppa__) && \\\n" + " !defined(__mips) && !defined(__mips__) && \\\n" + " !defined(__sparc) && !defined(__sparc__)\n" + "# error\n" + "#endif\n" }, + { "HAVE_UNALIGNED_ACCESS", "unaligned memory access (runtime test)", + "DEFINES_EVERYTHING|EXECUTE", "!HAVE_NO_UNALIGNED_ACCESS", NULL, "#include \n" "int main(int argc, char *argv[]) {\n" " (void)argc;\n" @@ -419,52 +420,33 @@ static const struct test base_tests[] = { " return *x == *y;\n" "}\n" }, { "HAVE_UTIME", "utime() declaration", - "DEFINES_FUNC", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" "#include \n" - "static int func(const char *filename) {\n" - " struct utimbuf times = { 0 };\n" - " return utime(filename, ×);\n" - "}" }, + "int (*func)(const char *, const struct utimbuf *) = &utime;\n" }, { "HAVE_WARN_UNUSED_RESULT", "__attribute__((warn_unused_result))", - "DEFINES_FUNC", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" "#include \n" - "static __attribute__((warn_unused_result)) int func(int i) {\n" - " return i + 1;\n" - "}" }, + "__attribute__((warn_unused_result)) int func(void);\n" }, { "HAVE_OPENMP", "#pragma omp and -fopenmp support", - "INSIDE_MAIN|EXECUTE|MAY_NOT_COMPILE", NULL, NULL, - "int i;\n" + "DEFINES_FUNC", NULL, NULL, + "static void func(void) {\n" + " int i;\n" "#pragma omp parallel for\n" - "for(i = 0; i < 0; i++) {};\n" - "return 0;\n", + " for(i = 0; i < 0; ++i);\n" + "}\n", "-Werror -fopenmp" }, { "HAVE_VALGRIND_MEMCHECK_H", "", - "OUTSIDE_MAIN", NULL, NULL, + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" }, - { "HAVE_UCONTEXT", "working ", + "DEFINES_EVERYTHING", NULL, NULL, "#include \n" - "static int x = 0;\n" - "static char stack[2048];\n" - "static ucontext_t a, b;\n" - "static void fn(void) {\n" - " x |= 2;\n" - " setcontext(&b);\n" - " x |= 4;\n" - "}\n" - "int main(void) {\n" - " x |= 1;\n" - " getcontext(&a);\n" - " a.uc_stack.ss_sp = stack;\n" - " a.uc_stack.ss_size = sizeof(stack);\n" - " makecontext(&a, fn, 0);\n" - " swapcontext(&b, &a);\n" - " return (x == 3) ? 0 : 1;\n" - "}\n" - }, + "int (*func0)(ucontext_t *) = &getcontext;\n" + "int (*func1)(const ucontext_t *) = &setcontext;\n" + "void (*func2)(ucontext_t *, void (*)(void), int, ...) = &makecontext;\n" + "int (*func3)(ucontext_t *, const ucontext_t *) = &swapcontext;\n" }, { "HAVE_POINTER_SAFE_MAKECONTEXT", "passing pointers via makecontext()", "DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE", "HAVE_UCONTEXT", NULL, @@ -491,50 +473,36 @@ static const struct test base_tests[] = { " return worked ? 0 : 1;\n" "}\n" }, - { "HAVE_BUILTIN_CPU_SUPPORTS", "__builtin_cpu_supports()", + { "HAVE_BUILTIN_CPU_SUPPORTS", "__builtin_cpu_supports support", "DEFINES_FUNC", NULL, NULL, - "#include \n" - "static bool func(void) {\n" - " return __builtin_cpu_supports(\"mmx\");\n" - "}" - }, - { "HAVE_CLOSEFROM", "closefrom() offered by system", + "static int func(void) { return __builtin_cpu_supports(\"mmx\"); }\n" }, + { "HAVE_CLOSEFROM", "closefrom() declaration", "DEFINES_EVERYTHING", NULL, NULL, "#include \n" "#include \n" - "int main(void) {\n" - " closefrom(STDERR_FILENO + 1);\n" - " return 0;\n" - "}\n" - }, - { "HAVE_F_CLOSEM", "F_CLOSEM defined for fctnl.", + "void (*func)(int) = &closefrom;\n" }, + { "HAVE_F_CLOSEM", "F_CLOSEM", "DEFINES_EVERYTHING", NULL, NULL, "#include \n" "#include \n" - "int main(void) {\n" - " int res = fcntl(STDERR_FILENO + 1, F_CLOSEM, 0);\n" - " return res < 0;\n" - "}\n" - }, - { "HAVE_NR_CLOSE_RANGE", "close_range syscall available as __NR_close_range.", + "enum { TEST = F_CLOSEM };\n" }, + { "HAVE_CLOSE_RANGE", "close_range() declaration", + "DEFINES_EVERYTHING", NULL, NULL, + "#ifndef _GNU_SOURCE\n" + "#define _GNU_SOURCE\n" + "#endif\n" + "#include \n" + "int (*func)(unsigned, unsigned, int) = &close_range;\n" }, + { "HAVE_NR_CLOSE_RANGE", "__NR_close_range", "DEFINES_EVERYTHING", NULL, NULL, - "#include \n" "#include \n" "#include \n" - "int main(void) {\n" - " int res = syscall(__NR_close_range, STDERR_FILENO + 1, INT_MAX, 0);\n" - " return res < 0;\n" - "}\n" - }, - { "HAVE_F_MAXFD", "F_MAXFD defined for fcntl.", + "enum { TEST = __NR_close_range };\n" }, + { "HAVE_F_MAXFD", "F_MAXFD", "DEFINES_EVERYTHING", NULL, NULL, "#include \n" "#include \n" - "int main(void) {\n" - " int res = fcntl(0, F_MAXFD);\n" - " return res < 0;\n" - "}\n" - }, + "int test = F_MAXFD;\n" }, }; static void c12r_err(int eval, const char *fmt, ...) @@ -558,7 +526,7 @@ static void c12r_errx(int eval, const char *fmt, ...) va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); - fprintf(stderr, "\n"); + fputc('\n', stderr); exit(eval); } @@ -573,7 +541,7 @@ static void start_test(const char *what, const char *why) static void end_test(bool result) { if (like_a_libtool) - printf("%s\n", result ? "yes" : "no"); + puts(result ? "yes" : "no"); } static size_t fcopy(FILE *fsrc, FILE *fdst) @@ -634,27 +602,43 @@ static char *run(const char *cmd, int *exitstatus) return ret; } -static char *connect_args(const char *argv[], const char *outflag, - const char *files) +/* + * Efficiently joins together an arbitrary number of strings using a glue char. + * The returned string must be freed when it is no longer needed. + * Each variadic argument is a pointer to an array of pointers to strings. + * The last element in each array must be NULL. + * The last argument must be NULL. + */ +static char *concat(int glue, /* (const char *const *) */...) { - unsigned int i; - char *ret; - size_t len = strlen(outflag) + strlen(files) + 1; - - for (i = 1; argv[i]; i++) - len += 1 + strlen(argv[i]); - - ret = malloc(len); - len = 0; - for (i = 1; argv[i]; i++) { - strcpy(ret + len, argv[i]); - len += strlen(argv[i]); - if (argv[i+1] || *outflag) - ret[len++] = ' '; + va_list ap; + size_t len = 0; + const char *const *arg; + const char *s; + char *ret, *p; + + va_start(ap, glue); + while ((arg = va_arg(ap, const char *const *))) { + while ((s = *arg++)) { + size_t n = strlen(s); + len += n + !!n; + } } - strcpy(ret + len, outflag); - len += strlen(outflag); - strcpy(ret + len, files); + va_end(ap); + if (!len) + return strdup(""); + + p = ret = malloc(len); + va_start(ap, glue); + while ((arg = va_arg(ap, const char *const *))) { + while ((s = *arg++)) { + p = stpcpy(p, s); + *p++ = (char) glue; + } + } + va_end(ap); + *--p = '\0'; + return ret; } @@ -671,6 +655,8 @@ static struct test *find_test(const char *name) } #define PRE_BOILERPLATE "/* Test program generated by configurator. */\n" +#define STATIC_ASSERT_START_BOILERPLATE "enum { TEST = 1/!!(" +#define STATIC_ASSERT_END_BOILERPLATE ") };\n" #define MAIN_START_BOILERPLATE \ "int main(int argc, char *argv[]) {\n" \ " (void)argc;\n" \ @@ -679,10 +665,11 @@ static struct test *find_test(const char *name) #define MAIN_BODY_BOILERPLATE "return 0;\n" #define MAIN_END_BOILERPLATE "}\n" -static bool run_test(const char *cmd, const char *wrapper, struct test *test) +static bool run_test(struct test *test) { char *output, *newcmd; FILE *outf; + const char *args[4], **arg = args; int status; if (test->done) @@ -691,58 +678,56 @@ static bool run_test(const char *cmd, const char *wrapper, struct test *test) if (test->depends) { size_t len; const char *deps = test->depends; - char *dep; + const char *dep; /* Space-separated dependencies, could be ! for inverse. */ - while ((len = strcspn(deps, " ")) != 0) { - bool positive = true; - if (deps[len]) { - dep = strdup(deps); - dep[len] = '\0'; - } else { - dep = (char *)deps; - } - - if (dep[0] == '!') { - dep++; - positive = false; - } - if (run_test(cmd, wrapper, find_test(dep)) != positive) { + while ((len = strcspn(deps += strspn(deps, " "), " ")) != 0) { + bool positive = deps[0] != '!'; + if (!positive) + ++deps, --len; + dep = deps[len] ? strndup(deps, len) : deps; + if (run_test(find_test(dep)) != positive) { test->answer = false; test->done = true; return test->answer; } if (deps[len]) - free(dep); - + free((void *) dep); deps += len; - deps += strspn(deps, " "); } } + bool need_run = strstr(test->style, "EXECUTE"); + outf = fopen(INPUT_FILE, verbose > 1 ? "w+" : "w"); if (!outf) c12r_err(EXIT_TROUBLE_RUNNING, "creating %s", INPUT_FILE); - fprintf(outf, "%s", PRE_BOILERPLATE); + fputs(PRE_BOILERPLATE, outf); - if (strstr(test->style, "INSIDE_MAIN")) { - fprintf(outf, "%s", MAIN_START_BOILERPLATE); - fprintf(outf, "%s", test->fragment); - fprintf(outf, "%s", MAIN_END_BOILERPLATE); + if (strstr(test->style, "STATIC_ASSERT")) { + fputs(STATIC_ASSERT_START_BOILERPLATE, outf); + fputs(test->fragment, outf); + fputs(STATIC_ASSERT_END_BOILERPLATE, outf); + } else if (strstr(test->style, "INSIDE_MAIN")) { + fputs(MAIN_START_BOILERPLATE, outf); + fputs(test->fragment, outf); + fputs(MAIN_END_BOILERPLATE, outf); + /* We run INSIDE_MAIN tests for sanity checking. */ + need_run = true; } else if (strstr(test->style, "OUTSIDE_MAIN")) { - fprintf(outf, "%s", test->fragment); - fprintf(outf, "%s", MAIN_START_BOILERPLATE); - fprintf(outf, "%s", MAIN_BODY_BOILERPLATE); - fprintf(outf, "%s", MAIN_END_BOILERPLATE); + fputs(test->fragment, outf); + fputs(MAIN_START_BOILERPLATE, outf); + fputs(MAIN_BODY_BOILERPLATE, outf); + fputs(MAIN_END_BOILERPLATE, outf); } else if (strstr(test->style, "DEFINES_FUNC")) { - fprintf(outf, "%s", test->fragment); - fprintf(outf, "%s", MAIN_START_BOILERPLATE); - fprintf(outf, "%s", USE_FUNC_BOILERPLATE); - fprintf(outf, "%s", MAIN_BODY_BOILERPLATE); - fprintf(outf, "%s", MAIN_END_BOILERPLATE); + fputs(test->fragment, outf); + fputs(MAIN_START_BOILERPLATE, outf); + fputs(USE_FUNC_BOILERPLATE, outf); + fputs(MAIN_BODY_BOILERPLATE, outf); + fputs(MAIN_END_BOILERPLATE, outf); } else if (strstr(test->style, "DEFINES_EVERYTHING")) { - fprintf(outf, "%s", test->fragment); + fputs(test->fragment, outf); } else c12r_errx(EXIT_BAD_TEST, "Unknown style for test %s: %s", test->name, test->style); @@ -754,26 +739,28 @@ static bool run_test(const char *cmd, const char *wrapper, struct test *test) fclose(outf); - newcmd = strdup(cmd); - if (test->flags) { - newcmd = realloc(newcmd, strlen(newcmd) + strlen(" ") - + strlen(test->flags) + 1); - strcat(newcmd, " "); - strcat(newcmd, test->flags); + *arg++ = test->flags; if (verbose > 1) - printf("Extra flags line: %s", newcmd); + printf("Extra compiler flags: %s\n", test->flags); } if (test->link) { - newcmd = realloc(newcmd, strlen(newcmd) + strlen(" ") - + strlen(test->link) + 1); - strcat(newcmd, " "); - strcat(newcmd, test->link); + *arg++ = test->link; if (verbose > 1) - printf("Extra link line: %s", newcmd); + printf("Extra linker flags: %s\n", test->link); + *arg++ = output_exe_flag; + } else if (need_run) { + *arg++ = output_exe_flag; + } else { + *arg++ = output_obj_flag; } + *arg = NULL; + newcmd = concat(' ', (const char *[]) { compiler, flags, NULL }, args, + (const char *[]) { OUTPUT_FILE, INPUT_FILE, NULL }, + NULL); + start_test("checking for ", test->desc); output = run(newcmd, &status); @@ -795,14 +782,17 @@ static bool run_test(const char *cmd, const char *wrapper, struct test *test) /* Compile succeeded. */ free(output); /* We run INSIDE_MAIN tests for sanity checking. */ - if (strstr(test->style, "EXECUTE") - || strstr(test->style, "INSIDE_MAIN")) { - char *runcmd = malloc(strlen(wrapper) + strlen(" ." DIR_SEP OUTPUT_FILE) + 1); - - strcpy(runcmd, wrapper); - strcat(runcmd, " ." DIR_SEP OUTPUT_FILE); - output = run(runcmd, &status); - free(runcmd); + if (need_run) { + if (wrapper) { + char *runcmd = malloc(strlen(wrapper) + + strlen(" ." DIR_SEP OUTPUT_FILE) + 1); + strcpy(stpcpy(runcmd, wrapper), + " ." DIR_SEP OUTPUT_FILE); + output = run(runcmd, &status); + free(runcmd); + } else { + output = run("." DIR_SEP OUTPUT_FILE, &status); + } if (!strstr(test->style, "EXECUTE") && status != 0) c12r_errx(EXIT_BAD_TEST, "Test for %s failed with %i:\n%s", @@ -874,7 +864,7 @@ static char *read_field(const char *name, bool compulsory) * First three non-ignored lines must be: * var= * desc= - * style=OUTSIDE_MAIN DEFINES_FUNC INSIDE_MAIN DEFINES_EVERYTHING EXECUTE MAY_NOT_COMPILE + * style=STATIC_ASSERT OUTSIDE_MAIN DEFINES_FUNC INSIDE_MAIN DEFINES_EVERYTHING EXECUTE MAY_NOT_COMPILE * * Followed by optional lines: * depends= @@ -947,13 +937,8 @@ static void read_tests(size_t num_tests) int main(int argc, const char *argv[]) { - char *cmd; unsigned int i; - const char *default_args[] - = { "", DEFAULT_COMPILER, DEFAULT_FLAGS, NULL }; - const char *outflag = DEFAULT_OUTPUT_EXE_FLAG; const char *configurator_cc = NULL; - const char *wrapper = ""; const char *orig_cc; const char *varfile = NULL; const char *headerfile = NULL; @@ -961,70 +946,61 @@ int main(int argc, const char *argv[]) FILE *outf; if (argc > 0) - progname = argv[0]; + progname = *argv++, --argc; - while (argc > 1) { - if (strcmp(argv[1], "--help") == 0) { - printf("Usage: configurator [-v] [--var-file=] [-O] [--configurator-cc=] [--wrapper=] [--autotools-style] [--extra-tests] [ ...]\n" + for (; argc > 0; ++argv, --argc) { + if (strcmp(argv[0], "--help") == 0) { + printf("Usage: configurator [-v] [--var-file=] [--output-exe=] [--output-obj=] [--configurator-cc=] [--wrapper=] [--autotools-style] [--extra-tests] [ ...]\n" " will have \" \" appended\n" - "Default: %s %s %s\n", + "Default : %s %s\n" + "Default --output-exe=\"%s\"\n" + "Default --output-obj=\"%s\"\n", DEFAULT_COMPILER, DEFAULT_FLAGS, - DEFAULT_OUTPUT_EXE_FLAG); + DEFAULT_OUTPUT_EXE_FLAG, + DEFAULT_OUTPUT_OBJ_FLAG); exit(0); } - if (strncmp(argv[1], "-O", 2) == 0) { - argc--; - argv++; - outflag = argv[1] + 2; - if (!*outflag) { + if (strncmp(argv[0], "-O", 2) == 0) { /* legacy compatibility */ + if (!argv[0][2]) { fprintf(stderr, "%s: option requires an argument -- O\n", argv[0]); exit(EXIT_BAD_USAGE); } - } else if (strcmp(argv[1], "-v") == 0) { - argc--; - argv++; + output_exe_flag = argv[0] + 2; + } else if (strcmp(argv[0], "-v") == 0) { verbose++; - } else if (strcmp(argv[1], "-vv") == 0) { - argc--; - argv++; + } else if (strcmp(argv[0], "-vv") == 0) { verbose += 2; - } else if (strncmp(argv[1], "--configurator-cc=", 18) == 0) { - configurator_cc = argv[1] + 18; - argc--; - argv++; - } else if (strncmp(argv[1], "--wrapper=", 10) == 0) { - wrapper = argv[1] + 10; - argc--; - argv++; - } else if (strncmp(argv[1], "--var-file=", 11) == 0) { - varfile = argv[1] + 11; - argc--; - argv++; - } else if (strcmp(argv[1], "--autotools-style") == 0) { + } else if (strncmp(argv[0], "--output-exe=", 13) == 0) { + output_exe_flag = argv[0] + 13; + } else if (strncmp(argv[0], "--output-obj=", 13) == 0) { + output_obj_flag = argv[0] + 13; + } else if (strncmp(argv[0], "--configurator-cc=", 18) == 0) { + configurator_cc = argv[0] + 18; + } else if (strncmp(argv[0], "--wrapper=", 10) == 0) { + wrapper = argv[0] + 10; + } else if (strncmp(argv[0], "--var-file=", 11) == 0) { + varfile = argv[0] + 11; + } else if (strcmp(argv[0], "--autotools-style") == 0) { like_a_libtool = true; - argc--; - argv++; - } else if (strncmp(argv[1], "--header-file=", 14) == 0) { - headerfile = argv[1] + 14; - argc--; - argv++; - } else if (strcmp(argv[1], "--extra-tests") == 0) { + } else if (strncmp(argv[0], "--header-file=", 14) == 0) { + headerfile = argv[0] + 14; + } else if (strcmp(argv[0], "--extra-tests") == 0) { extra_tests = true; - argc--; - argv++; - } else if (strcmp(argv[1], "--") == 0) { + } else if (strcmp(argv[0], "--") == 0) { break; - } else if (argv[1][0] == '-') { - c12r_errx(EXIT_BAD_USAGE, "Unknown option %s", argv[1]); + } else if (argv[0][0] == '-') { + c12r_errx(EXIT_BAD_USAGE, "Unknown option %s", argv[0]); } else { break; } } - if (argc == 1) - argv = default_args; + if (argc > 0) + compiler = *argv++, --argc; + if (argc > 0) + flags = concat(' ', argv, NULL); /* Copy with NULL entry at end */ tests = calloc(sizeof(base_tests)/sizeof(base_tests[0]) + 1, @@ -1034,19 +1010,17 @@ int main(int argc, const char *argv[]) if (extra_tests) read_tests(sizeof(base_tests)/sizeof(base_tests[0])); - orig_cc = argv[1]; + orig_cc = compiler; if (configurator_cc) - argv[1] = configurator_cc; + compiler = configurator_cc; - cmd = connect_args(argv, outflag, OUTPUT_FILE " " INPUT_FILE); if (like_a_libtool) { start_test("Making autoconf users comfortable", ""); sleep(1); end_test(1); } for (i = 0; tests[i].name; i++) - run_test(cmd, wrapper, &tests[i]); - free(cmd); + run_test(&tests[i]); remove(OUTPUT_FILE); remove(INPUT_FILE); @@ -1082,22 +1056,21 @@ int main(int argc, const char *argv[]) } else outf = stdout; - fprintf(outf, "/* Generated by CCAN configurator */\n" - "#ifndef CCAN_CONFIG_H\n" - "#define CCAN_CONFIG_H\n"); - fprintf(outf, "#ifndef _GNU_SOURCE\n"); - fprintf(outf, "#define _GNU_SOURCE /* Always use GNU extensions. */\n"); - fprintf(outf, "#endif\n"); + fputs("/* Generated by CCAN configurator */\n" + "#ifndef CCAN_CONFIG_H\n" + "#define CCAN_CONFIG_H\n" + "#ifndef _GNU_SOURCE\n" + "#define _GNU_SOURCE /* Always use GNU extensions. */\n" + "#endif\n", outf); fprintf(outf, "#define CCAN_COMPILER \"%s\"\n", orig_cc); - cmd = connect_args(argv + 1, "", ""); - fprintf(outf, "#define CCAN_CFLAGS \"%s\"\n", cmd); - free(cmd); - fprintf(outf, "#define CCAN_OUTPUT_EXE_CFLAG \"%s\"\n\n", outflag); + fprintf(outf, "#define CCAN_CFLAGS \"%s\"\n", flags); + fprintf(outf, "#define CCAN_OUTPUT_EXE_CFLAG \"%s\"\n\n", output_exe_flag); + fprintf(outf, "#define CCAN_OUTPUT_OBJ_CFLAG \"%s\"\n\n", output_obj_flag); /* This one implies "#include Date: Sat, 22 Aug 2026 17:05:37 -0400 Subject: [PATCH 13/17] build: place build products in a separate directory tree This allows building the same source tree for multiple different host machines without needing to clean it in between, and it simplifies cleanup of the build products down to a single subdirectory prune. In the course of making this change, I also eliminated the big ugly list of ccan object recipes in the top-level Makefile. Those object files are now named similarly to their corresponding source files but are placed beneath the build output directory, $(BUILDDIR), to avoid polluting the source tree. I also switched the 'obsclean' Make target to a double-colon target so that the several Makefiles can all contribute commands to it. Changelog-Changed: The build products are now placed into a separate directory tree. --- .gitignore | 1 + Makefile | 448 ++++++++++++++-------------------- bitcoin/Makefile | 11 +- bitcoin/test/Makefile | 9 +- channeld/Makefile | 19 +- channeld/test/Makefile | 13 +- cli/Makefile | 9 +- cli/test/Makefile | 7 +- closingd/Makefile | 15 +- common/Makefile | 15 +- common/test/Makefile | 131 ++++++---- connectd/Makefile | 17 +- connectd/test/Makefile | 4 +- db/Makefile | 2 +- devtools/Makefile | 22 +- doc/Makefile | 4 +- external/Makefile | 39 ++- gossipd/Makefile | 19 +- gossipd/test/Makefile | 7 +- hsmd/Makefile | 11 +- lightningd/Makefile | 14 +- lightningd/test/Makefile | 9 +- onchaind/Makefile | 17 +- onchaind/test/Makefile | 12 +- openingd/Makefile | 15 +- plugins/Makefile | 102 ++++---- plugins/askrene/Makefile | 7 +- plugins/askrene/test/Makefile | 13 +- plugins/bkpr/Makefile | 11 +- plugins/bkpr/test/Makefile | 7 +- plugins/renepay/Makefile | 7 +- plugins/renepay/test/Makefile | 9 +- plugins/test/Makefile | 19 +- plugins/xpay/Makefile | 7 +- tests/fuzz/Makefile | 29 ++- tests/plugins/Makefile | 21 +- tools/Makefile | 34 ++- tools/test/Makefile | 14 +- wallet/Makefile | 5 +- wallet/test/Makefile | 7 +- wire/Makefile | 2 +- wire/test/Makefile | 12 +- 42 files changed, 622 insertions(+), 554 deletions(-) diff --git a/.gitignore b/.gitignore index 5a7f6ebca5be..eb6b1f6dfbf2 100644 --- a/.gitignore +++ b/.gitignore @@ -98,6 +98,7 @@ plugins/cln-currencyrate # Build directories bionic/ +build/ focal/ jammy/ noble/ diff --git a/Makefile b/Makefile index 53acd756303a..e30ba3031b66 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,16 @@ CPPFLAGS = LDFLAGS_FROM_ENV := $(LDFLAGS) LDFLAGS = +# Look up the host machine tuple if not specified +ifndef HOST +HOST := $(shell $(CC) $(CFLAGS_FROM_ENV) -dumpmachine) +endif + +# Set a default build directory if not specified +ifndef BUILDDIR +BUILDDIR := build/$(HOST) +endif + # Use Homebrew LLVM toolchain for fuzzing support on macOS ifeq ($(OS),Darwin) export PATH := /opt/homebrew/opt/llvm/bin:$(PATH) @@ -108,136 +118,140 @@ PYTHON_GENERATED= \ FEATURES := CCAN_OBJS := \ - ccan-asort.o \ - ccan-base64.o \ - ccan-bitmap.o \ - ccan-bitops.o \ - ccan-breakpoint.o \ - ccan-cdump.o \ - ccan-closefrom.o \ - ccan-crc32c.o \ - ccan-crypto-hmac.o \ - ccan-crypto-hkdf.o \ - ccan-crypto-ripemd160.o \ - ccan-crypto-sha256.o \ - ccan-crypto-shachain.o \ - ccan-crypto-siphash24.o \ - ccan-err.o \ - ccan-fdpass.o \ - ccan-htable.o \ - ccan-ilog.o \ - ccan-io-io.o \ - ccan-intmap.o \ - ccan-io-poll.o \ - ccan-io-fdpass.o \ - ccan-isaac.o \ - ccan-isaac64.o \ - ccan-json_escape.o \ - ccan-json_out.o \ - ccan-list.o \ - ccan-mem.o \ - ccan-membuf.o \ - ccan-noerr.o \ - ccan-opt-helpers.o \ - ccan-opt-parse.o \ - ccan-opt-usage.o \ - ccan-opt.o \ - ccan-pipecmd.o \ - ccan-ptr_valid.o \ - ccan-rbuf.o \ - ccan-read_write_all.o \ - ccan-rune-coding.o \ - ccan-rune-rune.o \ - ccan-str-base32.o \ - ccan-str-hex.o \ - ccan-str.o \ - ccan-strmap.o \ - ccan-strset.o \ - ccan-take.o \ - ccan-tal-grab_file.o \ - ccan-tal-link.o \ - ccan-tal-path.o \ - ccan-tal-str.o \ - ccan-tal.o \ - ccan-time.o \ - ccan-timer.o \ - ccan-utf8.o - -CCAN_HEADERS := \ - $(CCANDIR)/config.h \ - $(CCANDIR)/ccan/alignof/alignof.h \ - $(CCANDIR)/ccan/array_size/array_size.h \ - $(CCANDIR)/ccan/asort/asort.h \ - $(CCANDIR)/ccan/base64/base64.h \ - $(CCANDIR)/ccan/bitmap/bitmap.h \ - $(CCANDIR)/ccan/bitops/bitops.h \ - $(CCANDIR)/ccan/breakpoint/breakpoint.h \ - $(CCANDIR)/ccan/build_assert/build_assert.h \ - $(CCANDIR)/ccan/cast/cast.h \ - $(CCANDIR)/ccan/cdump/cdump.h \ - $(CCANDIR)/ccan/check_type/check_type.h \ - $(CCANDIR)/ccan/closefrom/closefrom.h \ - $(CCANDIR)/ccan/compiler/compiler.h \ - $(CCANDIR)/ccan/container_of/container_of.h \ - $(CCANDIR)/ccan/cppmagic/cppmagic.h \ - $(CCANDIR)/ccan/crc32c/crc32c.h \ - $(CCANDIR)/ccan/crypto/hkdf_sha256/hkdf_sha256.h \ - $(CCANDIR)/ccan/crypto/hmac_sha256/hmac_sha256.h \ - $(CCANDIR)/ccan/crypto/ripemd160/ripemd160.h \ - $(CCANDIR)/ccan/crypto/sha256/sha256.h \ - $(CCANDIR)/ccan/crypto/shachain/shachain.h \ - $(CCANDIR)/ccan/crypto/siphash24/siphash24.h \ - $(CCANDIR)/ccan/endian/endian.h \ - $(CCANDIR)/ccan/err/err.h \ - $(CCANDIR)/ccan/fdpass/fdpass.h \ - $(CCANDIR)/ccan/graphql/graphql.h \ - $(CCANDIR)/ccan/htable/htable.h \ - $(CCANDIR)/ccan/htable/htable_type.h \ - $(CCANDIR)/ccan/ilog/ilog.h \ - $(CCANDIR)/ccan/intmap/intmap.h \ - $(CCANDIR)/ccan/io/backend.h \ - $(CCANDIR)/ccan/io/fdpass/fdpass.h \ - $(CCANDIR)/ccan/io/io.h \ - $(CCANDIR)/ccan/io/io_plan.h \ - $(CCANDIR)/ccan/isaac/isaac.h \ - $(CCANDIR)/ccan/isaac/isaac64.h \ - $(CCANDIR)/ccan/json_escape/json_escape.h \ - $(CCANDIR)/ccan/json_out/json_out.h \ - $(CCANDIR)/ccan/likely/likely.h \ - $(CCANDIR)/ccan/list/list.h \ - $(CCANDIR)/ccan/lqueue/lqueue.h \ - $(CCANDIR)/ccan/mem/mem.h \ - $(CCANDIR)/ccan/membuf/membuf.h \ - $(CCANDIR)/ccan/noerr/noerr.h \ - $(CCANDIR)/ccan/opt/opt.h \ - $(CCANDIR)/ccan/opt/private.h \ - $(CCANDIR)/ccan/order/order.h \ - $(CCANDIR)/ccan/pipecmd/pipecmd.h \ - $(CCANDIR)/ccan/ptr_valid/ptr_valid.h \ - $(CCANDIR)/ccan/ptrint/ptrint.h \ - $(CCANDIR)/ccan/rbuf/rbuf.h \ - $(CCANDIR)/ccan/read_write_all/read_write_all.h \ - $(CCANDIR)/ccan/rune/internal.h \ - $(CCANDIR)/ccan/rune/rune.h \ - $(CCANDIR)/ccan/short_types/short_types.h \ - $(CCANDIR)/ccan/str/base32/base32.h \ - $(CCANDIR)/ccan/str/hex/hex.h \ - $(CCANDIR)/ccan/str/str.h \ - $(CCANDIR)/ccan/str/str_debug.h \ - $(CCANDIR)/ccan/strmap/strmap.h \ - $(CCANDIR)/ccan/strset/strset.h \ - $(CCANDIR)/ccan/structeq/structeq.h \ - $(CCANDIR)/ccan/take/take.h \ - $(CCANDIR)/ccan/tal/grab_file/grab_file.h \ - $(CCANDIR)/ccan/tal/link/link.h \ - $(CCANDIR)/ccan/tal/path/path.h \ - $(CCANDIR)/ccan/tal/str/str.h \ - $(CCANDIR)/ccan/tal/tal.h \ - $(CCANDIR)/ccan/tcon/tcon.h \ - $(CCANDIR)/ccan/time/time.h \ - $(CCANDIR)/ccan/timer/timer.h \ - $(CCANDIR)/ccan/typesafe_cb/typesafe_cb.h \ - $(CCANDIR)/ccan/utf8/utf8.h + $(addprefix $(BUILDDIR)/$(CCANDIR)/ccan/, \ + asort/asort.o \ + base64/base64.o \ + bitmap/bitmap.o \ + bitops/bitops.o \ + breakpoint/breakpoint.o \ + cdump/cdump.o \ + closefrom/closefrom.o \ + crc32c/crc32c.o \ + crypto/hkdf_sha256/hkdf_sha256.o \ + crypto/hmac_sha256/hmac_sha256.o \ + crypto/ripemd160/ripemd160.o \ + crypto/sha256/sha256.o \ + crypto/shachain/shachain.o \ + crypto/siphash24/siphash24.o \ + err/err.o \ + fdpass/fdpass.o \ + htable/htable.o \ + ilog/ilog.o \ + intmap/intmap.o \ + io/fdpass/fdpass.o \ + io/io.o \ + io/poll.o \ + isaac/isaac.o \ + isaac/isaac64.o \ + json_escape/json_escape.o \ + json_out/json_out.o \ + list/list.o \ + mem/mem.o \ + membuf/membuf.o \ + noerr/noerr.o \ + opt/helpers.o \ + opt/opt.o \ + opt/parse.o \ + opt/usage.o \ + pipecmd/pipecmd.o \ + ptr_valid/ptr_valid.o \ + rbuf/rbuf.o \ + read_write_all/read_write_all.o \ + rune/coding.o \ + rune/rune.o \ + str/base32/base32.o \ + str/hex/hex.o \ + str/str.o \ + strmap/strmap.o \ + strset/strset.o \ + take/take.o \ + tal/grab_file/grab_file.o \ + tal/link/link.o \ + tal/path/path.o \ + tal/str/str.o \ + tal/tal.o \ + time/time.o \ + timer/timer.o \ + utf8/utf8.o \ + ) + +CCAN_HEADERS := \ + $(CCANDIR)/config.h \ + $(addprefix $(CCANDIR)/ccan/, \ + alignof/alignof.h \ + array_size/array_size.h \ + asort/asort.h \ + base64/base64.h \ + bitmap/bitmap.h \ + bitops/bitops.h \ + breakpoint/breakpoint.h \ + build_assert/build_assert.h \ + cast/cast.h \ + cdump/cdump.h \ + check_type/check_type.h \ + closefrom/closefrom.h \ + compiler/compiler.h \ + container_of/container_of.h \ + cppmagic/cppmagic.h \ + crc32c/crc32c.h \ + crypto/hkdf_sha256/hkdf_sha256.h \ + crypto/hmac_sha256/hmac_sha256.h \ + crypto/ripemd160/ripemd160.h \ + crypto/sha256/sha256.h \ + crypto/shachain/shachain.h \ + crypto/siphash24/siphash24.h \ + endian/endian.h \ + err/err.h \ + fdpass/fdpass.h \ + graphql/graphql.h \ + htable/htable.h \ + htable/htable_type.h \ + ilog/ilog.h \ + intmap/intmap.h \ + io/backend.h \ + io/fdpass/fdpass.h \ + io/io.h \ + io/io_plan.h \ + isaac/isaac.h \ + isaac/isaac64.h \ + json_escape/json_escape.h \ + json_out/json_out.h \ + likely/likely.h \ + list/list.h \ + lqueue/lqueue.h \ + mem/mem.h \ + membuf/membuf.h \ + noerr/noerr.h \ + opt/opt.h \ + opt/private.h \ + order/order.h \ + pipecmd/pipecmd.h \ + ptr_valid/ptr_valid.h \ + ptrint/ptrint.h \ + rbuf/rbuf.h \ + read_write_all/read_write_all.h \ + rune/internal.h \ + rune/rune.h \ + short_types/short_types.h \ + str/base32/base32.h \ + str/hex/hex.h \ + str/str.h \ + str/str_debug.h \ + strmap/strmap.h \ + strset/strset.h \ + structeq/structeq.h \ + take/take.h \ + tal/grab_file/grab_file.h \ + tal/link/link.h \ + tal/path/path.h \ + tal/str/str.h \ + tal/tal.h \ + tcon/tcon.h \ + time/time.h \ + timer/timer.h \ + typesafe_cb/typesafe_cb.h \ + utf8/utf8.h \ + ) BOLT_GEN := tools/generate-wire.py WIRE_GEN := $(BOLT_GEN) @@ -247,6 +261,7 @@ WIRE_GEN_DEPS := $(WIRE_GEN) $(wildcard tools/gen/*_template) # These are filled by individual Makefiles ALL_PROGRAMS := +ALL_BUILD_PROGRAMS := ALL_TEST_PROGRAMS := ALL_TEST_GEN := ALL_FUZZ_TARGETS := @@ -298,7 +313,7 @@ endif endif # Put the environment-inherited flags *last* so the user has the final say. -CPPFLAGS += -DCLN_NEXT_VERSION="\"$(CLN_NEXT_VERSION)\"" -DPKGLIBEXECDIR="\"$(pkglibexecdir)\"" -DBINDIR="\"$(bindir)\"" -DPLUGINDIR="\"$(plugindir)\"" -DCCAN_TAL_NEVER_RETURN_NULL=1 -I$(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I. -I$(CPATH) $(POSTGRES_INCLUDE) -DSHACHAIN_BITS=48 -DJSMN_PARENT_LINKS $(COMPAT_CFLAGS) $(CPPFLAGS_FROM_ENV) +CPPFLAGS += -DCLN_NEXT_VERSION="\"$(CLN_NEXT_VERSION)\"" -DPKGLIBEXECDIR="\"$(pkglibexecdir)\"" -DBINDIR="\"$(bindir)\"" -DPLUGINDIR="\"$(plugindir)\"" -DCCAN_TAL_NEVER_RETURN_NULL=1 -I$(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I. -I$(BUILDDIR) -I$(CPATH) $(POSTGRES_INCLUDE) -DSHACHAIN_BITS=48 -DJSMN_PARENT_LINKS $(COMPAT_CFLAGS) $(CPPFLAGS_FROM_ENV) CFLAGS = $(CWARNFLAGS) $(CDEBUGFLAGS) $(COPTFLAGS) $(SQLITE3_CFLAGS) $(SODIUM_CFLAGS) $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) $(PIE_CFLAGS) $(CSANFLAGS) $(CFLAGS_FROM_ENV) LDFLAGS += $(PIE_LDFLAGS) $(LDFLAGS_FROM_ENV) @@ -345,8 +360,10 @@ ccan/config.h config.vars &: configure ccan/tools/configurator/configurator.c %/: @$(MKDIR_P) $(@D) -%.o: %.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) +# Update all archive members using a single ar invocation. This un-breaks parallel Make. +(%) : % ; +%.a : + @$(call VERBOSE,"ar $@",$(AR) r $@ $?) # tools/update-mocks.sh does nasty recursive make, must not do this! ifeq ($(SUPPRESS_GENERATION),1) @@ -361,6 +378,8 @@ SHA256STAMP_CHANGED = [ x"`$(SED) -n 's/.*SHA256STAMP:\([a-f0-9]*\).*/\1/p' $@ 2 SHA256STAMP = echo "$(1) SHA256STAMP:"`cat $(sort $(filter-out FORCE,$^)) | $(SHA256SUM) | cut -c1-64`"$(2)" >> $@ endif +CDUMP_ENUMSTR := $(BUILDDIR)/ccan/ccan/cdump/tools/cdump-enumstr + # generate-wire.py --page [header|impl] hdrfilename wirename < csv > file %_wiregen.h: %_wire.csv $(WIRE_GEN_DEPS) @if $(call SHA256STAMP_CHANGED); then \ @@ -466,11 +485,14 @@ ALL_NONGEN_SRCFILES := $(ALL_NONGEN_HEADERS) $(ALL_NONGEN_SOURCES) # TODO: $(EXEEXT) support for Windows? Needs more coding for # the individual Makefiles, however. BIN_PROGRAMS = \ + $(addprefix $(BUILDDIR)/, \ cli/lightning-cli \ lightningd/lightningd \ tools/lightning-hsmtool\ + ) \ tools/reckless PKGLIBEXEC_PROGRAMS = \ + $(addprefix $(BUILDDIR)/, \ lightningd/lightning_channeld \ lightningd/lightning_closingd \ lightningd/lightning_connectd \ @@ -480,7 +502,8 @@ PKGLIBEXEC_PROGRAMS = \ lightningd/lightning_hsmd \ lightningd/lightning_onchaind \ lightningd/lightning_openingd \ - lightningd/lightning_websocketd + lightningd/lightning_websocketd \ + ) mkdocs.yml: $(MANPAGES:=.md) @$(call VERBOSE, "genidx $@", \ @@ -492,7 +515,7 @@ mkdocs.yml: $(MANPAGES:=.md) # Every single object file. -ALL_OBJS := $(ALL_C_SOURCES:.c=.o) +ALL_OBJS := $(ALL_C_SOURCES:%.c=$(BUILDDIR)/%.o) WIREGEN_FILES := $(filter %printgen.h %printgen.c %wiregen.h %wiregen.c, $(ALL_C_HEADERS) $(ALL_C_SOURCES)) @@ -764,11 +787,9 @@ TAGS: tags: $(RM) tags; find * -name test -type d -prune -o \( -name '*.[ch]' -o -name '*.py' \) -print0 | xargs -0 ctags --append -ccan/ccan/cdump/tools/cdump-enumstr: ccan/ccan/cdump/tools/cdump-enumstr.o libccan.a - -ALL_PROGRAMS += ccan/ccan/cdump/tools/cdump-enumstr +ALL_BUILD_PROGRAMS += $(CDUMP_ENUMSTR) # Can't add to ALL_OBJS, as that makes a circular dep. -ccan/ccan/cdump/tools/cdump-enumstr.o: $(CCAN_HEADERS) Makefile +$(CDUMP_ENUMSTR).o: $(CCAN_HEADERS) Makefile # Without a working git, you can't generate this file, so assume if it exists # it is ok (fixes "sudo make install"). @@ -782,29 +803,27 @@ version_gen.h: $(FORCE) @if cmp $@.new $@ >/dev/null 2>&1; then rm -f $@.new; else mv $@.new $@; $(ECHO) Version updated; fi endif -# That forces this rule to be run every time, too. -header_versions_gen.h: tools/headerversions $(FORCE) - @tools/headerversions $@ +header_versions_gen.h: $(BUILDDIR)/tools/headerversions $(FORCE) + @$< $@ # Once you have libccan.a, you don't need these. .INTERMEDIATE: $(CCAN_OBJS) # We make a static library, this way linker can discard unused parts. -libccan.a: $(CCAN_OBJS) - @$(call VERBOSE, "ar $@", $(AR) r $@ $(CCAN_OBJS)) +$(BUILDDIR)/libccan.a: $(BUILDDIR)/libccan.a($(CCAN_OBJS)) # All binaries require the external libs, ccan and system library versions. -$(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS) $(ALL_FUZZ_TARGETS): $(EXTERNAL_LIBS) libccan.a +$(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS) $(ALL_FUZZ_TARGETS): $(EXTERNAL_LIBS) $(BUILDDIR)/libccan.a -# Each test program depends on its own object. -$(ALL_TEST_PROGRAMS) $(ALL_FUZZ_TARGETS): %: %.o +# Each build-time program depends on its own object. +$(ALL_BUILD_PROGRAMS) $(ALL_TEST_PROGRAMS) $(ALL_FUZZ_TARGETS): %: %.o # Without this rule, the (built-in) link line contains # external/libwallycore.a directly, which causes a symbol clash (it # uses some ccan modules internally). We want to rely on -lwallycore etc. # (as per EXTERNAL_LDLIBS) so we filter them out here. We have to put the other # .a files (if any) at the end of the link line. -$(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS): +$(ALL_PROGRAMS) $(ALL_BUILD_PROGRAMS) $(ALL_TEST_PROGRAMS): @$(call VERBOSE, "ld $@", $(LINK.c) $(filter-out %.a,$^) $(filter-out external/%,$(filter %.a,$^)) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $($(@)_LDLIBS) -o $@) ifeq ($(OS),Darwin) @$(call VERBOSE, "dsymutil $@", dsymutil $@) @@ -826,7 +845,7 @@ endif endif $(ALL_FUZZ_TARGETS): - @$(call VERBOSE, "ld $@", $(LINK.c) $(filter-out %.a,$^) libcommon.a libccan.a $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $(FUZZ_LDFLAGS) -o $@) + @$(call VERBOSE, "ld $@", $(LINK.c) $(filter-out %.a,$^) $(addprefix $(BUILDDIR)/,libcommon.a libccan.a) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $(FUZZ_LDFLAGS) -o $@) ifeq ($(OS),Darwin) @$(call VERBOSE, "dsymutil $@", dsymutil $@) endif @@ -868,19 +887,22 @@ maintainer-clean: distclean # We used to have gen_ files, now we have _gen files. # We used to generate doc/schemas/lightning-sql.json. -obsclean: +# Build products used to land inside the source tree. +obsclean:: $(RM) gen_*.h */gen_*.[ch] */*/gen_*.[ch] $(RM) doc/schemas/lightning-sql.json + $(RM) libccan.a + $(RM) ccan/ccan/cdump/tools/cdump-enumstr ccan/ccan/cdump/tools/cdump-enumstr.o + $(RM) $(ALL_OBJS:$(BUILDDIR)/%=%) + $(RM) $(ALL_PROGRAMS:$(BUILDDIR)/%=%) + $(RM) $(ALL_TEST_PROGRAMS:$(BUILDDIR)/%=%) + $(RM) $(ALL_FUZZ_TARGETS:$(BUILDDIR)/%=%) clean: obsclean - $(RM) libccan.a $(CCAN_OBJS) $(CDUMP_OBJS) $(ALL_OBJS) + $(RM) -r $(BUILDDIR) $(RM) $(ALL_GEN_HEADERS) $(ALL_GEN_SOURCES) - $(RM) $(ALL_PROGRAMS) - $(RM) $(ALL_TEST_PROGRAMS) - $(RM) $(ALL_FUZZ_TARGETS) $(RM) $(MSGGEN_GEN_ALL) $(RM) ccan/tools/configurator/configurator - $(RM) ccan/ccan/cdump/tools/cdump-enumstr.o find . -name '*gcda' -delete find . -name '*gcno' -delete find . -name '*.nccout' -delete @@ -939,7 +961,7 @@ update-dot-version: update-mocks: $(ALL_TEST_PROGRAMS:%=update-mocks/%.c) -$(ALL_TEST_PROGRAMS:%=update-mocks/%.c): $(ALL_GEN_HEADERS) $(EXTERNAL_LIBS) libccan.a ccan/ccan/cdump/tools/cdump-enumstr config.vars +$(ALL_TEST_PROGRAMS:%=update-mocks/%.c): $(ALL_GEN_HEADERS) $(EXTERNAL_LIBS) $(BUILDDIR)/libccan.a $(CDUMP_ENUMSTR) config.vars update-mocks/%: % $(ALL_GEN_HEADERS) $(ALL_GEN_SOURCES) @MAKE=$(MAKE) SED=$(SED) tools/update-mocks.sh "$*" $(SUPPRESS_OUTPUT) @@ -1102,114 +1124,6 @@ clightning-$(VERSION)-$(DISTRO).tar.xz: install trap "rm -rf opt" 0; tar cvfa $@ opt/ endif -ccan-breakpoint.o: $(CCANDIR)/ccan/breakpoint/breakpoint.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-base64.o: $(CCANDIR)/ccan/base64/base64.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-tal.o: $(CCANDIR)/ccan/tal/tal.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-tal-str.o: $(CCANDIR)/ccan/tal/str/str.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-tal-link.o: $(CCANDIR)/ccan/tal/link/link.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-tal-path.o: $(CCANDIR)/ccan/tal/path/path.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-tal-grab_file.o: $(CCANDIR)/ccan/tal/grab_file/grab_file.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-take.o: $(CCANDIR)/ccan/take/take.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-list.o: $(CCANDIR)/ccan/list/list.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-asort.o: $(CCANDIR)/ccan/asort/asort.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-ptr_valid.o: $(CCANDIR)/ccan/ptr_valid/ptr_valid.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-read_write_all.o: $(CCANDIR)/ccan/read_write_all/read_write_all.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-str.o: $(CCANDIR)/ccan/str/str.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-opt.o: $(CCANDIR)/ccan/opt/opt.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-opt-helpers.o: $(CCANDIR)/ccan/opt/helpers.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-opt-parse.o: $(CCANDIR)/ccan/opt/parse.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-opt-usage.o: $(CCANDIR)/ccan/opt/usage.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-err.o: $(CCANDIR)/ccan/err/err.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-noerr.o: $(CCANDIR)/ccan/noerr/noerr.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-str-hex.o: $(CCANDIR)/ccan/str/hex/hex.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-crc32c.o: $(CCANDIR)/ccan/crc32c/crc32c.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-crypto-hmac.o: $(CCANDIR)/ccan/crypto/hmac_sha256/hmac_sha256.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-crypto-hkdf.o: $(CCANDIR)/ccan/crypto/hkdf_sha256/hkdf_sha256.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-crypto-shachain.o: $(CCANDIR)/ccan/crypto/shachain/shachain.c - @$(call VERBOSE, "cc $< -DSHACHAIN_BITS=48", $(COMPILE.c) -DSHACHAIN_BITS=48 -o $@ $<) -ccan-crypto-sha256.o: $(CCANDIR)/ccan/crypto/sha256/sha256.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-crypto-ripemd160.o: $(CCANDIR)/ccan/crypto/ripemd160/ripemd160.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-cdump.o: $(CCANDIR)/ccan/cdump/cdump.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-strmap.o: $(CCANDIR)/ccan/strmap/strmap.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-strset.o: $(CCANDIR)/ccan/strset/strset.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-crypto-siphash24.o: $(CCANDIR)/ccan/crypto/siphash24/siphash24.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-htable.o: $(CCANDIR)/ccan/htable/htable.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-ilog.o: $(CCANDIR)/ccan/ilog/ilog.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-intmap.o: $(CCANDIR)/ccan/intmap/intmap.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-isaac.o: $(CCANDIR)/ccan/isaac/isaac.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-isaac64.o: $(CCANDIR)/ccan/isaac/isaac64.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-time.o: $(CCANDIR)/ccan/time/time.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-timer.o: $(CCANDIR)/ccan/timer/timer.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-io-io.o: $(CCANDIR)/ccan/io/io.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-io-poll.o: $(CCANDIR)/ccan/io/poll.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-io-fdpass.o: $(CCANDIR)/ccan/io/fdpass/fdpass.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-pipecmd.o: $(CCANDIR)/ccan/pipecmd/pipecmd.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-mem.o: $(CCANDIR)/ccan/mem/mem.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-fdpass.o: $(CCANDIR)/ccan/fdpass/fdpass.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-bitops.o: $(CCANDIR)/ccan/bitops/bitops.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-rbuf.o: $(CCANDIR)/ccan/rbuf/rbuf.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-str-base32.o: $(CCANDIR)/ccan/str/base32/base32.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-utf8.o: $(CCANDIR)/ccan/utf8/utf8.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-bitmap.o: $(CCANDIR)/ccan/bitmap/bitmap.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-membuf.o: $(CCANDIR)/ccan/membuf/membuf.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-json_escape.o: $(CCANDIR)/ccan/json_escape/json_escape.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-json_out.o: $(CCANDIR)/ccan/json_out/json_out.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-closefrom.o: $(CCANDIR)/ccan/closefrom/closefrom.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-rune-rune.o: $(CCANDIR)/ccan/rune/rune.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) -ccan-rune-coding.o: $(CCANDIR)/ccan/rune/coding.c - @$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<) canned-gossmap: devtools/gossmap-compress DATE=`date +%Y-%m-%d` && devtools/gossmap-compress compress --output-node-map /tmp/gossip_store tests/data/gossip-store-$$DATE.compressed > tests/data/gossip-store-$$DATE-node-map && xz -9 tests/data/gossip-store-$$DATE-node-map && ls -l tests/data/gossip-store-$$DATE* @@ -1219,3 +1133,9 @@ print-binary-sizes: $(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS) $(BIN_PROGRAMS) @size -t $(PKGLIBEXEC_PROGRAMS) $(filter-out tools/reckless,$(BIN_PROGRAMS)) $(PLUGINS) @echo All programs: @size -t $(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS) | tail -n1 + +.SECONDEXPANSION: +# All rules beyond this point are subject to secondary expansion of their prerequisites! + +$(BUILDDIR)/%.o: %.c | $$(@D)/ + @$(call VERBOSE,"cc $<",$(COMPILE.c) -o $@ $<) diff --git a/bitcoin/Makefile b/bitcoin/Makefile index fcf30e9a2f76..d3891cfa036d 100644 --- a/bitcoin/Makefile +++ b/bitcoin/Makefile @@ -18,9 +18,10 @@ BITCOIN_SRC := \ bitcoin/tx_parts.c \ bitcoin/varint.c -BITCOIN_OBJS := $(BITCOIN_SRC:.c=.o) +BITCOIN_OBJS := $(BITCOIN_SRC:%.c=$(BUILDDIR)/%.o) -BITCOIN_HEADERS := bitcoin/address.h \ +BITCOIN_HEADERS := \ + bitcoin/address.h \ bitcoin/base58.h \ bitcoin/block.h \ bitcoin/chainparams.h \ @@ -57,9 +58,7 @@ check-bitcoin-makefile: check-whitespace: check-whitespace/bitcoin/Makefile -clean: bitcoin-clean - -bitcoin-clean: - $(RM) $(BITCOIN_OBJS) $(BITCOIN_TEST_PROGRAMS) $(BITCOIN_TEST_OBJS) +obsclean:: + $(RM) bitcoin/*.o include bitcoin/test/Makefile diff --git a/bitcoin/test/Makefile b/bitcoin/test/Makefile index eadb3ed3585b..bb4e03f58eab 100644 --- a/bitcoin/test/Makefile +++ b/bitcoin/test/Makefile @@ -1,14 +1,17 @@ BITCOIN_TEST_SRC := $(wildcard bitcoin/test/run-*.c) -BITCOIN_TEST_OBJS := $(BITCOIN_TEST_SRC:.c=.o) +BITCOIN_TEST_OBJS := $(BITCOIN_TEST_SRC:%.c=$(BUILDDIR)/%.o) BITCOIN_TEST_PROGRAMS := $(BITCOIN_TEST_OBJS:.o=) -$(BITCOIN_TEST_PROGRAMS): bitcoin/chainparams.o libcommon.a +$(BITCOIN_TEST_PROGRAMS): $(addprefix $(BUILDDIR)/,bitcoin/chainparams.o libcommon.a) $(BITCOIN_TEST_OBJS): $(BITCOIN_HEADERS) $(BITCOIN_SRC) bitcoin/test/Makefile ALL_TEST_PROGRAMS += $(BITCOIN_TEST_PROGRAMS) ALL_C_SOURCES += $(BITCOIN_TEST_PROGRAMS:=.c) # This needs to know what level of optimization we're using. -bitcoin/test/run-secret_eq_consttime.o: CFLAGS += -DCOPTFLAGS="\"${COPTFLAGS}\"" +$(BUILDDIR)/bitcoin/test/run-secret_eq_consttime.o: CPPFLAGS += -DCOPTFLAGS="\"${COPTFLAGS}\"" check-units: $(BITCOIN_TEST_PROGRAMS:%=unittest/%) + +obsclean:: + $(RM) bitcoin/test/*.o diff --git a/channeld/Makefile b/channeld/Makefile index a2c11e8bdda7..6c08b32362f5 100644 --- a/channeld/Makefile +++ b/channeld/Makefile @@ -18,25 +18,30 @@ CHANNELD_SRC := channeld/channeld.c \ channeld/channeld_wiregen.c \ channeld/watchtower.c -CHANNELD_OBJS := $(CHANNELD_SRC:.c=.o) +CHANNELD_OBJS := $(CHANNELD_SRC:%.c=$(BUILDDIR)/%.o) $(CHANNELD_OBJS): $(CHANNELD_HEADERS) # Make sure these depend on everything. ALL_C_SOURCES += $(CHANNELD_SRC) ALL_C_HEADERS += $(CHANNELD_HEADERS) -ALL_PROGRAMS += lightningd/lightning_channeld +ALL_PROGRAMS += $(BUILDDIR)/lightningd/lightning_channeld # Here's what lightningd depends on LIGHTNINGD_CONTROL_HEADERS += \ channeld/channeld_wiregen.h \ channeld/inflight.h -LIGHTNINGD_CONTROL_OBJS += \ +LIGHTNINGD_CONTROL_OBJS += \ + $(addprefix $(BUILDDIR)/, \ channeld/channeld_wiregen.o \ - channeld/inflight.o + channeld/inflight.o \ + ) -channeld/full_channel_error_names_gen.h: channeld/full_channel_error.h ccan/ccan/cdump/tools/cdump-enumstr - ccan/ccan/cdump/tools/cdump-enumstr channeld/full_channel_error.h > $@ +channeld/full_channel_error_names_gen.h: channeld/full_channel_error.h $(CDUMP_ENUMSTR) + $(CDUMP_ENUMSTR) channeld/full_channel_error.h > $@ -lightningd/lightning_channeld: $(CHANNELD_OBJS) $(HSMD_CLIENT_OBJS) libcommon.a +$(BUILDDIR)/lightningd/lightning_channeld: $(CHANNELD_OBJS) $(HSMD_CLIENT_OBJS) $(BUILDDIR)/libcommon.a + +obsclean:: + $(RM) channeld/*.o include channeld/test/Makefile diff --git a/channeld/test/Makefile b/channeld/test/Makefile index f683ec31b26f..0a5c45382246 100644 --- a/channeld/test/Makefile +++ b/channeld/test/Makefile @@ -1,17 +1,18 @@ # Note that these actually #include everything they need, except ccan/ and bitcoin/. # That allows for unit testing of statics, and special effects. CHANNELD_TEST_SRC := $(wildcard channeld/test/run-*.c) -CHANNELD_TEST_OBJS := $(CHANNELD_TEST_SRC:.c=.o) +CHANNELD_TEST_OBJS := $(CHANNELD_TEST_SRC:%.c=$(BUILDDIR)/%.o) CHANNELD_TEST_PROGRAMS := $(CHANNELD_TEST_OBJS:.o=) ALL_C_SOURCES += $(CHANNELD_TEST_SRC) ALL_TEST_PROGRAMS += $(CHANNELD_TEST_PROGRAMS) # run-full_channel.o needs a special version of some common files! -$(filter-out channeld/test/run-full_channel,$(CHANNELD_TEST_PROGRAMS)): libcommon.a +$(filter-out channeld/test/run-full_channel,$(CHANNELD_TEST_PROGRAMS)): $(BUILDDIR)/libcommon.a -channeld/test/run-full_channel: \ +$(BUILDDIR)/channeld/test/run-full_channel: \ $(BITCOIN_OBJS) \ + $(addprefix $(BUILDDIR)/, \ wire/towire.o \ wire/fromwire.o \ common/amount.o \ @@ -29,8 +30,12 @@ channeld/test/run-full_channel: \ common/pseudorand.o \ common/randbytes.o \ common/setup.o \ - common/utils.o + common/utils.o \ + ) $(CHANNELD_TEST_OBJS): $(CHANNELD_HEADERS) $(CHANNELD_SRC) channeld/test/Makefile +obsclean:: + $(RM) channeld/test/*.o + check-units: $(CHANNELD_TEST_PROGRAMS:%=unittest/%) diff --git a/cli/Makefile b/cli/Makefile index 4839e5138344..473f4f6fee94 100644 --- a/cli/Makefile +++ b/cli/Makefile @@ -1,12 +1,15 @@ LIGHTNING_CLI_SRC := cli/lightning-cli.c -LIGHTNING_CLI_OBJS := $(LIGHTNING_CLI_SRC:.c=.o) +LIGHTNING_CLI_OBJS := $(LIGHTNING_CLI_SRC:%.c=$(BUILDDIR)/%.o) ALL_C_SOURCES += $(LIGHTNING_CLI_SRC) ALL_C_HEADERS += -ALL_PROGRAMS += cli/lightning-cli +ALL_PROGRAMS += $(BUILDDIR)/cli/lightning-cli $(LIGHTNING_CLI_OBJS): cli/Makefile -cli/lightning-cli: $(LIGHTNING_CLI_OBJS) libcommon.a +$(BUILDDIR)/cli/lightning-cli: $(LIGHTNING_CLI_OBJS) $(BUILDDIR)/libcommon.a + +obsclean:: + $(RM) cli/*.o include cli/test/Makefile diff --git a/cli/test/Makefile b/cli/test/Makefile index d6dcffb787ce..079b5a6698d1 100644 --- a/cli/test/Makefile +++ b/cli/test/Makefile @@ -1,14 +1,17 @@ # Note that these actually #include everything they need, except ccan/ and bitcoin/. # That allows for unit testing of statics, and special effects. CLI_TEST_SRC := $(wildcard cli/test/run-*.c) -CLI_TEST_OBJS := $(CLI_TEST_SRC:.c=.o) +CLI_TEST_OBJS := $(CLI_TEST_SRC:%.c=$(BUILDDIR)/%.o) CLI_TEST_PROGRAMS := $(CLI_TEST_OBJS:.o=) ALL_C_SOURCES += $(CLI_TEST_SRC) ALL_TEST_PROGRAMS += $(CLI_TEST_PROGRAMS) -$(CLI_TEST_PROGRAMS): libcommon.a +$(CLI_TEST_PROGRAMS): $(BUILDDIR)/libcommon.a $(CLI_TEST_OBJS): $(LIGHTNING_CLI_HEADERS) $(LIGHTNING_CLI_SRC) cli/test/Makefile check-units: $(CLI_TEST_PROGRAMS:%=unittest/%) + +obsclean:: + $(RM) cli/test/*.o diff --git a/closingd/Makefile b/closingd/Makefile index a128163f2756..9eabb0a61280 100644 --- a/closingd/Makefile +++ b/closingd/Makefile @@ -5,7 +5,7 @@ CLOSINGD_HEADERS := closingd/closingd_wiregen.h CLOSINGD_SRC := closingd/closingd.c \ $(CLOSINGD_HEADERS:.h=.c) -CLOSINGD_OBJS := $(CLOSINGD_SRC:.c=.o) +CLOSINGD_OBJS := $(CLOSINGD_SRC:%.c=$(BUILDDIR)/%.o) $(CLOSINGD_OBJS): $(CLOSINGD_HEADERS) # Simple close daemon @@ -14,20 +14,23 @@ SIMPLECLOSED_HEADERS := closingd/simpleclosed_wiregen.h SIMPLECLOSED_SRC := closingd/simpleclosed.c \ $(SIMPLECLOSED_HEADERS:.h=.c) -SIMPLECLOSED_OBJS := $(SIMPLECLOSED_SRC:.c=.o) +SIMPLECLOSED_OBJS := $(SIMPLECLOSED_SRC:%.c=$(BUILDDIR)/%.o) $(SIMPLECLOSED_OBJS): $(SIMPLECLOSED_HEADERS) # Make sure these depend on everything. ALL_C_SOURCES += $(CLOSINGD_SRC) $(SIMPLECLOSED_SRC) ALL_C_HEADERS += $(CLOSINGD_HEADERS) $(SIMPLECLOSED_HEADERS) -ALL_PROGRAMS += lightningd/lightning_closingd lightningd/lightning_simpleclosed +ALL_PROGRAMS += $(addprefix $(BUILDDIR)/lightningd/,lightning_closingd lightning_simpleclosed) # Here's what lightningd depends on LIGHTNINGD_CONTROL_HEADERS += closingd/closingd_wiregen.h closingd/simpleclosed_wiregen.h -LIGHTNINGD_CONTROL_OBJS += closingd/closingd_wiregen.o closingd/simpleclosed_wiregen.o +LIGHTNINGD_CONTROL_OBJS += $(addprefix $(BUILDDIR)/closingd/,closingd_wiregen.o simpleclosed_wiregen.o) -lightningd/lightning_closingd: $(CLOSINGD_OBJS) $(HSMD_CLIENT_OBJS) libcommon.a +$(BUILDDIR)/lightningd/lightning_closingd: $(CLOSINGD_OBJS) $(HSMD_CLIENT_OBJS) $(BUILDDIR)/libcommon.a -lightningd/lightning_simpleclosed: $(SIMPLECLOSED_OBJS) $(HSMD_CLIENT_OBJS) libcommon.a +$(BUILDDIR)/lightningd/lightning_simpleclosed: $(SIMPLECLOSED_OBJS) $(HSMD_CLIENT_OBJS) $(BUILDDIR)/libcommon.a + +obsclean:: + $(RM) closingd/*.o -include closingd/test/Makefile diff --git a/common/Makefile b/common/Makefile index d60606420807..7fa4a87b8bea 100644 --- a/common/Makefile +++ b/common/Makefile @@ -132,7 +132,7 @@ COMMON_HEADERS_GEN := common/htlc_state_names_gen.h common/status_wiregen.h comm COMMON_HEADERS := $(COMMON_HEADERS_GEN) $(COMMON_HEADERS_NOGEN) COMMON_SRC := $(COMMON_SRC_NOGEN) $(COMMON_SRC_GEN) -COMMON_OBJS := $(COMMON_SRC:.c=.o) +COMMON_OBJS := $(COMMON_SRC:%.c=$(BUILDDIR)/%.o) common/scb_wiregen.h_args := -s common/scb_wiregen.c_args := -s @@ -145,28 +145,29 @@ check-common-files: check-source: check-common-files # Only common/version.c can include this header. -common/version.o: version_gen.h +$(BUILDDIR)/common/version.o: version_gen.h # Rebuild objects should this file change. $(COMMON_OBJS): common/Makefile # We make a static library, this way linker can discard unused parts. -libcommon.a: $(COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) - @$(call VERBOSE, "ar $@", $(AR) r $@ $?) +$(BUILDDIR)/libcommon.a: $(BUILDDIR)/libcommon.a($(COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS)) ALL_C_HEADERS += $(COMMON_HEADERS) ALL_C_SOURCES += $(COMMON_SRC) -common/htlc_state_names_gen.h: common/htlc_state.h ccan/ccan/cdump/tools/cdump-enumstr - ccan/ccan/cdump/tools/cdump-enumstr common/htlc_state.h > $@ +common/htlc_state_names_gen.h: common/htlc_state.h $(CDUMP_ENUMSTR) + $(CDUMP_ENUMSTR) common/htlc_state.h > $@ check-source-bolt: $(COMMON_SRC_NOGEN:%=bolt-check/%) $(COMMON_HEADERS_NOGEN:%=bolt-check/%) check-whitespace: $(COMMON_SRC_NOGEN:%=check-whitespace/%) $(COMMON_HEADERS_NOGEN:%=check-whitespace/%) clean: common-clean +obsclean:: + $(RM) libcommon.a common/*.o + common-clean: - $(RM) libcommon.a $(RM) common/gen* include common/test/Makefile diff --git a/common/test/Makefile b/common/test/Makefile index 71f9dc17d981..9588a5726c06 100644 --- a/common/test/Makefile +++ b/common/test/Makefile @@ -1,14 +1,16 @@ COMMON_TEST_SRC := $(wildcard common/test/run-*.c) -COMMON_TEST_OBJS := $(COMMON_TEST_SRC:.c=.o) +COMMON_TEST_OBJS := $(COMMON_TEST_SRC:%.c=$(BUILDDIR)/%.o) COMMON_TEST_PROGRAMS := $(COMMON_TEST_OBJS:.o=) COMMON_TEST_COMMON_OBJS := \ + $(addprefix $(BUILDDIR)/, \ common/autodata.o \ common/randbytes.o \ common/clock_time.o \ common/setup.o \ - common/utils.o + common/utils.o \ + ) $(COMMON_TEST_PROGRAMS): $(COMMON_TEST_COMMON_OBJS) $(BITCOIN_OBJS) $(COMMON_TEST_OBJS): $(COMMON_HEADERS) $(WIRE_HEADERS) $(COMMON_SRC) common/test/Makefile @@ -20,13 +22,14 @@ ALL_TEST_PROGRAMS += $(COMMON_TEST_PROGRAMS) $(COMMON_TEST_OBJS): $(COMMON_SRC) # Sphinx test wants to decode TLVs. -common/test/run-sphinx: wire/onion_wiregen.o wire/towire.o wire/fromwire.o -common/test/run-blindedpath_enctlv common/test/run-blindedpath_onion: common/base32.o common/wireaddr.o wire/onion_wiregen.o wire/peer_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o -common/test/run-route_blinding_test: wire/onion_wiregen.o wire/peer_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o common/coin_mvt.o -common/test/run-route_blinding_override_test: common/base32.o common/wireaddr.o wire/onion_wiregen.o wire/peer_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o common/coin_mvt.o - -common/test/run-param \ -common/test/run-json: \ +$(BUILDDIR)/common/test/run-sphinx: $(addprefix $(BUILDDIR)/,wire/onion_wiregen.o wire/towire.o wire/fromwire.o) +$(BUILDDIR)/common/test/run-blindedpath_enctlv $(BUILDDIR)/common/test/run-blindedpath_onion: $(addprefix $(BUILDDIR)/,common/base32.o common/wireaddr.o wire/onion_wiregen.o wire/peer_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o) +$(BUILDDIR)/common/test/run-route_blinding_test: $(addprefix $(BUILDDIR)/,wire/onion_wiregen.o wire/peer_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o common/coin_mvt.o) +$(BUILDDIR)/common/test/run-route_blinding_override_test: $(addprefix $(BUILDDIR)/,common/base32.o common/wireaddr.o wire/onion_wiregen.o wire/peer_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o common/coin_mvt.o) + +$(BUILDDIR)/common/test/run-param \ +$(BUILDDIR)/common/test/run-json: \ + $(addprefix $(BUILDDIR)/, \ common/amount.o \ common/base32.o \ common/bigsize.o \ @@ -41,9 +44,13 @@ common/test/run-json: \ wire/fromwire.o \ wire/onion_wiregen.o \ wire/peer_wiregen.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-route common/test/run-route-specific common/test/run-route-infloop: \ +$(BUILDDIR)/common/test/run-route \ +$(BUILDDIR)/common/test/run-route-specific \ +$(BUILDDIR)/common/test/run-route-infloop: \ + $(addprefix $(BUILDDIR)/, \ common/amount.o \ common/dijkstra.o \ common/fp16.o \ @@ -55,25 +62,31 @@ common/test/run-route common/test/run-route-specific common/test/run-route-inflo common/gossip_store_wiregen.o \ wire/fromwire.o \ wire/peer_wiregen.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-gossmap_local: \ +$(BUILDDIR)/common/test/run-gossmap_local: \ + $(addprefix $(BUILDDIR)/, \ common/base32.o \ common/wireaddr.o \ wire/fromwire.o \ wire/peer_wiregen.o \ wire/tlvstream.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-gossmap_canned: \ +$(BUILDDIR)/common/test/run-gossmap_canned: \ + $(addprefix $(BUILDDIR)/, \ common/base32.o \ common/wireaddr.o \ wire/fromwire.o \ wire/peer_wiregen.o \ wire/tlvstream.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-bolt12_merkle: \ +$(BUILDDIR)/common/test/run-bolt12_merkle: \ + $(addprefix $(BUILDDIR)/, \ common/amount.o \ common/bigsize.o \ common/base32.o \ @@ -86,9 +99,11 @@ common/test/run-bolt12_merkle: \ wire/fromwire.o \ wire/tlvstream.o \ wire/peer_wiregen.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-bolt12_merkle-partial: \ +$(BUILDDIR)/common/test/run-bolt12_merkle-partial: \ + $(addprefix $(BUILDDIR)/, \ common/amount.o \ common/bigsize.o \ common/base32.o \ @@ -101,9 +116,11 @@ common/test/run-bolt12_merkle-partial: \ wire/fromwire.o \ wire/tlvstream.o \ wire/peer_wiregen.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-bolt12-format-string-test: \ +$(BUILDDIR)/common/test/run-bolt12-format-string-test: \ + $(addprefix $(BUILDDIR)/, \ common/amount.o \ common/bigsize.o \ common/base32.o \ @@ -113,13 +130,18 @@ common/test/run-bolt12-format-string-test: \ common/node_id.o \ wire/bolt12_wiregen.o \ wire/tlvstream.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-bolt12_merkle-json: \ +$(BUILDDIR)/common/test/run-bolt12_merkle-json: \ + $(addprefix $(BUILDDIR)/, \ common/base32.o \ - common/wireaddr.o + common/wireaddr.o \ + ) -common/test/run-bolt12_proof common/test/run-bolt12_proof_vectors: \ +$(BUILDDIR)/common/test/run-bolt12_proof \ +$(BUILDDIR)/common/test/run-bolt12_proof_vectors: \ + $(addprefix $(BUILDDIR)/, \ common/bolt12.o \ common/bigsize.o \ common/amount.o \ @@ -128,15 +150,19 @@ common/test/run-bolt12_proof common/test/run-bolt12_proof_vectors: \ wire/onion_wiregen.o \ wire/tlvstream.o \ wire/fromwire.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-version: \ +$(BUILDDIR)/common/test/run-version: \ + $(addprefix $(BUILDDIR)/, \ common/amount.o \ wire/fromwire.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-splice_script: \ +$(BUILDDIR)/common/test/run-splice_script: \ + $(addprefix $(BUILDDIR)/, \ common/amount.o \ common/node_id.o \ common/bech32.o \ @@ -144,38 +170,61 @@ common/test/run-splice_script: \ common/wireaddr.o \ common/base32.o \ wire/fromwire.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-trace: \ +$(BUILDDIR)/common/test/run-trace: \ + $(addprefix $(BUILDDIR)/, \ common/amount.o \ common/memleak.o \ common/pseudorand.o \ common/randbytes.o \ common/trace.o \ wire/fromwire.o \ - wire/towire.o + wire/towire.o \ + ) -common/test/run-mkdatastorekey: \ - common/pseudorand.o +$(BUILDDIR)/common/test/run-mkdatastorekey: \ + $(addprefix $(BUILDDIR)/, \ + common/pseudorand.o \ + ) -common/test/run-htable: \ +$(BUILDDIR)/common/test/run-htable: \ + $(addprefix $(BUILDDIR)/, \ common/randbytes.o \ - common/pseudorand.o + common/pseudorand.o \ + ) -common/test/run-shutdown_scriptpubkey: wire/towire.o wire/fromwire.o +$(BUILDDIR)/common/test/run-shutdown_scriptpubkey: \ + $(addprefix $(BUILDDIR)/, \ + wire/towire.o \ + wire/fromwire.o \ + ) -common/test/run-wireaddr: wire/towire.o wire/fromwire.o +$(BUILDDIR)/common/test/run-wireaddr: \ + $(addprefix $(BUILDDIR)/, \ + wire/towire.o \ + wire/fromwire.o \ + ) -common/test/run-jsonrpc_io: common/json_parse_simple.o +$(BUILDDIR)/common/test/run-jsonrpc_io: \ + $(addprefix $(BUILDDIR)/, \ + common/json_parse_simple.o \ + ) -common/test/run-close_tx: \ +$(BUILDDIR)/common/test/run-close_tx: \ + $(addprefix $(BUILDDIR)/, \ common/amount.o \ common/close_tx.o \ common/permute_tx.o \ common/psbt_keypath.o \ common/pseudorand.o \ wire/fromwire.o \ - wire/towire.o + wire/towire.o \ + ) check-units: $(COMMON_TEST_PROGRAMS:%=unittest/%) + +obsclean:: + $(RM) common/test/*.o diff --git a/connectd/Makefile b/connectd/Makefile index 4cec6fdde40f..653cf0f19de2 100644 --- a/connectd/Makefile +++ b/connectd/Makefile @@ -16,27 +16,30 @@ CONNECTD_HEADERS := connectd/connectd_wiregen.h \ CONNECTD_SRC := $(CONNECTD_HEADERS:.h=.c) connectd/connectd.c -CONNECTD_OBJS := $(CONNECTD_SRC:.c=.o) +CONNECTD_OBJS := $(CONNECTD_SRC:%.c=$(BUILDDIR)/%.o) $(CONNECTD_OBJS): $(CONNECTD_HEADERS) WEBSOCKETD_HEADERS := connectd/sha1.h WEBSOCKETD_SRC := $(WEBSOCKETD_HEADERS:.h=.c) connectd/websocketd.c -WEBSOCKETD_OBJS := $(WEBSOCKETD_SRC:.c=.o) +WEBSOCKETD_OBJS := $(WEBSOCKETD_SRC:%.c=$(BUILDDIR)/%.o) $(WEBSOCKETD_OBJS): $(WEBSOCKETD_HEADERS) # Make sure these depend on everything. ALL_C_SOURCES += $(CONNECTD_SRC) $(WEBSOCKETD_SRC) ALL_C_HEADERS += $(CONNECTD_HEADERS) $(WEBSOCKETD_HEADERS) -ALL_PROGRAMS += lightningd/lightning_connectd -ALL_PROGRAMS += lightningd/lightning_websocketd +ALL_PROGRAMS += $(BUILDDIR)/lightningd/lightning_connectd +ALL_PROGRAMS += $(BUILDDIR)/lightningd/lightning_websocketd # Here's what lightningd depends on LIGHTNINGD_CONTROL_HEADERS += connectd/connectd_wiregen.h -LIGHTNINGD_CONTROL_OBJS += connectd/connectd_wiregen.o +LIGHTNINGD_CONTROL_OBJS += $(BUILDDIR)/connectd/connectd_wiregen.o -lightningd/lightning_connectd: $(CONNECTD_OBJS) $(HSMD_CLIENT_OBJS) gossipd/gossipd_wiregen.o libcommon.a +$(BUILDDIR)/lightningd/lightning_connectd: $(CONNECTD_OBJS) $(HSMD_CLIENT_OBJS) $(addprefix $(BUILDDIR)/,gossipd/gossipd_wiregen.o libcommon.a) -lightningd/lightning_websocketd: $(WEBSOCKETD_OBJS) libcommon.a +$(BUILDDIR)/lightningd/lightning_websocketd: $(WEBSOCKETD_OBJS) $(BUILDDIR)/libcommon.a + +obsclean:: + $(RM) connectd/*.o include connectd/test/Makefile diff --git a/connectd/test/Makefile b/connectd/test/Makefile index 3bdb1c380642..ed015f4505fb 100644 --- a/connectd/test/Makefile +++ b/connectd/test/Makefile @@ -1,13 +1,13 @@ # Note that these actually #include everything they need, except ccan/ and bitcoin/. # That allows for unit testing of statics, and special effects. CONNECTD_TEST_SRC := $(wildcard connectd/test/run-*.c) -CONNECTD_TEST_OBJS := $(CONNECTD_TEST_SRC:.c=.o) +CONNECTD_TEST_OBJS := $(CONNECTD_TEST_SRC:%.c=$(BUILDDIR)/%.o) CONNECTD_TEST_PROGRAMS := $(CONNECTD_TEST_OBJS:.o=) ALL_C_SOURCES += $(CONNECTD_TEST_SRC) ALL_TEST_PROGRAMS += $(CONNECTD_TEST_PROGRAMS) -$(CONNECTD_TEST_PROGRAMS): libcommon.a +$(CONNECTD_TEST_PROGRAMS): $(BUILDDIR)/libcommon.a # Test objects depend on ../ src and headers. $(CONNECTD_TEST_OBJS): $(CONNECTD_HEADERS) $(CONNECTD_SRC) $(WEBSOCKETD_HEADERS) $(WEBSOCKETD_SRC) connectd/test/Makefile diff --git a/db/Makefile b/db/Makefile index 43380acd6245..f3f8cb82f790 100644 --- a/db/Makefile +++ b/db/Makefile @@ -12,7 +12,7 @@ DB_DRIVERS := \ DB_SRC := $(DB_LIB_SRC) $(DB_DRIVERS) DB_HEADERS := $(DB_LIB_SRC:.c=.h) db/common.h -DB_OBJS := $(DB_LIB_SRC:.c=.o) $(DB_DRIVERS:.c=.o) +DB_OBJS := $(addprefix $(BUILDDIR)/,$(DB_LIB_SRC:.c=.o) $(DB_DRIVERS:.c=.o)) $(DB_OBJS): $(DB_HEADERS) # Make sure these depend on everything. diff --git a/devtools/Makefile b/devtools/Makefile index 5488f162fba1..c6f35ec042df 100644 --- a/devtools/Makefile +++ b/devtools/Makefile @@ -1,10 +1,10 @@ -DEVTOOLS := devtools/bolt11-cli devtools/decodemsg devtools/onion devtools/dump-gossipstore devtools/gossipwith devtools/create-gossipstore devtools/mkcommit devtools/mkfunding devtools/mkclose devtools/mkgossip devtools/mkencoded devtools/mkquery devtools/lightning-checkmessage devtools/topology devtools/route devtools/bolt12-cli devtools/encodeaddr devtools/features devtools/fp16 devtools/rune devtools/gossmap-compress devtools/bip137-verifysignature devtools/convert-gossmap +DEVTOOLS := $(addprefix $(BUILDDIR)/devtools/,bolt11-cli decodemsg onion dump-gossipstore gossipwith create-gossipstore mkcommit mkfunding mkclose mkgossip mkencoded mkquery lightning-checkmessage topology route bolt12-cli encodeaddr features fp16 rune gossmap-compress bip137-verifysignature convert-gossmap) ifeq ($(HAVE_SQLITE3),1) -DEVTOOLS += devtools/checkchannels +DEVTOOLS += $(BUILDDIR)/devtools/checkchannels endif -DEVTOOLS_TOOL_SRC := $(DEVTOOLS:=.c) devtools/print_wire.c devtools/clean_topo.c -DEVTOOLS_TOOL_OBJS := $(DEVTOOLS_TOOL_SRC:.c=.o) +DEVTOOLS_TOOL_SRC := $(DEVTOOLS:$(BUILDDIR)/%=%.c) devtools/print_wire.c devtools/clean_topo.c +DEVTOOLS_TOOL_OBJS := $(DEVTOOLS_TOOL_SRC:%.c=$(BUILDDIR)/%.o) # Make sure these depend on everything. ALL_C_SOURCES += $(DEVTOOLS_TOOL_SRC) @@ -16,15 +16,15 @@ ifeq ($(HAVE_ZLIB),1) devtools/gossmap-compress_LDLIBS=-lz endif # ZLIB -$(DEVTOOLS): %: %.o libcommon.a +$(DEVTOOLS): %: %.o $(BUILDDIR)/libcommon.a $(DEVTOOLS_TOOL_OBJS): wire/wire.h # Some devtools require extra objects -devtools/decodemsg: devtools/print_wire.o -devtools/decodemsg.o: devtools/print_wire.h +$(BUILDDIR)/devtools/decodemsg: $(BUILDDIR)/devtools/print_wire.o +$(BUILDDIR)/devtools/decodemsg.o: devtools/print_wire.h -devtools/mkcommit: channeld/full_channel.o channeld/commit_tx.o -devtools/mkcommit.o: channeld/full_channel.h channeld/commit_tx.h +$(BUILDDIR)/devtools/mkcommit: $(addprefix $(BUILDDIR)/channeld/,full_channel.o commit_tx.o) +$(BUILDDIR)/devtools/mkcommit.o: channeld/full_channel.h channeld/commit_tx.h -devtools/route devtools/topology: devtools/clean_topo.o -devtools/route.o devtools/topology.o: devtools/clean_topo.h +$(BUILDDIR)/devtools/route $(BUILDDIR)/devtools/topology: $(BUILDDIR)/devtools/clean_topo.o +$(BUILDDIR)/devtools/route.o $(BUILDDIR)/devtools/topology.o: devtools/clean_topo.h diff --git a/doc/Makefile b/doc/Makefile index 2775eb1c9c49..b5912c5a2096 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -204,8 +204,8 @@ OLD_MARKDOWNPAGES_WITH_EXT := $(PREFIXED_MANPAGES:=.md) # - Read the json template from schemas/sql-template.json # - Generate the tables schema via plugins/sql # - Merge both and generate final schemas/sql.json -doc/schemas/sql.json: doc/schemas/sql-template.json plugins/sql - @plugins/sql --print-docs | jq --arg sqldata "$$(awk '{printf "%s\n", $$0}')" '.tables += [$$sqldata]' $< > "$@.tmp" && mv "$@.tmp" "$@"; +doc/schemas/sql.json: doc/schemas/sql-template.json $(BUILDDIR)/plugins/sql + @$(BUILDDIR)/plugins/sql --print-docs | jq --arg sqldata "$$(awk '{printf "%s\n", $$0}')" '.tables += [$$sqldata]' $< > "$@.tmp" && mv "$@.tmp" "$@"; doc-all: $(MANPAGES) doc/index.rst diff --git a/external/Makefile b/external/Makefile index 4ff220539eb5..e3e3306f5567 100644 --- a/external/Makefile +++ b/external/Makefile @@ -7,9 +7,6 @@ SUBMODULES = \ TOP := ../.. ifdef BUILD CROSSCOMPILE_OPTS := --host="$(MAKE_HOST)" --build="$(BUILD)" -TARGET_DIR := external/build-$(MAKE_HOST) -else -TARGET_DIR := external/build-$(shell ${CC} -dumpmachine) endif LIBWALLY_HEADERS := external/libwally-core/include/wally_bip32.h \ @@ -24,7 +21,7 @@ GHEAP_HEADERS := external/gheap/gheap.h LIBBACKTRACE_HEADERS := external/libbacktrace/backtrace.h EXTERNAL_HEADERS := $(LIBWALLY_HEADERS) $(LIBSECP_HEADERS) $(JSMN_HEADERS) $(GHEAP_HEADERS) $(LIBBACKTRACE_HEADERS) -EXTERNAL_LIBS := ${TARGET_DIR}/libwallycore.a ${TARGET_DIR}/libsecp256k1.a ${TARGET_DIR}/libjsmn.a ${TARGET_DIR}/libbacktrace.a +EXTERNAL_LIBS := $(addprefix $(BUILDDIR)/external/,libwallycore.a libsecp256k1.a libjsmn.a libbacktrace.a) EXTERNAL_INCLUDE_FLAGS := \ -I external/libwally-core/include/ \ @@ -32,7 +29,7 @@ EXTERNAL_INCLUDE_FLAGS := \ -I external/jsmn/ \ -I external/libbacktrace/ \ -I external/gheap/ \ - -I ${TARGET_DIR}/libbacktrace-build + -I $(BUILDDIR)/external/libbacktrace-build LDLIBS += $(SODIUM_LDLIBS) @@ -40,7 +37,7 @@ ifeq ($(HAVE_ZLIB),1) LDLIBS += -lz endif -EXTERNAL_LDLIBS := -L${TARGET_DIR} $(patsubst lib%.a,-l%,$(notdir $(EXTERNAL_LIBS))) +EXTERNAL_LDLIBS := -L$(BUILDDIR)/external $(patsubst lib%.a,-l%,$(notdir $(EXTERNAL_LIBS))) .PHONY: submodcheck @@ -54,20 +51,20 @@ $(EXTERNAL_HEADERS): submodcheck # libsecp included in libwally. # Wildcards here are magic. See http://stackoverflow.com/questions/2973445/gnu-makefile-rule-generating-a-few-targets-from-a-single-source-file -$(TARGET_DIR)/libsecp256k1.% $(TARGET_DIR)/libwallycore.%: $(TARGET_DIR)/libwally-core-build/src/secp256k1/libsecp256k1.la $(TARGET_DIR)/libwally-core-build/src/libwallycore.la - $(MAKE) -C $(TARGET_DIR)/libwally-core-build DESTDIR=$$(pwd)/$(TARGET_DIR) install-exec +$(BUILDDIR)/external/libsecp256k1.% $(BUILDDIR)/external/libwallycore.%: $(BUILDDIR)/external/libwally-core-build/src/secp256k1/libsecp256k1.la $(BUILDDIR)/external/libwally-core-build/src/libwallycore.la + $(MAKE) -C $(BUILDDIR)/external/libwally-core-build DESTDIR=$$(pwd)/$(BUILDDIR)/external install-exec # Build libwally-core. ifeq ($(DEBUGBUILD),1) WALLY_OPTS=--enable-debug endif -.INTERMEDIATE: $(TARGET_DIR)/libwally-core-build/src/secp256k1/libsecp256k1.la $(TARGET_DIR)/libwally-core-build/src/libwallycore.la +.INTERMEDIATE: $(addprefix $(BUILDDIR)/external/libwally-core-build/src/,secp256k1/libsecp256k1.la libwallycore.la) -$(TARGET_DIR)/libwally-core-build/src/libwallycore.% $(TARGET_DIR)/libwally-core-build/src/secp256k1/libsecp256k1.%: $(LIBWALLY_HEADERS) $(LIBSECP_HEADERS) +$(BUILDDIR)/external/libwally-core-build/src/libwallycore.% $(BUILDDIR)/external/libwally-core-build/src/secp256k1/libsecp256k1.%: $(LIBWALLY_HEADERS) $(LIBSECP_HEADERS) cd external/libwally-core && ./tools/autogen.sh - mkdir -p ${TARGET_DIR}/libwally-core-build - cd ${TARGET_DIR}/libwally-core-build \ + $(MKDIR_P) $(BUILDDIR)/external/libwally-core-build + cd $(BUILDDIR)/external/libwally-core-build \ && PYTHON_VERSION=3 CFLAGS="-std=c99 $(FUZZFLAGS)" LDFLAGS="$(FUZZFLAGS)" ${TOP}/libwally-core/configure CC="$(CC)" \ --enable-static=yes \ $(CROSSCOMPILE_OPTS) \ @@ -82,28 +79,28 @@ $(TARGET_DIR)/libwally-core-build/src/libwallycore.% $(TARGET_DIR)/libwally-core external/jsmn/jsmn.c: external/jsmn/jsmn.h [ -f $@ ] -$(TARGET_DIR)/jsmn-build/jsmn.o: external/jsmn/jsmn.c Makefile +$(BUILDDIR)/external/jsmn-build/jsmn.o: external/jsmn/jsmn.c Makefile @mkdir -p $(@D) $(COMPILE.c) -DJSMN_STRICT=1 -o $@ $< -$(TARGET_DIR)/libjsmn.a: $(TARGET_DIR)/jsmn-build/jsmn.o +$(BUILDDIR)/external/libjsmn.a: $(BUILDDIR)/external/jsmn-build/jsmn.o $(AR) rc $@ $< -.INTERMEDIATE: $(TARGET_DIR)/jsmn-build/jsmn.o +.INTERMEDIATE: $(BUILDDIR)/external/jsmn-build/jsmn.o # Need separate build dir: changes inside submodule make git think it's dirty. -$(TARGET_DIR)/libbacktrace.a: external/libbacktrace/backtrace.h - mkdir -p $(TARGET_DIR)/libbacktrace-build - cd $(TARGET_DIR)/libbacktrace-build && $(TOP)/libbacktrace/configure CC="$(CC)" --enable-static=yes $(CROSSCOMPILE_OPTS) --enable-shared=no --prefix=/ --libdir=/ && $(MAKE) - $(MAKE) -C $(TARGET_DIR)/libbacktrace-build DESTDIR=$$(pwd)/$(TARGET_DIR) install-exec +$(BUILDDIR)/external/libbacktrace.a: external/libbacktrace/backtrace.h + mkdir -p $(BUILDDIR)/external/libbacktrace-build + cd $(BUILDDIR)/external/libbacktrace-build && $(TOP)/libbacktrace/configure CC="$(CC)" --enable-static=yes $(CROSSCOMPILE_OPTS) --enable-shared=no --prefix=/ --libdir=/ && $(MAKE) + $(MAKE) -C $(BUILDDIR)/external/libbacktrace-build DESTDIR=$$(pwd)/$(BUILDDIR)/external install-exec distclean: external-distclean clean: external-clean external-clean: $(RM) $(EXTERNAL_LIBS) - $(RM) -rf $(TARGET_DIR) + $(RM) -r $(BUILDDIR)/external external-distclean: - $(RM) -rf ${TARGET_DIR}/libbacktrace-build ${TARGET_DIR}/libsodium-build ${TARGET_DIR}/libwally-core-build ${TARGET_DIR}/jsmn-build + $(RM) -r $(addprefix $(BUILDDIR)/external/,libbacktrace-build libsodium-build libwally-core-build jsmn-build) $(RM) -r `git status --ignored --porcelain external/libwally-core | grep '^!! ' | cut -c3-` diff --git a/gossipd/Makefile b/gossipd/Makefile index 6ca4bbbef0ad..5189ac9b7fe8 100644 --- a/gossipd/Makefile +++ b/gossipd/Makefile @@ -11,29 +11,26 @@ GOSSIPD_HEADERS_WSRC := gossipd/gossipd_wiregen.h \ GOSSIPD_HEADERS := $(GOSSIPD_HEADERS_WSRC) GOSSIPD_SRC := $(GOSSIPD_HEADERS_WSRC:.h=.c) -GOSSIPD_OBJS := $(GOSSIPD_SRC:.c=.o) +GOSSIPD_OBJS := $(GOSSIPD_SRC:%.c=$(BUILDDIR)/%.o) $(GOSSIPD_OBJS): $(GOSSIPD_HEADERS) GOSSIPD_COMPACT_SRC := gossipd/compactd.c -GOSSIPD_COMPACT_OBJS := $(GOSSIPD_COMPACT_SRC:.c=.o) +GOSSIPD_COMPACT_OBJS := $(GOSSIPD_COMPACT_SRC:%.c=$(BUILDDIR)/%.o) # Make sure these depend on everything. ALL_C_SOURCES += $(GOSSIPD_SRC) $(GOSSIPD_COMPACT_SRC) ALL_C_HEADERS += $(GOSSIPD_HEADERS) -ALL_PROGRAMS += lightningd/lightning_gossipd lightningd/lightning_gossip_compactd +ALL_PROGRAMS += $(addprefix $(BUILDDIR)/lightningd/,lightning_gossipd lightning_gossip_compactd) # Here's what lightningd depends on LIGHTNINGD_CONTROL_HEADERS += gossipd/gossipd_wiregen.h -LIGHTNINGD_CONTROL_OBJS += gossipd/gossipd_wiregen.o +LIGHTNINGD_CONTROL_OBJS += $(BUILDDIR)/gossipd/gossipd_wiregen.o -lightningd/lightning_gossipd: $(GOSSIPD_OBJS) $(HSMD_CLIENT_OBJS) connectd/connectd_gossipd_wiregen.o libcommon.a +$(BUILDDIR)/lightningd/lightning_gossipd: $(GOSSIPD_OBJS) $(HSMD_CLIENT_OBJS) $(addprefix $(BUILDDIR)/,connectd/connectd_gossipd_wiregen.o libcommon.a) -lightningd/lightning_gossip_compactd: $(GOSSIPD_COMPACT_OBJS) libcommon.a +$(BUILDDIR)/lightningd/lightning_gossip_compactd: $(GOSSIPD_COMPACT_OBJS) $(BUILDDIR)/libcommon.a -# The CSV was removed, but the generated files may live on! -clean: clean-old-gossip-gen - -clean-old-gossip-gen: - $(RM) gossipd_peerd_wiregen.* +obsclean:: + $(RM) gossipd_peerd_wiregen.* gossipd/*.o include gossipd/test/Makefile diff --git a/gossipd/test/Makefile b/gossipd/test/Makefile index a05e4fda29c7..0f7a23a5d1af 100644 --- a/gossipd/test/Makefile +++ b/gossipd/test/Makefile @@ -3,15 +3,18 @@ check-units: gossipd-tests # Note that these actually #include everything they need, except ccan/ and bitcoin/. # That allows for unit testing of statics, and special effects. GOSSIPD_TEST_SRC := $(wildcard gossipd/test/run-*.c) -GOSSIPD_TEST_OBJS := $(GOSSIPD_TEST_SRC:.c=.o) +GOSSIPD_TEST_OBJS := $(GOSSIPD_TEST_SRC:%.c=$(BUILDDIR)/%.o) GOSSIPD_TEST_PROGRAMS := $(GOSSIPD_TEST_OBJS:.o=) ALL_C_SOURCES += $(GOSSIPD_TEST_SRC) ALL_TEST_PROGRAMS += $(GOSSIPD_TEST_PROGRAMS) -$(GOSSIPD_TEST_PROGRAMS): libcommon.a +$(GOSSIPD_TEST_PROGRAMS): $(BUILDDIR)/libcommon.a # Test objects depend on ../ src and headers. $(GOSSIPD_TEST_OBJS): $(GOSSIPD_HEADERS) $(GOSSIPD_SRC) gossipd/test/Makefile +obsclean:: + $(RM) gossipd/test/*.o + gossipd-tests: $(GOSSIPD_TEST_PROGRAMS:%=unittest/%) diff --git a/hsmd/Makefile b/hsmd/Makefile index c60f960eb1d4..2cfc17f220a4 100644 --- a/hsmd/Makefile +++ b/hsmd/Makefile @@ -6,21 +6,23 @@ HSMD_SRC := hsmd/hsmd.c \ hsmd/libhsmd.c HSMD_HEADERS := hsmd/hsmd_wiregen.h hsmd/permissions.h -HSMD_OBJS := $(HSMD_SRC:.c=.o) +HSMD_OBJS := $(HSMD_SRC:%.c=$(BUILDDIR)/%.o) $(HSMD_OBJS): $(HSMD_HEADERS) # Other programs which use the hsm need this. HSMD_CLIENT_OBJS := \ + $(addprefix $(BUILDDIR)/, \ hsmd/hsmd_wiregen.o \ hsmd/hsm_utxo.o \ + ) # Make sure these depend on everything. ALL_C_SOURCES += $(HSMD_SRC) ALL_C_HEADERS += $(HSMD_HEADERS) -ALL_PROGRAMS += lightningd/lightning_hsmd +ALL_PROGRAMS += $(BUILDDIR)/lightningd/lightning_hsmd -lightningd/lightning_hsmd: $(HSMD_OBJS) libcommon.a +$(BUILDDIR)/lightningd/lightning_hsmd: $(HSMD_OBJS) $(BUILDDIR)/libcommon.a check-source: check-hsm-versions @@ -28,4 +30,7 @@ check-source: check-hsm-versions check-hsm-versions: hsmd/hsmd_wire.csv common/hsm_version.h @SUM=`grep -vE '^(#| *$$)' hsmd/hsmd_wire.csv | sha256sum | cut -c1-64`; if ! grep -q "$$SUM" common/hsm_version.h; then echo "*** hsmd_wire.csv changed to $$SUM without update to common/hsm_version.h">&2; exit 1; fi +obsclean:: + $(RM) hsmd/*.o + -include hsmd/test/Makefile diff --git a/lightningd/Makefile b/lightningd/Makefile index f3ba8c0d86e4..aae3eef19f53 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -63,26 +63,26 @@ LIGHTNINGD_HDRS := \ $(WALLET_HDRS) -LIGHTNINGD_OBJS := $(LIGHTNINGD_SRC:.c=.o) $(LIGHTNINGD_SRC_NOHDR:.c=.o) +LIGHTNINGD_OBJS := $(addprefix $(BUILDDIR)/,$(LIGHTNINGD_SRC:.c=.o) $(LIGHTNINGD_SRC_NOHDR:.c=.o)) $(LIGHTNINGD_OBJS): $(LIGHTNINGD_HDRS) $(LIGHTNINGD_CONTROL_HEADERS) # Make sure these depend on everything. ALL_C_SOURCES += $(LIGHTNINGD_SRC) $(LIGHTNINGD_SRC_NOHDR) ALL_C_HEADERS += $(LIGHTNINGD_HDRS) -ALL_PROGRAMS += lightningd/lightningd +ALL_PROGRAMS += $(BUILDDIR)/lightningd/lightningd # We explicitly check header versions in lightningd.c -lightningd/lightningd.o: header_versions_gen.h +$(BUILDDIR)/lightningd/lightningd.o: header_versions_gen.h $(LIGHTNINGD_OBJS): $(LIGHTNINGD_HDRS) $(WALLET_OBJS): $(LIGHTNINGD_HDRS) $(DB_HEADERS) # Only the plugin component needs to depend on this header. -lightningd/plugin.o: plugins/list_of_builtin_plugins_gen.h +$(BUILDDIR)/lightningd/plugin.o: plugins/list_of_builtin_plugins_gen.h -lightningd/channel_state_names_gen.h: lightningd/channel_state.h ccan/ccan/cdump/tools/cdump-enumstr - ccan/ccan/cdump/tools/cdump-enumstr lightningd/channel_state.h > $@ +lightningd/channel_state_names_gen.h: lightningd/channel_state.h $(CDUMP_ENUMSTR) + $(CDUMP_ENUMSTR) lightningd/channel_state.h > $@ -lightningd/lightningd: $(LIGHTNINGD_OBJS) $(WALLET_OBJS) $(LIGHTNINGD_CONTROL_OBJS) $(HSMD_CLIENT_OBJS) $(DB_OBJS) libcommon.a +$(BUILDDIR)/lightningd/lightningd: $(LIGHTNINGD_OBJS) $(WALLET_OBJS) $(LIGHTNINGD_CONTROL_OBJS) $(HSMD_CLIENT_OBJS) $(DB_OBJS) $(BUILDDIR)/libcommon.a include lightningd/test/Makefile diff --git a/lightningd/test/Makefile b/lightningd/test/Makefile index ade3d8cf7151..f025d96d0970 100644 --- a/lightningd/test/Makefile +++ b/lightningd/test/Makefile @@ -1,17 +1,20 @@ # Note that these actually #include everything they need, except ccan/ and bitcoin/. # That allows for unit testing of statics, and special effects. LIGHTNINGD_TEST_SRC := $(wildcard lightningd/test/run-*.c) -LIGHTNINGD_TEST_OBJS := $(LIGHTNINGD_TEST_SRC:.c=.o) +LIGHTNINGD_TEST_OBJS := $(LIGHTNINGD_TEST_SRC:%.c=$(BUILDDIR)/%.o) LIGHTNINGD_TEST_PROGRAMS := $(LIGHTNINGD_TEST_OBJS:.o=) ALL_C_SOURCES += $(LIGHTNINGD_TEST_SRC) ALL_TEST_PROGRAMS += $(LIGHTNINGD_TEST_PROGRAMS) # run-find_my_abspath.c includes lightningd.c, which includes header_versions_gen.h -lightningd/test/run-find_my_abspath.o: header_versions_gen.h +$(BUILDDIR)/lightningd/test/run-find_my_abspath.o: header_versions_gen.h -$(LIGHTNINGD_TEST_PROGRAMS): libcommon.a +$(LIGHTNINGD_TEST_PROGRAMS): $(BUILDDIR)/libcommon.a $(LIGHTNINGD_TEST_OBJS): $(LIGHTNINGD_HDRS) $(LIGHTNINGD_SRC) $(LIGHTNINGD_SRC_NOHDR) lightningd/test/Makefile check-units: $(LIGHTNINGD_TEST_PROGRAMS:%=unittest/%) + +obsclean:: + $(RM) lightningd/test/*.o diff --git a/onchaind/Makefile b/onchaind/Makefile index b64cd0dc5640..d07d129fa400 100644 --- a/onchaind/Makefile +++ b/onchaind/Makefile @@ -10,25 +10,30 @@ ONCHAIND_SRC := onchaind/onchaind.c \ onchaind/onchaind_wiregen.c \ onchaind/onchaind_wire.c -onchaind/onchain_types_names_gen.h: onchaind/onchain_types.h ccan/ccan/cdump/tools/cdump-enumstr - ccan/ccan/cdump/tools/cdump-enumstr onchaind/onchain_types.h > $@ +onchaind/onchain_types_names_gen.h: onchaind/onchain_types.h $(CDUMP_ENUMSTR) + $(CDUMP_ENUMSTR) onchaind/onchain_types.h > $@ -ONCHAIND_OBJS := $(ONCHAIND_SRC:.c=.o) +ONCHAIND_OBJS := $(ONCHAIND_SRC:%.c=$(BUILDDIR)/%.o) $(ONCHAIND_OBJS): $(ONCHAIND_HEADERS) # Make sure these depend on everything. ALL_C_SOURCES += $(ONCHAIND_SRC) ALL_C_HEADERS += $(ONCHAIND_HEADERS) -ALL_PROGRAMS += lightningd/lightning_onchaind +ALL_PROGRAMS += $(BUILDDIR)/lightningd/lightning_onchaind # Here's what lightningd depends on LIGHTNINGD_CONTROL_HEADERS += \ onchaind/onchaind_wiregen.h \ onchaind/onchaind_wire.h LIGHTNINGD_CONTROL_OBJS += \ + $(addprefix $(BUILDDIR)/, \ onchaind/onchaind_wiregen.o \ - onchaind/onchaind_wire.o + onchaind/onchaind_wire.o \ + ) -lightningd/lightning_onchaind: $(ONCHAIND_OBJS) $(HSMD_CLIENT_OBJS) libcommon.a +$(BUILDDIR)/lightningd/lightning_onchaind: $(ONCHAIND_OBJS) $(HSMD_CLIENT_OBJS) $(BUILDDIR)/libcommon.a + +obsclean:: + $(RM) onchaind/*.o include onchaind/test/Makefile diff --git a/onchaind/test/Makefile b/onchaind/test/Makefile index b776ea1fd1a7..9465dd504c8c 100644 --- a/onchaind/test/Makefile +++ b/onchaind/test/Makefile @@ -3,17 +3,18 @@ check-units: onchaind-tests # Note that these actually #include everything they need, except ccan/ and bitcoin/. # That allows for unit testing of statics, and special effects. ONCHAIND_TEST_SRC := $(wildcard onchaind/test/run-*.c) -ONCHAIND_TEST_OBJS := $(ONCHAIND_TEST_SRC:.c=.o) +ONCHAIND_TEST_OBJS := $(ONCHAIND_TEST_SRC:%.c=$(BUILDDIR)/%.o) ONCHAIND_TEST_PROGRAMS := $(ONCHAIND_TEST_OBJS:.o=) ALL_C_SOURCES += $(ONCHAIND_TEST_SRC) ALL_TEST_PROGRAMS += $(ONCHAIND_TEST_PROGRAMS) # test/run-grind_feerate-bug uses its own htlc_timeout_tx() -$(filter-out onchaind/test/run-grind_feerate-bug,$(ONCHAIND_TEST_PROGRAMS)): libcommon.a +$(filter-out onchaind/test/run-grind_feerate-bug,$(ONCHAIND_TEST_PROGRAMS)): $(BUILDDIR)/libcommon.a -onchaind/test/run-grind_feerate-bug: \ +$(BUILDDIR)/onchaind/test/run-grind_feerate-bug: \ $(BITCOIN_OBJS) \ + $(addprefix $(BUILDDIR)/, \ wire/towire.o \ wire/fromwire.o \ common/amount.o \ @@ -22,10 +23,13 @@ onchaind/test/run-grind_feerate-bug: \ common/psbt_keypath.o \ common/pseudorand.o \ common/setup.o \ - common/utils.o + common/utils.o \ + ) # Test objects depend on ../ src and headers. $(ONCHAIND_TEST_OBJS): $(ONCHAIND_HEADERS) $(ONCHAIND_SRC) onchaind/test/Makefile onchaind-tests: $(ONCHAIND_TEST_PROGRAMS:%=unittest/%) +obsclean:: + $(RM) onchaind/test/*.o diff --git a/openingd/Makefile b/openingd/Makefile index b5a1c29f8870..88e7fdaa1fd6 100644 --- a/openingd/Makefile +++ b/openingd/Makefile @@ -14,23 +14,26 @@ OPENINGD_SRC := openingd/openingd.c \ DUALOPEND_SRC := openingd/dualopend.c \ $(DUALOPEND_HEADERS:.h=.c) -OPENINGD_OBJS := $(OPENINGD_SRC:.c=.o) +OPENINGD_OBJS := $(OPENINGD_SRC:%.c=$(BUILDDIR)/%.o) $(OPENINGD_OBJS): $(OPENINGD_HEADERS) -DUALOPEND_OBJS := $(DUALOPEND_SRC:.c=.o) +DUALOPEND_OBJS := $(DUALOPEND_SRC:%.c=$(BUILDDIR)/%.o) $(DUALOPEND_OBJS): $(DUALOPEND_HEADERS) # Make sure these depend on everything. ALL_C_SOURCES += $(OPENINGD_SRC) $(DUALOPEND_SRC) ALL_C_HEADERS += $(OPENINGD_HEADERS) $(DUALOPEND_HEADERS) -ALL_PROGRAMS += lightningd/lightning_openingd lightningd/lightning_dualopend +ALL_PROGRAMS += $(addprefix $(BUILDDIR)/lightningd/,lightning_openingd lightning_dualopend) # Here's what lightningd depends on LIGHTNINGD_CONTROL_HEADERS += openingd/openingd_wiregen.h openingd/dualopend_wiregen.h -LIGHTNINGD_CONTROL_OBJS += openingd/openingd_wiregen.o openingd/dualopend_wiregen.o +LIGHTNINGD_CONTROL_OBJS += $(addprefix $(BUILDDIR)/openingd/,openingd_wiregen.o dualopend_wiregen.o) -lightningd/lightning_openingd: $(OPENINGD_OBJS) $(HSMD_CLIENT_OBJS) libcommon.a +$(BUILDDIR)/lightningd/lightning_openingd: $(OPENINGD_OBJS) $(HSMD_CLIENT_OBJS) $(BUILDDIR)/libcommon.a -lightningd/lightning_dualopend: $(DUALOPEND_OBJS) $(HSMD_CLIENT_OBJS) libcommon.a +$(BUILDDIR)/lightningd/lightning_dualopend: $(DUALOPEND_OBJS) $(HSMD_CLIENT_OBJS) $(BUILDDIR)/libcommon.a + +obsclean:: + $(RM) openingd/*.o -include openingd/test/Makefile diff --git a/plugins/Makefile b/plugins/Makefile index 9179e1d116fa..8fe4f7aad9b1 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -1,21 +1,21 @@ PLUGIN_PAY_SRC := plugins/pay.c PLUGIN_PAY_HEADER := -PLUGIN_PAY_OBJS := $(PLUGIN_PAY_SRC:.c=.o) +PLUGIN_PAY_OBJS := $(PLUGIN_PAY_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_AUTOCLEAN_SRC := plugins/autoclean.c -PLUGIN_AUTOCLEAN_OBJS := $(PLUGIN_AUTOCLEAN_SRC:.c=.o) +PLUGIN_AUTOCLEAN_OBJS := $(PLUGIN_AUTOCLEAN_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_chanbackup_SRC := plugins/chanbackup.c -PLUGIN_chanbackup_OBJS := $(PLUGIN_chanbackup_SRC:.c=.o) +PLUGIN_chanbackup_OBJS := $(PLUGIN_chanbackup_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_TOPOLOGY_SRC := plugins/topology.c -PLUGIN_TOPOLOGY_OBJS := $(PLUGIN_TOPOLOGY_SRC:.c=.o) +PLUGIN_TOPOLOGY_OBJS := $(PLUGIN_TOPOLOGY_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_TXPREPARE_SRC := plugins/txprepare.c -PLUGIN_TXPREPARE_OBJS := $(PLUGIN_TXPREPARE_SRC:.c=.o) +PLUGIN_TXPREPARE_OBJS := $(PLUGIN_TXPREPARE_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_BCLI_SRC := plugins/bcli.c -PLUGIN_BCLI_OBJS := $(PLUGIN_BCLI_SRC:.c=.o) +PLUGIN_BCLI_OBJS := $(PLUGIN_BCLI_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_BWATCH_SRC := plugins/bwatch/bwatch.c \ plugins/bwatch/bwatch_store.c \ @@ -27,17 +27,17 @@ PLUGIN_BWATCH_HEADER := plugins/bwatch/bwatch.h \ plugins/bwatch/bwatch_scanner.h \ plugins/bwatch/bwatch_interface.h \ plugins/bwatch/bwatch_wiregen.h -PLUGIN_BWATCH_OBJS := $(PLUGIN_BWATCH_SRC:.c=.o) +PLUGIN_BWATCH_OBJS := $(PLUGIN_BWATCH_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_COMMANDO_SRC := plugins/commando.c -PLUGIN_COMMANDO_OBJS := $(PLUGIN_COMMANDO_SRC:.c=.o) +PLUGIN_COMMANDO_OBJS := $(PLUGIN_COMMANDO_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_KEYSEND_SRC := plugins/keysend.c -PLUGIN_KEYSEND_OBJS := $(PLUGIN_KEYSEND_SRC:.c=.o) +PLUGIN_KEYSEND_OBJS := $(PLUGIN_KEYSEND_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_LIB_SRC := plugins/libplugin.c PLUGIN_LIB_HEADER := plugins/libplugin.h -PLUGIN_LIB_OBJS := $(PLUGIN_LIB_SRC:.c=.o) +PLUGIN_LIB_OBJS := $(PLUGIN_LIB_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_PAY_LIB_SRC := \ plugins/channel_hint.c \ @@ -47,19 +47,19 @@ PLUGIN_PAY_LIB_HEADER := \ plugins/channel_hint.h \ plugins/libplugin-pay.h -PLUGIN_PAY_LIB_OBJS := $(PLUGIN_PAY_LIB_SRC:.c=.o) +PLUGIN_PAY_LIB_OBJS := $(PLUGIN_PAY_LIB_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_OFFERS_SRC := plugins/offers.c plugins/offers_offer.c plugins/offers_invreq_hook.c plugins/offers_inv_hook.c plugins/establish_onion_path.c plugins/fetchinvoice.c plugins/offers_proof.c -PLUGIN_OFFERS_OBJS := $(PLUGIN_OFFERS_SRC:.c=.o) +PLUGIN_OFFERS_OBJS := $(PLUGIN_OFFERS_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_OFFERS_HEADER := $(PLUGIN_OFFERS_SRC:.c=.h) PLUGIN_SQL_SRC := plugins/sql.c PLUGIN_SQL_HEADER := -PLUGIN_SQL_OBJS := $(PLUGIN_SQL_SRC:.c=.o) +PLUGIN_SQL_OBJS := $(PLUGIN_SQL_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_EXPOSESECRET_SRC := plugins/exposesecret.c PLUGIN_EXPOSESECRET_HEADER := -PLUGIN_EXPOSESECRET_OBJS := $(PLUGIN_EXPOSESECRET_SRC:.c=.o) +PLUGIN_EXPOSESECRET_OBJS := $(PLUGIN_EXPOSESECRET_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_SPENDER_SRC := \ plugins/spender/fundchannel.c \ @@ -75,20 +75,20 @@ PLUGIN_SPENDER_HEADER := \ plugins/spender/multifundchannel.h \ plugins/spender/openchannel.h \ plugins/spender/splice.h -PLUGIN_SPENDER_OBJS := $(PLUGIN_SPENDER_SRC:.c=.o) +PLUGIN_SPENDER_OBJS := $(PLUGIN_SPENDER_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_RECOVER_SRC := plugins/recover.c -PLUGIN_RECOVER_OBJS := $(PLUGIN_RECOVER_SRC:.c=.o) +PLUGIN_RECOVER_OBJS := $(PLUGIN_RECOVER_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_FUNDER_SRC := \ plugins/funder.c \ plugins/funder_policy.c PLUGIN_FUNDER_HEADER := \ plugins/funder_policy.h -PLUGIN_FUNDER_OBJS := $(PLUGIN_FUNDER_SRC:.c=.o) +PLUGIN_FUNDER_OBJS := $(PLUGIN_FUNDER_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_RECKLESSRPC_SRC := plugins/recklessrpc.c -PLUGIN_RECKLESSRPC_OBJS := $(PLUGIN_RECKLESSRPC_SRC:.c=.o) +PLUGIN_RECKLESSRPC_OBJS := $(PLUGIN_RECKLESSRPC_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_ALL_SRC := \ $(PLUGIN_AUTOCLEAN_SRC) \ @@ -119,6 +119,7 @@ PLUGIN_ALL_HEADER := \ $(PLUGIN_BWATCH_HEADER) C_PLUGINS := \ + $(addprefix $(BUILDDIR)/, \ plugins/autoclean \ plugins/chanbackup \ plugins/bcli \ @@ -136,10 +137,11 @@ C_PLUGINS := \ plugins/cln-renepay \ plugins/cln-xpay \ plugins/spenderp \ - plugins/cln-askrene + plugins/cln-askrene \ + ) ifeq ($(HAVE_SQLITE3),1) -C_PLUGINS += plugins/sql +C_PLUGINS += $(BUILDDIR)/plugins/sql PLUGIN_ALL_SRC += $(PLUGIN_SQL_SRC) PLUGIN_ALL_HEADER += $(PLUGIN_SQL_HEADER) endif @@ -157,7 +159,7 @@ RUST_PLUGIN_NAMES := cln-grpc clnrest cln-lsps-client cln-lsps-service wss-proxy # Builtin plugins must be in this plugins dir to work when we're executed # *without* make install. -RUST_PLUGINS := $(addprefix plugins/,$(RUST_PLUGIN_NAMES)) +RUST_PLUGINS := $(addprefix $(BUILDDIR)/plugins/,$(RUST_PLUGIN_NAMES)) $(RUST_PLUGINS): plugins/%: $(RUST_TARGET_DIR)/% @cp $< $@ @@ -177,48 +179,48 @@ ALL_C_SOURCES += $(PLUGIN_ALL_SRC) ALL_C_HEADERS += $(PLUGIN_ALL_HEADER) ALL_PROGRAMS += $(C_PLUGINS) -PLUGIN_ALL_OBJS := $(PLUGIN_ALL_SRC:.c=.o) +PLUGIN_ALL_OBJS := $(PLUGIN_ALL_SRC:%.c=$(BUILDDIR)/%.o) # Make all plugins depend on all plugin headers, for simplicity (and this file!) $(PLUGIN_ALL_OBJS): $(PLUGIN_ALL_HEADER) plugins/Makefile -plugins/pay: $(PLUGIN_PAY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/pay: $(PLUGIN_PAY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/autoclean: $(PLUGIN_AUTOCLEAN_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/autoclean: $(PLUGIN_AUTOCLEAN_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/chanbackup: $(PLUGIN_chanbackup_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/chanbackup: $(PLUGIN_chanbackup_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/commando: $(PLUGIN_COMMANDO_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/commando: $(PLUGIN_COMMANDO_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a # Topology wants to decode node_announcement, and peer_wiregen which # pulls in some of bitcoin/. -plugins/topology: $(PLUGIN_TOPOLOGY_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/topology: $(PLUGIN_TOPOLOGY_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/txprepare: $(PLUGIN_TXPREPARE_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/txprepare: $(PLUGIN_TXPREPARE_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/exposesecret: $(PLUGIN_EXPOSESECRET_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/exposesecret: $(PLUGIN_EXPOSESECRET_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/bcli: $(PLUGIN_BCLI_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/bcli: $(PLUGIN_BCLI_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/bwatch/bwatch.o: $(PLUGIN_BWATCH_HEADER) -plugins/bwatch/bwatch_store.o: $(PLUGIN_BWATCH_HEADER) -plugins/bwatch/bwatch_scanner.o: $(PLUGIN_BWATCH_HEADER) -plugins/bwatch/bwatch_interface.o: $(PLUGIN_BWATCH_HEADER) -plugins/bwatch/bwatch_wiregen.o: $(PLUGIN_BWATCH_HEADER) -plugins/cln-bwatch: $(PLUGIN_BWATCH_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/bwatch/bwatch.o: $(PLUGIN_BWATCH_HEADER) +$(BUILDDIR)/plugins/bwatch/bwatch_store.o: $(PLUGIN_BWATCH_HEADER) +$(BUILDDIR)/plugins/bwatch/bwatch_scanner.o: $(PLUGIN_BWATCH_HEADER) +$(BUILDDIR)/plugins/bwatch/bwatch_interface.o: $(PLUGIN_BWATCH_HEADER) +$(BUILDDIR)/plugins/bwatch/bwatch_wiregen.o: $(PLUGIN_BWATCH_HEADER) +$(BUILDDIR)/plugins/cln-bwatch: $(PLUGIN_BWATCH_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/keysend: $(PLUGIN_KEYSEND_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) libcommon.a -$(PLUGIN_KEYSEND_OBJS): $(PLUGIN_PAY_LIB_HEADER) libcommon.a +$(BUILDDIR)/plugins/keysend: $(PLUGIN_KEYSEND_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(BUILDDIR)/libcommon.a +$(PLUGIN_KEYSEND_OBJS): $(PLUGIN_PAY_LIB_HEADER) $(BUILDDIR)/libcommon.a -plugins/spenderp: $(PLUGIN_SPENDER_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/spenderp: $(PLUGIN_SPENDER_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/offers: $(PLUGIN_OFFERS_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/offers: $(PLUGIN_OFFERS_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/funder: $(PLUGIN_FUNDER_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/funder: $(PLUGIN_FUNDER_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/recover: $(PLUGIN_RECOVER_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/recover: $(PLUGIN_RECOVER_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a -plugins/recklessrpc: $(PLUGIN_RECKLESSRPC_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/recklessrpc: $(PLUGIN_RECKLESSRPC_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a # This covers all the low-level list RPCs which return simple arrays SQL_LISTRPCS := listchannels listforwards listhtlcs listinvoices listnodes listoffers listpeers listpeerchannels listclosedchannels listtransactions listsendpays listchainmoves listchannelmoves bkpr-listaccountevents bkpr-listincome listnetworkevents @@ -248,12 +250,12 @@ plugins/sql-schema_gen.h: $(SQL_SCHEMA_PARTS) echo "}\"") | tr -d " \n" > $@ \ ) -plugins/sql.o: plugins/sql-schema_gen.h -plugins/sql: $(PLUGIN_SQL_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/sql.o: plugins/sql-schema_gen.h +$(BUILDDIR)/plugins/sql: $(PLUGIN_SQL_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a # Generated from PLUGINS definition in plugins/Makefile ALL_C_HEADERS += plugins/list_of_builtin_plugins_gen.h -PLUGIN_BASES := $(PLUGINS:plugins/%=%) $(PY_PLUGINS:plugins/%=%) +PLUGIN_BASES := $(PLUGINS:$(BUILDDIR)/plugins/%=%) $(PY_PLUGINS:plugins/%=%) plugins/list_of_builtin_plugins_gen.h: plugins/Makefile Makefile config.vars @$(call VERBOSE,GEN $@,echo "static const char *list_of_builtin_plugins[] = { $(PLUGIN_BASES:%=\"%\",) NULL };" > $@) @@ -297,12 +299,16 @@ $(RUST_TARGET_DIR)/cln-currencyrate: ${CLN_CURRENCYRATE_PLUGIN_SRC} ${CLN_RPC_SO ifneq ($(RUST),0) include plugins/rest-plugin/Makefile include plugins/wss-proxy-plugin/Makefile -DEFAULT_TARGETS += $(CLN_PLUGIN_EXAMPLES) plugins/cln-grpc plugins/clnrest plugins/cln-lsps-client plugins/cln-lsps-service plugins/wss-proxy plugins/cln-bip353 plugins/cln-currencyrate +DEFAULT_TARGETS += $(CLN_PLUGIN_EXAMPLES) $(addprefix $(BUILDDIR)/plugins/,cln-grpc clnrest cln-lsps-client cln-lsps-service wss-proxy cln-bip353 cln-currencyrate) endif clean: plugins-clean + +obsclean:: + $(RM) $(PLUGINS:$(BUILDDIR)/%=%) plugins/*.o + plugins-clean: - $(RM) $(PLUGINS) $(CLN_PLUGIN_EXAMPLES) + $(RM) $(CLN_PLUGIN_EXAMPLES) $(RM) plugins/sql-schema_gen.h include plugins/test/Makefile diff --git a/plugins/askrene/Makefile b/plugins/askrene/Makefile index 292059112a67..2bae722cc954 100644 --- a/plugins/askrene/Makefile +++ b/plugins/askrene/Makefile @@ -20,13 +20,16 @@ PLUGIN_ASKRENE_CHILD_SRC := \ PLUGIN_ASKRENE_SRC := $(PLUGIN_ASKRENE_PARENT_SRC) $(PLUGIN_ASKRENE_CHILD_SRC) PLUGIN_ASKRENE_HEADER := $(PLUGIN_ASKRENE_SRC:.c=.h) plugins/askrene/child/additional_costs.h -PLUGIN_ASKRENE_OBJS := $(PLUGIN_ASKRENE_SRC:.c=.o) +PLUGIN_ASKRENE_OBJS := $(PLUGIN_ASKRENE_SRC:%.c=$(BUILDDIR)/%.o) $(PLUGIN_ASKRENE_OBJS): $(PLUGIN_ASKRENE_HEADER) plugins/askrene/Makefile PLUGIN_ALL_SRC += $(PLUGIN_ASKRENE_SRC) PLUGIN_ALL_HEADER += $(PLUGIN_ASKRENE_HEADER) -plugins/cln-askrene: $(PLUGIN_ASKRENE_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/cln-askrene: $(PLUGIN_ASKRENE_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a + +obsclean:: + $(RM) plugins/askrene/*.o plugins/askrene/child/*.o include plugins/askrene/test/Makefile diff --git a/plugins/askrene/test/Makefile b/plugins/askrene/test/Makefile index c9e06cdab2e5..0f9030d622a5 100644 --- a/plugins/askrene/test/Makefile +++ b/plugins/askrene/test/Makefile @@ -1,19 +1,24 @@ # Note that these actually #include everything they need, except ccan/ and bitcoin/. # That allows for unit testing of statics, and special effects. PLUGIN_ASKRENE_TEST_SRC := $(wildcard plugins/askrene/test/run-*.c) -PLUGIN_ASKRENE_TEST_OBJS := $(PLUGIN_ASKRENE_TEST_SRC:.c=.o) +PLUGIN_ASKRENE_TEST_OBJS := $(PLUGIN_ASKRENE_TEST_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_ASKRENE_TEST_PROGRAMS := $(PLUGIN_ASKRENE_TEST_OBJS:.o=) ALL_C_SOURCES += $(PLUGIN_ASKRENE_TEST_SRC) ALL_TEST_PROGRAMS += $(PLUGIN_ASKRENE_TEST_PROGRAMS) $(PLUGIN_RENEPAY_TEST_OBJS): $(PLUGIN_ASKRENE_SRC) plugins/askrene/test/Makefile -plugins/askrene/test/run-bfs plugins/askrene/test/run-dijkstra plugins/askrene/test/run-flow plugins/askrene/test/run-mcf plugins/askrene/test/run-mcf-large: \ +$(addprefix $(BUILDDIR)/plugins/askrene/test/,run-bfs run-dijkstra run-flow run-mcf run-mcf-large): \ + $(addprefix $(BUILDDIR)/, \ plugins/askrene/child/priorityqueue.o \ - plugins/askrene/child/graph.o + plugins/askrene/child/graph.o \ + ) -$(PLUGIN_ASKRENE_TEST_PROGRAMS): $(PLUGIN_LIB_OBJS) libcommon.a +$(PLUGIN_ASKRENE_TEST_PROGRAMS): $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a check-askrene: $(PLUGIN_ASKRENE_TEST_PROGRAMS:%=unittest/%) check-units: check-askrene + +obsclean:: + $(RM) askrene/test/*.o diff --git a/plugins/bkpr/Makefile b/plugins/bkpr/Makefile index b49b24924cf0..099f454bcb32 100644 --- a/plugins/bkpr/Makefile +++ b/plugins/bkpr/Makefile @@ -32,16 +32,16 @@ BOOKKEEPER_HEADER := \ plugins/bkpr/recorder.h \ plugins/bkpr/sql.h -BOOKKEEPER_OBJS := $(BOOKKEEPER_SRC:.c=.o) +BOOKKEEPER_OBJS := $(BOOKKEEPER_SRC:%.c=$(BUILDDIR)/%.o) $(BOOKKEEPER_OBJS): $(PLUGIN_LIB_HEADER) $(BOOKKEEPER_HEADER) PLUGIN_ALL_SRC += $(BOOKKEEPER_SRC) PLUGIN_ALL_HEADER += $(BOOKKEEPER_HEADER) -C_PLUGINS += plugins/bookkeeper -PLUGINS += plugins/bookkeeper +C_PLUGINS += $(BUILDDIR)/plugins/bookkeeper +PLUGINS += $(BUILDDIR)/plugins/bookkeeper -plugins/bookkeeper: $(BOOKKEEPER_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/bookkeeper: $(BOOKKEEPER_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a maintainer-clean: clean clean: bkpr-maintainer-clean @@ -50,4 +50,7 @@ bkpr-maintainer-clean: $(RM) plugins/bkpr/statements_gettextgen.po $(RM) $(BOOKKEEPER_DB_QUERIES) +obsclean:: + $(RM) plugins/bkpr/*.o + include plugins/bkpr/test/Makefile diff --git a/plugins/bkpr/test/Makefile b/plugins/bkpr/test/Makefile index c28bc00b7fbe..1c7c7cae3cdf 100644 --- a/plugins/bkpr/test/Makefile +++ b/plugins/bkpr/test/Makefile @@ -1,11 +1,14 @@ BOOKKEEPER_TEST_SRC := $(wildcard plugins/bkpr/test/run-*.c) -BOOKKEEPER_TEST_OBJS := $(BOOKKEEPER_TEST_SRC:.c=.o) +BOOKKEEPER_TEST_OBJS := $(BOOKKEEPER_TEST_SRC:%.c=$(BUILDDIR)/%.o) BOOKKEEPER_TEST_PROGRAMS := $(BOOKKEEPER_TEST_OBJS:.o=) ALL_C_SOURCES += $(BOOKKEEPER_TEST_SRC) ALL_TEST_PROGRAMS += $(BOOKKEEPER_TEST_PROGRAMS) -$(BOOKKEEPER_TEST_PROGRAMS): libcommon.a +$(BOOKKEEPER_TEST_PROGRAMS): $(BUILDDIR)/libcommon.a $(BOOKKEEPER_TEST_OBJS): $(BOOKKEEPER_SRC) $(BOOKKEEPER_HEADER) plugins/bkpr/test/Makefile check-units: $(BOOKKEEPER_TEST_PROGRAMS:%=unittest/%) + +obsclean:: + $(RM) plugins/bkpr/test/*.o diff --git a/plugins/renepay/Makefile b/plugins/renepay/Makefile index a52483e89154..48ae77317e39 100644 --- a/plugins/renepay/Makefile +++ b/plugins/renepay/Makefile @@ -34,7 +34,7 @@ PLUGIN_RENEPAY_HDRS := \ plugins/renepay/errorcodes.h \ plugins/renepay/json.h -PLUGIN_RENEPAY_OBJS := $(PLUGIN_RENEPAY_SRC:.c=.o) +PLUGIN_RENEPAY_OBJS := $(PLUGIN_RENEPAY_SRC:%.c=$(BUILDDIR)/%.o) # Make sure these depend on everything. PLUGIN_ALL_SRC += $(PLUGIN_RENEPAY_SRC) @@ -43,6 +43,9 @@ PLUGIN_ALL_HEADER += $(PLUGIN_RENEPAY_HDRS) # Make all plugins depend on all plugin headers, for simplicity (and this file). $(PLUGIN_RENEPAY_OBJS): $(PLUGIN_RENEPAY_HDRS) plugins/renepay/Makefile -plugins/cln-renepay: $(PLUGIN_RENEPAY_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/cln-renepay: $(PLUGIN_RENEPAY_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a + +obsclean:: + $(RM) plugins/renepay/*.o include plugins/renepay/test/Makefile diff --git a/plugins/renepay/test/Makefile b/plugins/renepay/test/Makefile index f6dcb33cda00..6d1ab173ac0a 100644 --- a/plugins/renepay/test/Makefile +++ b/plugins/renepay/test/Makefile @@ -1,7 +1,7 @@ # Note that these actually #include everything they need, except ccan/ and bitcoin/. # That allows for unit testing of statics, and special effects. PLUGIN_RENEPAY_TEST_SRC := $(wildcard plugins/renepay/test/run-*.c) -PLUGIN_RENEPAY_TEST_OBJS := $(PLUGIN_RENEPAY_TEST_SRC:.c=.o) +PLUGIN_RENEPAY_TEST_OBJS := $(PLUGIN_RENEPAY_TEST_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_RENEPAY_TEST_PROGRAMS := $(PLUGIN_RENEPAY_TEST_OBJS:.o=) ALL_C_SOURCES += $(PLUGIN_RENEPAY_TEST_SRC) @@ -9,10 +9,15 @@ ALL_TEST_PROGRAMS += $(PLUGIN_RENEPAY_TEST_PROGRAMS) $(PLUGIN_RENEPAY_TEST_OBJS): $(PLUGIN_RENEPAY_SRC) plugins/renepay/test/common.h plugins/renepay/test/Makefile $(PLUGIN_RENEPAY_TEST_PROGRAMS): \ + $(addprefix $(BUILDDIR)/, \ plugins/renepay/dijkstra.o \ plugins/renepay/chan_extra.o \ - libcommon.a + libcommon.a \ + ) check-renepay: $(PLUGIN_RENEPAY_TEST_PROGRAMS:%=unittest/%) check-units: check-renepay + +obsclean:: + $(RM) plugins/renepay/test/*.o diff --git a/plugins/test/Makefile b/plugins/test/Makefile index 5ec83035b651..6f9c0326df47 100644 --- a/plugins/test/Makefile +++ b/plugins/test/Makefile @@ -1,24 +1,31 @@ # Note that these actually #include everything they need, except ccan/, bitcoin/ and wire/ # That allows for unit testing of statics, and special effects. PLUGIN_TEST_SRC := $(wildcard plugins/test/run-*.c) -PLUGIN_TEST_OBJS := $(PLUGIN_TEST_SRC:.c=.o) +PLUGIN_TEST_OBJS := $(PLUGIN_TEST_SRC:%.c=$(BUILDDIR)/%.o) PLUGIN_TEST_PROGRAMS := $(PLUGIN_TEST_OBJS:.o=) ALL_C_SOURCES += $(PLUGIN_TEST_SRC) ALL_TEST_PROGRAMS += $(PLUGIN_TEST_PROGRAMS) -plugins/test/run-route-overlong: \ - plugins/channel_hint.o +$(BUILDDIR)/plugins/test/run-route-overlong: \ + $(addprefix $(BUILDDIR)/, \ + plugins/channel_hint.o \ + ) -plugins/test/run-route-calc: \ +$(BUILDDIR)/plugins/test/run-route-calc: \ + $(addprefix $(BUILDDIR)/, \ common/fp16.o \ common/gossmap.o \ common/node_id.o \ common/route.o \ - plugins/channel_hint.o + plugins/channel_hint.o \ + ) -$(PLUGIN_TEST_PROGRAMS): libcommon.a +$(PLUGIN_TEST_PROGRAMS): $(BUILDDIR)/libcommon.a $(PLUGIN_TEST_OBJS): $(PLUGIN_ALL_HEADER) $(PLUGIN_ALL_SRC) plugins/test/Makefile check-units: $(PLUGIN_TEST_PROGRAMS:%=unittest/%) + +obsclean:: + $(RM) plugins/test/*.o diff --git a/plugins/xpay/Makefile b/plugins/xpay/Makefile index 33f22eb117b2..84365d11c4d3 100644 --- a/plugins/xpay/Makefile +++ b/plugins/xpay/Makefile @@ -4,7 +4,7 @@ PLUGIN_XPAY_SRC := \ PLUGIN_XPAY_HDRS := -PLUGIN_XPAY_OBJS := $(PLUGIN_XPAY_SRC:.c=.o) +PLUGIN_XPAY_OBJS := $(PLUGIN_XPAY_SRC:%.c=$(BUILDDIR)/%.o) # Make sure these depend on everything. ALL_C_SOURCES += $(PLUGIN_XPAY_SRC) @@ -13,4 +13,7 @@ ALL_C_HEADERS += $(PLUGIN_XPAY_HDRS) # Make all plugins depend on all plugin headers, for simplicity (and this file) $(PLUGIN_XPAY_OBJS): $(PLUGIN_XPAY_HDRS) $(PLUGIN_LIB_HEADER) plugins/xpay/Makefile -plugins/cln-xpay: $(PLUGIN_XPAY_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/plugins/cln-xpay: $(PLUGIN_XPAY_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a + +obsclean:: + $(RM) plugins/xpay/*.o diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile index 05a2d6646484..6657997c7f47 100644 --- a/tests/fuzz/Makefile +++ b/tests/fuzz/Makefile @@ -1,24 +1,24 @@ LIBFUZZ_SRC := tests/fuzz/libfuzz.c LIBFUZZ_HEADERS := $(LIBFUZZ_SRC:.c=.h) -LIBFUZZ_OBJS := $(LIBFUZZ_SRC:.c=.o) +LIBFUZZ_OBJS := $(LIBFUZZ_SRC:%.c=$(BUILDDIR)/%.o) -tests/fuzz/fuzz-connectd-handshake-act*.o: tests/fuzz/connectd_handshake.h -tests/fuzz/fuzz-ripemd160: LDLIBS += -lcrypto -tests/fuzz/fuzz-sha256: LDLIBS += -lcrypto -tests/fuzz/fuzz-hmac-sha256: LDLIBS += -lcrypto -tests/fuzz/fuzz-wire-*.o: tests/fuzz/wire.h -tests/fuzz/fuzz-bolt12-*.o: tests/fuzz/bolt12.h +$(BUILDDIR)/tests/fuzz/fuzz-connectd-handshake-act*.o: tests/fuzz/connectd_handshake.h +$(BUILDDIR)/tests/fuzz/fuzz-ripemd160: LDLIBS += -lcrypto +$(BUILDDIR)/tests/fuzz/fuzz-sha256: LDLIBS += -lcrypto +$(BUILDDIR)/tests/fuzz/fuzz-hmac-sha256: LDLIBS += -lcrypto +$(BUILDDIR)/tests/fuzz/fuzz-wire-*.o: tests/fuzz/wire.h +$(BUILDDIR)/tests/fuzz/fuzz-bolt12-*.o: tests/fuzz/bolt12.h -tests/fuzz/fuzz-handle_onion_message: connectd/onion_message.o connectd/connectd_wiregen.o -tests/fuzz/fuzz-full_channel: channeld/full_channel.o channeld/commit_tx.o -tests/fuzz/fuzz-open_channel: hsmd/hsmd_wiregen.o openingd/common.o openingd/openingd_wiregen.o +$(BUILDDIR)/tests/fuzz/fuzz-handle_onion_message: $(addprefix $(BUILDDIR)/,connectd/onion_message.o connectd/connectd_wiregen.o) +$(BUILDDIR)/tests/fuzz/fuzz-full_channel: $(addprefix $(BUILDDIR)/,channeld/full_channel.o channeld/commit_tx.o) +$(BUILDDIR)/tests/fuzz/fuzz-open_channel: $(addprefix $(BUILDDIR)/,hsmd/hsmd_wiregen.o openingd/common.o openingd/openingd_wiregen.o) FUZZ_TARGETS_SRC := $(wildcard tests/fuzz/fuzz-*.c) -FUZZ_TARGETS_OBJS := $(FUZZ_TARGETS_SRC:.c=.o) -FUZZ_TARGETS_BIN := $(FUZZ_TARGETS_SRC:.c=) +FUZZ_TARGETS_OBJS := $(FUZZ_TARGETS_SRC:%.c=$(BUILDDIR)/%.o) +FUZZ_TARGETS_BIN := $(FUZZ_TARGETS_OBJS:.o=) $(FUZZ_TARGETS_OBJS): $(COMMON_HEADERS) $(WIRE_HEADERS) $(COMMON_SRC) tests/fuzz/libfuzz.h -$(FUZZ_TARGETS_BIN): $(LIBFUZZ_OBJS) libcommon.a +$(FUZZ_TARGETS_BIN): $(LIBFUZZ_OBJS) $(BUILDDIR)/libcommon.a ALL_C_SOURCES += $(FUZZ_TARGETS_SRC) $(LIBFUZZ_SRC) ALL_FUZZ_TARGETS += $(FUZZ_TARGETS_BIN) @@ -27,3 +27,6 @@ ALL_FUZZ_TARGETS += $(FUZZ_TARGETS_BIN) ifneq ($(FUZZING),1) check-units: $(FUZZ_TARGETS_BIN:%=fuzzunittest/%) endif + +obsclean:: + $(RM) tests/fuzz/*.o diff --git a/tests/plugins/Makefile b/tests/plugins/Makefile index 3a0c46851f3d..c15f1cb908e0 100644 --- a/tests/plugins/Makefile +++ b/tests/plugins/Makefile @@ -1,26 +1,31 @@ PLUGIN_TESTLIBPLUGIN_SRC := tests/plugins/test_libplugin.c -PLUGIN_TESTLIBPLUGIN_OBJS := $(PLUGIN_TESTLIBPLUGIN_SRC:.c=.o) +PLUGIN_TESTLIBPLUGIN_OBJS := $(PLUGIN_TESTLIBPLUGIN_SRC:%.c=$(BUILDDIR)/%.o) -tests/plugins/test_libplugin: $(PLUGIN_TESTLIBPLUGIN_OBJS) $(PLUGIN_LIB_OBJS) libcommon.a +$(BUILDDIR)/tests/plugins/test_libplugin: $(PLUGIN_TESTLIBPLUGIN_OBJS) $(PLUGIN_LIB_OBJS) $(BUILDDIR)/libcommon.a $(PLUGIN_TESTLIBPLUGIN_OBJS): $(PLUGIN_LIB_HEADER) tests/plugins/Makefile PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_SRC := tests/plugins/test_selfdisable_after_getmanifest.c -PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_OBJS := $(PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_SRC:.c=.o) +PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_OBJS := $(PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_SRC:%.c=$(BUILDDIR)/%.o) -tests/plugins/test_selfdisable_after_getmanifest: $(PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_OBJS) libcommon.a +$(BUILDDIR)/tests/plugins/test_selfdisable_after_getmanifest: $(PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_OBJS) $(BUILDDIR)/libcommon.a PLUGIN_CHANNELD_FAKENET_SRC := tests/plugins/channeld_fakenet.c -PLUGIN_CHANNELD_FAKENET_OBJS := $(PLUGIN_CHANNELD_FAKENET_SRC:.c=.o) +PLUGIN_CHANNELD_FAKENET_OBJS := $(PLUGIN_CHANNELD_FAKENET_SRC:%.c=$(BUILDDIR)/%.o) -tests/plugins/channeld_fakenet: \ +$(BUILDDIR)/tests/plugins/channeld_fakenet: \ $(PLUGIN_CHANNELD_FAKENET_OBJS) \ + $(addprefix $(BUILDDIR)/, \ channeld/channeld_wiregen.o \ channeld/commit_tx.o \ channeld/full_channel.o \ channeld/inflight.o \ - libcommon.a + libcommon.a \ + ) # Make sure these depend on everything. -ALL_TEST_PROGRAMS += tests/plugins/test_libplugin tests/plugins/test_selfdisable_after_getmanifest tests/plugins/channeld_fakenet +ALL_TEST_PROGRAMS += $(addprefix $(BUILDDIR)/tests/plugins/,test_libplugin test_selfdisable_after_getmanifest channeld_fakenet) ALL_C_SOURCES += $(PLUGIN_TESTLIBPLUGIN_SRC) $(PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_SRC) $(PLUGIN_CHANNELD_FAKENET_SRC) + +obsclean:: + $(RM) tests/plugins/*.o diff --git a/tools/Makefile b/tools/Makefile index 4ffac102af94..1cf67bd99e4f 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,7 +1,7 @@ #! /usr/bin/make -TOOLS := tools/lightning-hsmtool tools/lightning-downgrade -TOOLS_SRC := $(TOOLS:=.c) -TOOLS_OBJ := $(TOOLS_SRC:.c=.o) +TOOLS_SRC := tools/lightning-hsmtool.c tools/lightning-downgrade.c +TOOLS_OBJS := $(TOOLS_SRC:%.c=$(BUILDDIR)/%.o) +TOOLS := $(TOOLS_OBJS:.o=) # Make sure these depend on everything. ALL_C_SOURCES += $(TOOLS_SRC) @@ -10,33 +10,31 @@ ALL_PROGRAMS += $(TOOLS) # We force make to relink this every time, to detect version changes. # Do it atomically, otherwise parallel builds can get upset! -tools/headerversions: $(FORCE) tools/headerversions.o libccan.a - @trap "rm -f $@.tmp.$$$$" EXIT; $(LINK.c) tools/headerversions.o libccan.a $(LOADLIBES) $(LDLIBS) -o $@.tmp.$$$$ && mv -f $@.tmp.$$$$ $@ +$(BUILDDIR)/tools/headerversions: $(FORCE) $(addprefix $(BUILDDIR)/,tools/headerversions.o libccan.a) + @trap "rm -f $@.tmp.$$$$" EXIT; $(LINK.c) $(addprefix $(BUILDDIR)/,tools/headerversions.o libccan.a) $(LOADLIBES) $(LDLIBS) -o $@.tmp.$$$$ && mv -f $@.tmp.$$$$ $@ -$(TOOLS): libcommon.a +$(TOOLS): $(BUILDDIR)/libcommon.a -tools/headerversions.o: ccan/config.h -tools/lightning-hsmtool: tools/lightning-hsmtool.o -tools/lightning-downgrade.o: CFLAGS:=$(CFLAGS) -DCLN_PREV_VERSION=$(CLN_PREV_VERSION) +$(BUILDDIR)/tools/headerversions.o: ccan/config.h +$(BUILDDIR)/tools/lightning-hsmtool: $(BUILDDIR)/tools/lightning-hsmtool.o +$(BUILDDIR)/tools/lightning-downgrade.o: CFLAGS:=$(CFLAGS) -DCLN_PREV_VERSION=$(CLN_PREV_VERSION) -tools/lightning-downgrade: \ +$(BUILDDIR)/tools/lightning-downgrade: \ + $(addprefix $(BUILDDIR)/, \ db/exec.o \ db/bindings.o \ db/utils.o \ wallet/datastore.o \ wallet/migrations.o \ plugins/askrene/datastore_wire.o \ - $(DB_OBJS) \ $(WALLET_DB_QUERIES:.c=.o) \ - tools/lightning-downgrade.o + tools/lightning-downgrade.o \ + ) \ + $(DB_OBJS) update-mocks: $(tools/lightning-downgrade.c:%=update-mocks/%.c) -clean: tools-clean - -tools-clean: - $(RM) $(TOOLS) $(TOOLS_OBJ) - $(RM) tools/headerversions - $(RM) tools/headerversions.o +obsclean:: + $(RM) tools/headerversions tools/*.o include tools/test/Makefile diff --git a/tools/test/Makefile b/tools/test/Makefile index c9482c9b00e7..d44e6a30e6e5 100644 --- a/tools/test/Makefile +++ b/tools/test/Makefile @@ -10,10 +10,10 @@ check-units: check-tools TOOL_TEST_INCL_SRC := tools/test/enum.c TOOL_GEN_SRC := tools/test/test_gen.c tools/test/print_gen.c -TOOL_GEN_OBJS := $(TOOL_GEN_SRC:.c=.o) +TOOL_GEN_OBJS := $(TOOL_GEN_SRC:%.c=$(BUILDDIR)/%.o) TOOL_GEN_HEADER := tools/test/test_gen.h tools/test/print_gen.h TOOL_TEST_SRC := $(wildcard tools/test/run-*.c) -TOOL_TEST_OBJS := $(TOOL_TEST_SRC:.c=.o) +TOOL_TEST_OBJS := $(TOOL_TEST_SRC:%.c=$(BUILDDIR)/%.o) TOOL_TEST_PROGRAMS := $(TOOL_TEST_OBJS:.o=) # Get dependencies correct @@ -22,9 +22,9 @@ ALL_C_HEADERS += $(TOOL_GEN_HEADER) TOOLS_WIRE_DEPS := $(BOLT_DEPS) tools/test/test_cases $(wildcard tools/gen/*_template) -tools/test/enum.o: ccan/config.h +$(BUILDDIR)/tools/test/enum.o: ccan/config.h $(TOOL_TEST_OBJS) $(TOOL_GEN_OBJS): $(TOOL_GEN_HEADER) tools/test/Makefile -$(TOOL_TEST_PROGRAMS): $(TOOL_GEN_OBJS) tools/test/enum.o libcommon.a +$(TOOL_TEST_PROGRAMS): $(TOOL_GEN_OBJS) $(addprefix $(BUILDDIR)/,tools/test/enum.o libcommon.a) tools/test/test_gen.h: $(TOOLS_WIRE_DEPS) tools/test/Makefile $(BOLT_GEN) --page header $@ test_type < tools/test/test_cases > $@ @@ -45,6 +45,8 @@ check-tools: $(TOOL_TEST_PROGRAMS:%=unittest/%) clean: tools-test-clean +obsclean:: + $(RM) tools/test/*.o + tools-test-clean: - $(RM) $(TOOL_GEN_HEADER) $(TOOL_GEN_SRC) $(TOOL_TEST_OBJS) $(TOOL_TEST_PROGRAMS) - $(RM) $(TOOL_GEN_SRC:.c=.o) tools/test/enum.o + $(RM) $(TOOL_GEN_HEADER) $(TOOL_GEN_SRC) diff --git a/wallet/Makefile b/wallet/Makefile index 1dc4364843fa..237210998fea 100644 --- a/wallet/Makefile +++ b/wallet/Makefile @@ -21,7 +21,7 @@ WALLET_DB_QUERIES := \ WALLET_SRC := $(WALLET_LIB_SRC) $(WALLET_LIB_SRC_NOHDR) $(WALLET_DB_QUERIES) WALLET_HDRS := $(WALLET_LIB_SRC:.c=.h) -WALLET_OBJS := $(WALLET_SRC:.c=.o) +WALLET_OBJS := $(WALLET_SRC:%.c=$(BUILDDIR)/%.o) # This really should be a subdir of lightningd/. We depend on their headers! $(WALLET_OBJS): $(LIGHTNINGD_SRC:.c=.h) @@ -64,4 +64,7 @@ wallet-maintainer-clean: $(RM) wallet/statements_gettextgen.po $(RM) $(WALLET_DB_QUERIES) +obsclean:: + $(RM) wallet/*.o + include wallet/test/Makefile diff --git a/wallet/test/Makefile b/wallet/test/Makefile index 65869c5c6082..d51b54f11cb4 100644 --- a/wallet/test/Makefile +++ b/wallet/test/Makefile @@ -1,11 +1,14 @@ WALLET_TEST_SRC := $(wildcard wallet/test/run-*.c) -WALLET_TEST_OBJS := $(WALLET_TEST_SRC:.c=.o) +WALLET_TEST_OBJS := $(WALLET_TEST_SRC:%.c=$(BUILDDIR)/%.o) WALLET_TEST_PROGRAMS := $(WALLET_TEST_OBJS:.o=) ALL_C_SOURCES += $(WALLET_TEST_SRC) ALL_TEST_PROGRAMS += $(WALLET_TEST_PROGRAMS) -$(WALLET_TEST_PROGRAMS): wallet/db_sqlite3_sqlgen.o libcommon.a +$(WALLET_TEST_PROGRAMS): $(addprefix $(BUILDDIR)/,wallet/db_sqlite3_sqlgen.o libcommon.a) $(WALLET_TEST_OBJS): $(WALLET_HDRS) $(WALLET_SRC) wallet/test/Makefile check-units: $(WALLET_TEST_PROGRAMS:%=unittest/%) + +obsclean:: + $(RM) wallet/test/*.o diff --git a/wire/Makefile b/wire/Makefile index 656b64b4f92e..21e958a72d6f 100644 --- a/wire/Makefile +++ b/wire/Makefile @@ -20,7 +20,7 @@ WIRE_HEADERS := wire/onion_defs.h \ wire/wire.h \ $(WIRE_SRC:.c=.h) -WIRE_OBJS := $(WIRE_SRC:.c=.o) $(WIRE_SRC_NOHDR:.c=.o) +WIRE_OBJS := $(addprefix $(BUILDDIR)/,$(WIRE_SRC:.c=.o) $(WIRE_SRC_NOHDR:.c=.o)) $(WIRE_OBJS): $(WIRE_HEADERS) ALL_C_SOURCES += $(WIRE_SRC) $(WIRE_SRC_NOHDR) diff --git a/wire/test/Makefile b/wire/test/Makefile index ad3720ae3891..476f47c8efe6 100644 --- a/wire/test/Makefile +++ b/wire/test/Makefile @@ -3,27 +3,31 @@ check-units: wire-tests # Note that these actually #include everything they need, except ccan/ and bitcoin/. # That allows for unit testing of statics, and special effects. WIRE_TEST_SRC := $(wildcard wire/test/run-*.c) -WIRE_TEST_OBJS := $(WIRE_TEST_SRC:.c=.o) +WIRE_TEST_OBJS := $(WIRE_TEST_SRC:%.c=$(BUILDDIR)/%.o) WIRE_TEST_PROGRAMS := $(WIRE_TEST_OBJS:.o=) ALL_C_SOURCES += $(WIRE_TEST_SRC) ALL_TEST_PROGRAMS += $(WIRE_TEST_PROGRAMS) WIRE_TEST_COMMON_OBJS := \ + $(addprefix $(BUILDDIR)/, \ common/autodata.o \ common/base32.o \ common/pseudorand.o \ common/setup.o \ common/utils.o \ - common/wireaddr.o + common/wireaddr.o \ + ) # run-tlvstream.c and run-peer-wire.c provide their own mocks for randbytes_ and randbytes_overridden # run-tlvstream.c needs to reach into bitcoin/pubkey for SUPERVERBOSE -$(WIRE_TEST_PROGRAMS): $(WIRE_TEST_COMMON_OBJS) $(filter-out bitcoin/pubkey.o bitcoin/chainparams.o,$(BITCOIN_OBJS)) +$(WIRE_TEST_PROGRAMS): $(WIRE_TEST_COMMON_OBJS) $(filter-out $(addprefix $(BUILDDIR)/bitcoin/,pubkey.o chainparams.o),$(BITCOIN_OBJS)) $(WIRE_TEST_OBJS): $(WIRE_HEADERS) $(WIRE_SRC) $(WIRE_PRINT_SRC) wire/test/Makefile wire-tests: $(WIRE_TEST_PROGRAMS:%=unittest/%) -wire/test/run-peer-wire: wire/peer_wiregen.o common/bigsize.o +$(BUILDDIR)/wire/test/run-peer-wire: $(addprefix $(BUILDDIR)/,wire/peer_wiregen.o common/bigsize.o) +obsclean:: + $(RM) wire/test/*.o From daa3e6f98c34d73e83f2edb793d52fad20f4717a Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Thu, 20 Aug 2026 13:37:43 -0400 Subject: [PATCH 14/17] configure: support standard variables/options for cross-compiling * --host= Specifies the tuple of the host machine on which the build products are intended to execute. Its value determines the default host-machine toolchain prefix. It defaults to empty. * --build= Specifies the tuple of the build machine on which the build itself executes. Its value determines the default build-machine toolchain prefix. It defaults to empty. * CC= Specifies the host-machine compiler driver. It defaults to "${HOST}-cc" if "${HOST}" is not empty, else "cc". * CFLAGS= Specifies the host-machine compiler flags. It defaults to empty. "-ffunction-sections" will be prepended if "${CC}" supports it. * CPPFLAGS= Specifies the host-machine preprocessor flags. It defaults to "-std=gnu11". * LDFLAGS= Specifies the host-machine linker flags. It defaults to empty. "-Wl,--gc-sections" will be prepended if "${CC}" supports it. * CC_FOR_BUILD= Specifies the build-machine compiler driver. It defaults to "${CC}" if "${BUILD}" == "${HOST}", else "${BUILD}-cc" if "${BUILD}" is not empty, else "cc". * CFLAGS_FOR_BUILD= Specifies the build-machine compiler flags. It defaults to "${CFLAGS}" if "${BUILD}" == "${HOST}", else "-O1". "-ffunction-sections" will be prepended if "${CC_FOR_BUILD}" supports it. * CPPFLAGS_FOR_BUILD= Specifies the build-machine preprocessor flags. It defaults to "${CPPFLAGS}" if "${BUILD}" == "${HOST}", else "-std=gnu11". * LDFLAGS_FOR_BUILD= Specifies the build-machine linker flags. It defaults to empty. "-Wl,--gc-sections" will be prepended if "${CC_FOR_BUILD}" supports it. Build Configurator with "${CC_FOR_BUILD}" since it needs to run on the build machine. Changelog-Added: Configure has gained new options supporting cross-compilation. --- configure | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 91283bc5708d..7101458d3ee5 100755 --- a/configure +++ b/configure @@ -174,10 +174,10 @@ set_defaults() # Note that ":-" means substitute if empty or unset, "-" means only if unset # which matters since you might explicitly set of these blank. PREFIX=${PREFIX:-/usr/local} - CC=${CC:-cc} # A more compact way of setting the default value of a variable. # Similar to the above, ":=" means assign if empty or unset; "=" means assign only if unset. # The quotes suppress the globbing that would otherwise occur after variable expansion. + : "${CC:=${HOST:+$HOST-}cc}" : "${CPPFLAGS=-std=gnu11}" # Detect macOS and use appropriate debug flags for libbacktrace compatibility if [ "$(uname -s)" = "Darwin" ]; then @@ -220,6 +220,17 @@ set_defaults() PYTEST=${PYTEST-$(default_pytest $PYTHON)} COPTFLAGS=${COPTFLAGS-$(default_coptflags "$DEBUGBUILD")} CONFIGURATOR_CC=${CONFIGURATOR_CC-$CC} + if [ "x$BUILD" = "x$HOST" ]; then + : "${CC_FOR_BUILD:=$CC}" + : "${CFLAGS_FOR_BUILD=$CFLAGS}" + : "${CPPFLAGS_FOR_BUILD=$CPPFLAGS}" + : "${LDFLAGS_FOR_BUILD=$LDFLAGS}" + else + : "${CC_FOR_BUILD:=${BUILD:+$BUILD-}cc}" + : "${CFLAGS_FOR_BUILD=-O1}" + : "${CPPFLAGS_FOR_BUILD=-std=gnu11}" + : "${LDFLAGS_FOR_BUILD=}" + fi VALGRIND=${VALGRIND:-$(default_valgrind_setting)} TEST_NETWORK=${TEST_NETWORK:-regtest} RUST=${RUST:-$(default_rust_setting)} @@ -258,11 +269,23 @@ usage() fi usage_with_default "CONFIGURATOR_CC" "${CONFIGURATOR_CC:-$CC}" echo " To override compile line for configurator itself" + usage_with_default "CC_FOR_BUILD" "$CC_FOR_BUILD" + echo " To set compiler driver for build system when cross-compiling" + usage_with_default "CFLAGS_FOR_BUILD" "$CFLAGS_FOR_BUILD" + echo " To set compiler flags for build system when cross-compiling" + usage_with_default "CPPFLAGS_FOR_BUILD" "$CPPFLAGS_FOR_BUILD" + echo " To set preprocessor flags for build system when cross-compiling" + usage_with_default "LDFLAGS_FOR_BUILD" "$LDFLAGS_FOR_BUILD" + echo " To set linker flags for build system when cross-compiling" usage_with_default "PYTEST" "$PYTEST" usage_with_default "VALGRIND" "$VALGRIND" usage_with_default "SED" "$SED" echo "Options include:" + usage_with_default "--host=" "$HOST" + echo " Compile to execute on host machine tuple" + usage_with_default "--build=" "$BUILD" + echo " Compile on build machine tuple" usage_with_default "--prefix=" "$PREFIX" echo " Prefix for make install" usage_with_default "--enable/disable-debugbuild" "$DEBUGBUILD" "enable" "disable" @@ -329,7 +352,13 @@ for opt in "$@"; do CFLAGS=*) CFLAGS="${opt#CFLAGS=}";; CPPFLAGS=*) CPPFLAGS="${opt#CPPFLAGS=}";; LDFLAGS=*) LDFLAGS="${opt#LDFLAGS=}";; + CC_FOR_BUILD=*) CC_FOR_BUILD="${opt#*=}";; + CFLAGS_FOR_BUILD=*) CFLAGS_FOR_BUILD="${opt#*=}";; + CPPFLAGS_FOR_BUILD=*) CPPFLAGS_FOR_BUILD="${opt#*=}";; + LDFLAGS_FOR_BUILD=*) LDFLAGS_FOR_BUILD="${opt#*=}";; PYTEST=*) PYTEST="${opt#PYTEST=}";; + --host=*) HOST="${opt#*=}";; + --build=*) BUILD="${opt#*=}";; --prefix=*) PREFIX="${opt#--prefix=}";; --enable-debugbuild) DEBUGBUILD=1;; --disable-debugbuild) DEBUGBUILD=0;; @@ -387,16 +416,29 @@ fi # We call this first, so we can make sure configurator runs with it as a sanity check! if have_function_sections $CC "${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS $CFLAGS $CPPFLAGS"; then + case " $CFLAGS " in + *' -ffunction-sections '*) ;; + *) CFLAGS="-ffunction-sections $CFLAGS" ;; + esac case "$LDFLAGS" in *'--gc-sections'*) ;; *) LDFLAGS="-Wl,--gc-sections $LDFLAGS";; esac - COPTFLAGS="$COPTFLAGS -ffunction-sections" + if [ "x$CC_FOR_BUILD" = "x$CC" ]; then + case " $CFLAGS_FOR_BUILD " in + *' -ffunction-sections '*) ;; + *) CFLAGS_FOR_BUILD="-ffunction-sections $CFLAGS_FOR_BUILD";; + esac + case "$LDFLAGS_FOR_BUILD" in + *'--gc-sections'*) ;; + *) LDFLAGS_FOR_BUILD="-Wl,--gc-sections $LDFLAGS_FOR_BUILD";; + esac + fi fi # We assume warning flags don't affect congfigurator that much! printf 'Compiling %s...' "${CONFIGURATOR}" >&2 -$CC ${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS $CFLAGS $CPPFLAGS $LDFLAGS -o $CONFIGURATOR $CONFIGURATOR.c +$CC_FOR_BUILD $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD -o $CONFIGURATOR $CONFIGURATOR.c echo "done" >&2 if [ "$CLANG_COVERAGE" = "1" ]; then @@ -630,6 +672,8 @@ if [ -z ${CWARNFLAGS+x} ]; then "$DEBUGBUILD") fi +add_var HOST "$HOST" +add_var BUILD "$BUILD" add_var PREFIX "$PREFIX" add_var CC "$CC" add_var CONFIGURATOR_CC "$CONFIGURATOR_CC" @@ -639,6 +683,10 @@ add_var COPTFLAGS "$COPTFLAGS" add_var CFLAGS "$CFLAGS" add_var CPPFLAGS "$CPPFLAGS" add_var LDFLAGS "$LDFLAGS" +add_var CC_FOR_BUILD "$CC_FOR_BUILD" +add_var CFLAGS_FOR_BUILD "$CFLAGS_FOR_BUILD" +add_var CPPFLAGS_FOR_BUILD "$CPPFLAGS_FOR_BUILD" +add_var LDFLAGS_FOR_BUILD "$LDFLAGS_FOR_BUILD" if [ -n "${SDKROOT:-}" ]; then add_var SDKROOT "$SDKROOT" fi From 5663e128f54dc1dad4f1100010032d5a0b67fa46 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sun, 23 Aug 2026 21:23:34 -0400 Subject: [PATCH 15/17] configure: do not require configurator tests to be executed We can test for the usability of headers and link libraries without needing to execute the build products of the configurator tests. This is crucial when cross-building, as the configurator build products may be targeted at an architecture that the build machine cannot execute. Changelog-None --- configure | 78 +++++++++++++++++++------------------------------------ 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/configure b/configure index 7101458d3ee5..c7c80db031ea 100755 --- a/configure +++ b/configure @@ -504,88 +504,62 @@ $CONFIGURATOR --extra-tests --autotools-style --var-file=$CONFIG_VAR_FILE.$$ --h var=HAVE_ZLIB desc=zlib support -style=DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE +style=OUTSIDE_MAIN link=-lz code= #include -#include -int main(void) -{ - gzFile f = gzopen("/dev/null", "wb"); - if (f != NULL) { - gzclose(f); - return 0; - } - return 1; -} +gzFile (*test0)(const char *, const char *) = &gzopen; +int (*test1)(gzFile) = &gzclose; /*END*/ var=HAVE_GOOD_LIBSODIUM desc=libsodium with IETF chacha20 variants -style=DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE -link=$SODIUM_LDLIBS +style=OUTSIDE_MAIN +link=${SODIUM_LDLIBS:--lsodium_disabled} code= #include -#include -#include -int main(void) -{ - crypto_secretstream_xchacha20poly1305_state crypto_state; - unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; - unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]; - - crypto_secretstream_xchacha20poly1305_keygen(key); - crypto_secretstream_xchacha20poly1305_init_push(&crypto_state, header, - key); - printf("%p\n", crypto_aead_chacha20poly1305_ietf_encrypt); - printf("%d\n", crypto_aead_chacha20poly1305_ietf_NPUBBYTES); - return 0; -} +void (*func0)(unsigned char *) = &crypto_secretstream_xchacha20poly1305_keygen; +int (*func1)(crypto_secretstream_xchacha20poly1305_state *, unsigned char *, + const unsigned char *) + = &crypto_secretstream_xchacha20poly1305_init_push; +int (*func2)(unsigned char *, unsigned long long *, const unsigned char *, + unsigned long long, const unsigned char *, unsigned long long, + const unsigned char *, const unsigned char *, + const unsigned char *) + = &crypto_aead_chacha20poly1305_ietf_encrypt; +enum { TEST = crypto_aead_chacha20poly1305_NPUBBYTES }; /*END*/ var=HAVE_SQLITE3 desc=sqlite3 -style=DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE -link=$SQLITE3_LDLIBS +style=OUTSIDE_MAIN +link=${SQLITE3_LDLIBS:--lsqlite3_disabled} code= #include -#include -int main(void) -{ - printf("%p\n", sqlite3_prepare_v2); - return 0; -} +int (*func)(sqlite3 *, const char *, int, sqlite3_stmt **, const char **) + = &sqlite3_prepare_v2; /*END*/ var=HAVE_POSTGRES desc=postgres -style=DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE -link=$POSTGRES_LDLIBS +style=OUTSIDE_MAIN +link=${POSTGRES_LDLIBS:--lpq_disabled} code= #include -#include -int main(void) -{ - printf("libpq version %d\n", PQlibVersion()); - return 0; -} +int (*func)(void) = &PQlibVersion; /*END*/ var=HAVE_USDT desc=User Statically-Defined Tracing (USDT) -style=DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE +style=DEFINES_FUNC code= #include -int main(void) -{ - DTRACE_PROBE(lightningd, test_sdt); - return 0; -} +static void func(void) { DTRACE_PROBE(lightningd, test_sdt); } /*END*/ var=HAVE_GCC desc=compiler is GCC -style=OUTSIDE_MAIN +style=DEFINES_EVERYTHING code= #ifndef __GNUC__ #error "Not GCC" @@ -596,7 +570,7 @@ code= /*END*/ var=HAVE_MODERN_GCC desc=GCC version is 7 or above -style=OUTSIDE_MAIN +style=DEFINES_EVERYTHING code= #if __GNUC__ < 7 #error "Not modern GCC" From a6dbca93878a807abe868d9907167242903a58c8 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sun, 23 Aug 2026 21:47:15 -0400 Subject: [PATCH 16/17] headerversions: rewrite as a shell script headerversions as a compiled program does not play nicely with cross- building, and we can't simply tweak the Makefiles to build it using $(CC_FOR_BUILD), as the version of SQLite3 visible to the build-machine toolchain may differ from the version visible to the host-machine toolchain. Rewrite this build-time tool in POSIX shell so that it runs and emits version information relevant to the host machine even when cross-building on a build machine that may lack SQLite3 or may have a different version of it installed. Changelog-None --- Makefile | 8 +++-- tools/Makefile | 6 ---- tools/header-versions.sh | 50 +++++++++++++++++++++++++++++ tools/headerversions.c | 69 ---------------------------------------- 4 files changed, 56 insertions(+), 77 deletions(-) create mode 100755 tools/header-versions.sh delete mode 100644 tools/headerversions.c diff --git a/Makefile b/Makefile index e30ba3031b66..b244db740594 100644 --- a/Makefile +++ b/Makefile @@ -803,8 +803,10 @@ version_gen.h: $(FORCE) @if cmp $@.new $@ >/dev/null 2>&1; then rm -f $@.new; else mv $@.new $@; $(ECHO) Version updated; fi endif -header_versions_gen.h: $(BUILDDIR)/tools/headerversions $(FORCE) - @$< $@ +header_versions_gen.h: tools/header-versions.sh $(FORCE) + @HAVE_SQLITE3='$(HAVE_SQLITE3)' \ + SQLITE3_CFLAGS='$(SQLITE3_CFLAGS)' \ + $< $@ # Once you have libccan.a, you don't need these. .INTERMEDIATE: $(CCAN_OBJS) @@ -887,10 +889,12 @@ maintainer-clean: distclean # We used to have gen_ files, now we have _gen files. # We used to generate doc/schemas/lightning-sql.json. +# headerversions used to be a compiled program. # Build products used to land inside the source tree. obsclean:: $(RM) gen_*.h */gen_*.[ch] */*/gen_*.[ch] $(RM) doc/schemas/lightning-sql.json + $(RM) tools/headerversions tools/headerversions.o $(RM) libccan.a $(RM) ccan/ccan/cdump/tools/cdump-enumstr ccan/ccan/cdump/tools/cdump-enumstr.o $(RM) $(ALL_OBJS:$(BUILDDIR)/%=%) diff --git a/tools/Makefile b/tools/Makefile index 1cf67bd99e4f..d7fff6e5806a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -8,14 +8,8 @@ ALL_C_SOURCES += $(TOOLS_SRC) ALL_C_HEADERS += ALL_PROGRAMS += $(TOOLS) -# We force make to relink this every time, to detect version changes. -# Do it atomically, otherwise parallel builds can get upset! -$(BUILDDIR)/tools/headerversions: $(FORCE) $(addprefix $(BUILDDIR)/,tools/headerversions.o libccan.a) - @trap "rm -f $@.tmp.$$$$" EXIT; $(LINK.c) $(addprefix $(BUILDDIR)/,tools/headerversions.o libccan.a) $(LOADLIBES) $(LDLIBS) -o $@.tmp.$$$$ && mv -f $@.tmp.$$$$ $@ - $(TOOLS): $(BUILDDIR)/libcommon.a -$(BUILDDIR)/tools/headerversions.o: ccan/config.h $(BUILDDIR)/tools/lightning-hsmtool: $(BUILDDIR)/tools/lightning-hsmtool.o $(BUILDDIR)/tools/lightning-downgrade.o: CFLAGS:=$(CFLAGS) -DCLN_PREV_VERSION=$(CLN_PREV_VERSION) diff --git a/tools/header-versions.sh b/tools/header-versions.sh new file mode 100755 index 000000000000..1e392f1c5cff --- /dev/null +++ b/tools/header-versions.sh @@ -0,0 +1,50 @@ +#!/bin/sh +set -e -o pipefail + +if [ "$#" -ne 1 ] ; then + echo "Usage: $0 " >&2 + exit 1 +fi + +unset file +if [ -f "$1" ] ; then + exec <"$1" + flock 0 + file="$(cat)" +fi + +have_sqlite3() { [ "${HAVE_SQLITE3:-0}" -ne 0 ] ; } +if have_sqlite3 ; then + SQLITE_VERSION_NUMBER=$({ + ${CC:-cc} ${SQLITE3_CFLAGS} -E -o - - <<-END + #include + SQLITE_VERSION_NUMBER + END + } | tail -n1) +fi + +new=$( + echo "/* Generated file by $0, do not edit! */" + have_sqlite3 && echo "/* SQLITE3 version: ${SQLITE_VERSION_NUMBER} */" + echo '#include ' + have_sqlite3 && echo '#include ' + echo + echo 'static inline void check_linked_library_versions(void)' + echo '{' + have_sqlite3 && printf '%s\n' \ + ' /* Require at least the version we compiled with. */' \ + ' if (SQLITE_VERSION_NUMBER > sqlite3_libversion_number())' \ + ' errx(1, "SQLITE version mismatch: compiled %u, now %u",' \ + ' SQLITE_VERSION_NUMBER, sqlite3_libversion_number());' \ + ' /* Ensure the major version matches. */' \ + ' if (SQLITE_VERSION_NUMBER + 1000000 < sqlite3_libversion_number())' \ + ' errx(1, "SQLITE major version mismatch: compiled %u, now %u",' \ + ' SQLITE_VERSION_NUMBER, sqlite3_libversion_number());' \ + ' /* Earliest supported sqlite3 version */' \ + ' if (SQLITE_VERSION_NUMBER < 3026000)' \ + ' errx(1, "SQLITE version %u too old (minimum 3.26)",' \ + ' SQLITE_VERSION_NUMBER);' + echo '}' +) + +[ "${new}" = "${file}" ] || echo "${new}" >"$1" diff --git a/tools/headerversions.c b/tools/headerversions.c deleted file mode 100644 index 8cee70adf8e3..000000000000 --- a/tools/headerversions.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Updates the given file if any library versions have changed. This - * is important for systemwide updates, such as sqlite3. */ -#include "config.h" -#include -#include -#include -#include -#include -#include -#if HAVE_SQLITE3 -# include -# define IF_SQLITE3(...) __VA_ARGS__ -#else -# define IF_SQLITE3(...) -#endif -#include - -static const char template[] = - "/* Generated file by tools/headerversions, do not edit! */\n" - IF_SQLITE3("/* SQLITE3 version: %u */\n") - "#include \n" - IF_SQLITE3("#include \n") - "\n" - "static inline void check_linked_library_versions(void)\n" - "{\n" - IF_SQLITE3( - " /* Require at least the version we compiled with. */" - " if (SQLITE_VERSION_NUMBER > sqlite3_libversion_number())\n" - " errx(1, \"SQLITE version mismatch: compiled %%u, now %%u\",\n" - " SQLITE_VERSION_NUMBER, sqlite3_libversion_number());\n" - " /* Ensure the major version matches. */" - " if (SQLITE_VERSION_NUMBER + 1000000 < sqlite3_libversion_number())\n" - " errx(1, \"SQLITE major version mismatch: compiled %%u, now %%u\",\n" - " SQLITE_VERSION_NUMBER, sqlite3_libversion_number());\n" - " /* Earliest supported sqlite3 version */\n" - " if (SQLITE_VERSION_NUMBER < 3026000)\n" - " errx(1, \"SQLITE version %%u too old (minimum 3.26)\",\n" - " SQLITE_VERSION_NUMBER);\n" - ) - "}\n"; - -int main(int argc, char *argv[]) -{ - char *file, *new; - - /* We don't bother with setup_locale(); we're a build tool */ - err_set_progname(argv[0]); - - if (argc != 2) - errx(1, "Usage: %s ", argv[0]); - - file = grab_file_str(NULL, argv[1]); - if (!file && errno != ENOENT) - err(1, "Reading %s", argv[1]); - - new = tal_fmt(NULL, template - IF_SQLITE3(, sqlite3_libversion_number())); - if (!file || !streq(new, file)) { - int fd = open(argv[1], O_TRUNC|O_WRONLY|O_CREAT, 0666); - if (fd < 0) - err(1, "Writing %s", argv[1]); - if (!write_all(fd, new, strlen(new))) - err(1, "Writing to %s", argv[1]); - close(fd); - } - tal_free(new); - tal_free(file); - return 0; -} From cbb13eb02694eb71af02d1d344437a1652e26910 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Mon, 24 Aug 2026 04:21:49 -0400 Subject: [PATCH 17/17] build: fully support cross-building MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce some new Make variables: * BUILD: the build-machine tuple * AR_FOR_BUILD: ar for the build machine * CC_FOR_BUILD: C compiler for the build machine * CFLAGS_FOR_BUILD: compiler flags for the build machine * CPPFLAGS_FOR_BUILD: preprocessor flags for the build machine * LDFLAGS_FOR_BUILD: linker flags for the build machine * CROSS_BUILD: defined iff doing a cross-build * BUILDDIR_FOR_BUILD: build output directory for build machine Introduce a new $(BUILDDIR_FOR_BUILD)/libccan.a static library, which contains the code needed by build-time tools (namely, cdump_enumstr), compiled for the build machine. Don't regenerate doc/schemas/sql.json when doing a cross-build, as $(BUILDDIR)/plugins/sql is not going to run on the build machine. Eliminate references to QEMU in doc/…/getting-started/installation.md, as emulation is no longer needed when configuring CLN for a cross-build. Changelog-None --- Makefile | 103 ++++++++++++++++-- doc/Makefile | 11 +- .../getting-started/installation.md | 32 ++---- external/Makefile | 2 +- 4 files changed, 111 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index b244db740594..ce2e41bb9657 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,14 @@ BOLTVERSION := $(DEFAULT_BOLTVERSION) -include config.vars +ifdef BUILD +AR_FOR_BUILD ?= $(BUILD)-ar +CC_FOR_BUILD ?= $(BUILD)-cc +else +AR_FOR_BUILD ?= ar +CC_FOR_BUILD ?= cc +endif + # Save flags inherited from environment (or config.vars) before we start munging them CFLAGS_FROM_ENV := $(CFLAGS) CFLAGS = @@ -46,17 +54,76 @@ CPPFLAGS_FROM_ENV := $(CPPFLAGS) CPPFLAGS = LDFLAGS_FROM_ENV := $(LDFLAGS) LDFLAGS = +ifneq ($(origin CFLAGS_FOR_BUILD),undefined) +CFLAGS_FOR_BUILD_FROM_ENV := $(CFLAGS_FOR_BUILD) +endif +CFLAGS_FOR_BUILD = +ifneq ($(origin CPPFLAGS_FOR_BUILD),undefined) +CPPFLAGS_FOR_BUILD_FROM_ENV := $(CPPFLAGS_FOR_BUILD) +endif +CPPFLAGS_FOR_BUILD = +ifneq ($(origin LDFLAGS_FOR_BUILD),undefined) +LDFLAGS_FOR_BUILD_FROM_ENV := $(LDFLAGS_FOR_BUILD) +endif +LDFLAGS_FOR_BUILD = + +# Determine whether we are cross-building +CROSS_BUILD := 1 +ifeq ($(CC_FOR_BUILD),$(CC)) +CFLAGS_FOR_BUILD_FROM_ENV ?= $(CFLAGS_FROM_ENV) +CPPFLAGS_FOR_BUILD_FROM_ENV ?= $(CPPFLAGS_FROM_ENV) +LDFLAGS_FOR_BUILD_FROM_ENV ?= $(LDFLAGS_FROM_ENV) +ifeq ($(CFLAGS_FOR_BUILD_FROM_ENV),$(CFLAGS_FROM_ENV)) +ifeq ($(CPPFLAGS_FOR_BUILD_FROM_ENV),$(CPPFLAGS_FROM_ENV)) +ifeq ($(LDFLAGS_FOR_BUILD_FROM_ENV),$(LDFLAGS_FROM_ENV)) +undefine CROSS_BUILD +endif +endif +endif +endif # Look up the host machine tuple if not specified ifndef HOST HOST := $(shell $(CC) $(CFLAGS_FROM_ENV) -dumpmachine) endif -# Set a default build directory if not specified +# Look up the build machine tuple if not specified +ifndef BUILD +ifdef CROSS_BUILD +BUILD := $(shell $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD_FROM_ENV) -dumpmachine) +else +BUILD := $(HOST) +endif +endif + +# Set a default host-machine build directory if not specified ifndef BUILDDIR BUILDDIR := build/$(HOST) endif +# Set a default build-machine build directory if not specified +ifndef BUILDDIR_FOR_BUILD +ifdef CROSS_BUILD +ifneq ($(BUILD),$(HOST)) +BUILDDIR_FOR_BUILD := build/$(BUILD) +else +BUILDDIR_FOR_BUILD := $(BUILDDIR).build +endif +else +BUILDDIR_FOR_BUILD := $(BUILDDIR) +endif +endif + +# Override toolchain when building targets for build machine +ifdef CROSS_BUILD +$(BUILDDIR_FOR_BUILD)/%: override CC = $(CC_FOR_BUILD) +$(BUILDDIR_FOR_BUILD)/%: override CFLAGS = $(CFLAGS_FOR_BUILD) +$(BUILDDIR_FOR_BUILD)/%: override CPPFLAGS = $(CPPFLAGS_FOR_BUILD) +$(BUILDDIR_FOR_BUILD)/%: override LDFLAGS = $(LDFLAGS_FOR_BUILD) +$(BUILDDIR_FOR_BUILD)/%: override LDLIBS = $(LDLIBS_FOR_BUILD) +$(BUILDDIR_FOR_BUILD)/%: override EXTERNAL_LDLIBS = $(EXTERNAL_LDLIBS_FOR_BUILD) +endif + # Use Homebrew LLVM toolchain for fuzzing support on macOS ifeq ($(OS),Darwin) export PATH := /opt/homebrew/opt/llvm/bin:$(PATH) @@ -124,7 +191,6 @@ CCAN_OBJS := \ bitmap/bitmap.o \ bitops/bitops.o \ breakpoint/breakpoint.o \ - cdump/cdump.o \ closefrom/closefrom.o \ crc32c/crc32c.o \ crypto/hkdf_sha256/hkdf_sha256.o \ @@ -175,6 +241,18 @@ CCAN_OBJS := \ utf8/utf8.o \ ) +CCAN_BUILD_OBJS := \ + $(addprefix $(BUILDDIR_FOR_BUILD)/$(CCANDIR)/ccan/, \ + cdump/cdump.o \ + list/list.o \ + noerr/noerr.o \ + strmap/strmap.o \ + take/take.o \ + tal/grab_file/grab_file.o \ + tal/str/str.o \ + tal/tal.o \ + ) + CCAN_HEADERS := \ $(CCANDIR)/config.h \ $(addprefix $(CCANDIR)/ccan/, \ @@ -317,6 +395,10 @@ CPPFLAGS += -DCLN_NEXT_VERSION="\"$(CLN_NEXT_VERSION)\"" -DPKGLIBEXECDIR="\"$(pk CFLAGS = $(CWARNFLAGS) $(CDEBUGFLAGS) $(COPTFLAGS) $(SQLITE3_CFLAGS) $(SODIUM_CFLAGS) $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) $(PIE_CFLAGS) $(CSANFLAGS) $(CFLAGS_FROM_ENV) LDFLAGS += $(PIE_LDFLAGS) $(LDFLAGS_FROM_ENV) +CFLAGS_FOR_BUILD = $(CWARNFLAGS) $(CFLAGS_FOR_BUILD_FROM_ENV) +CPPFLAGS_FOR_BUILD = -I$(CCANDIR) -I. $(CPPFLAGS_FOR_BUILD_FROM_ENV) +LDFLAGS_FOR_BUILD = $(LDFLAGS_FOR_BUILD_FROM_ENV) + # If CFLAGS is already set in the environment of make (to whatever value, it # does not matter) then it would export it to subprocesses with the above value # we set, including CWARNFLAGS which by default contains -Wall -Werror. This @@ -378,7 +460,7 @@ SHA256STAMP_CHANGED = [ x"`$(SED) -n 's/.*SHA256STAMP:\([a-f0-9]*\).*/\1/p' $@ 2 SHA256STAMP = echo "$(1) SHA256STAMP:"`cat $(sort $(filter-out FORCE,$^)) | $(SHA256SUM) | cut -c1-64`"$(2)" >> $@ endif -CDUMP_ENUMSTR := $(BUILDDIR)/ccan/ccan/cdump/tools/cdump-enumstr +CDUMP_ENUMSTR := $(BUILDDIR_FOR_BUILD)/ccan/ccan/cdump/tools/cdump-enumstr # generate-wire.py --page [header|impl] hdrfilename wirename < csv > file %_wiregen.h: %_wire.csv $(WIRE_GEN_DEPS) @@ -809,14 +891,18 @@ header_versions_gen.h: tools/header-versions.sh $(FORCE) $< $@ # Once you have libccan.a, you don't need these. -.INTERMEDIATE: $(CCAN_OBJS) +.INTERMEDIATE: $(CCAN_OBJS) $(CCAN_BUILD_OBJS) # We make a static library, this way linker can discard unused parts. $(BUILDDIR)/libccan.a: $(BUILDDIR)/libccan.a($(CCAN_OBJS)) +$(BUILDDIR_FOR_BUILD)/libccan.a: $(BUILDDIR_FOR_BUILD)/libccan.a($(CCAN_BUILD_OBJS)) -# All binaries require the external libs, ccan and system library versions. +# All host-machine programs require the external libs and ccan. $(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS) $(ALL_FUZZ_TARGETS): $(EXTERNAL_LIBS) $(BUILDDIR)/libccan.a +# All build-machine programs require ccan built for the build machine. +$(ALL_BUILD_PROGRAMS): $(BUILDDIR_FOR_BUILD)/libccan.a + # Each build-time program depends on its own object. $(ALL_BUILD_PROGRAMS) $(ALL_TEST_PROGRAMS) $(ALL_FUZZ_TARGETS): %: %.o @@ -854,7 +940,7 @@ endif # Everything depends on the CCAN headers, and Makefile -$(CCAN_OBJS) $(CDUMP_OBJS): $(CCAN_HEADERS) Makefile ccan_compat.h +$(CCAN_OBJS) $(CCAN_BUILD_OBJS): $(CCAN_HEADERS) Makefile ccan_compat.h # Except for CCAN, we treat everything else as dependent on external/ bitcoin/ common/ wire/ and all generated headers, and Makefile $(ALL_OBJS): $(BITCOIN_HEADERS) $(COMMON_HEADERS) $(CCAN_HEADERS) $(WIRE_HEADERS) $(ALL_GEN_HEADERS) $(EXTERNAL_HEADERS) Makefile @@ -903,7 +989,7 @@ obsclean:: $(RM) $(ALL_FUZZ_TARGETS:$(BUILDDIR)/%=%) clean: obsclean - $(RM) -r $(BUILDDIR) + $(RM) -r $(BUILDDIR) $(BUILDDIR_FOR_BUILD) $(RM) $(ALL_GEN_HEADERS) $(ALL_GEN_SOURCES) $(RM) $(MSGGEN_GEN_ALL) $(RM) ccan/tools/configurator/configurator @@ -1143,3 +1229,6 @@ print-binary-sizes: $(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS) $(BIN_PROGRAMS) $(BUILDDIR)/%.o: %.c | $$(@D)/ @$(call VERBOSE,"cc $<",$(COMPILE.c) -o $@ $<) + +$(BUILDDIR_FOR_BUILD)/%.o: %.c | $$(@D)/ + @$(call VERBOSE,"cc $<",$(COMPILE.c) -o $@ $<) diff --git a/doc/Makefile b/doc/Makefile index b5912c5a2096..30f6a0757491 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -201,21 +201,22 @@ NON_PREFIXED_MARKDOWNPAGES_WITH_EXT := $(NON_PREFIXED_MANPAGES:=.md) OLD_MARKDOWNPAGES_WITH_EXT := $(PREFIXED_MANPAGES:=.md) +# Don't try to build sql.json tables with plugins/sql if we don't have sqlite3 +ifneq ($(HAVE_SQLITE3),0) +# ...or if we're doing a cross build +ifndef CROSS_BUILD # - Read the json template from schemas/sql-template.json # - Generate the tables schema via plugins/sql # - Merge both and generate final schemas/sql.json doc/schemas/sql.json: doc/schemas/sql-template.json $(BUILDDIR)/plugins/sql @$(BUILDDIR)/plugins/sql --print-docs | jq --arg sqldata "$$(awk '{printf "%s\n", $$0}')" '.tables += [$$sqldata]' $< > "$@.tmp" && mv "$@.tmp" "$@"; +endif +endif doc-all: $(MANPAGES) doc/index.rst SCHEMAS := $(wildcard doc/schemas/*.json) $(NOTIFICATION_SCHEMAS) $(HOOK_SCHEMAS) -# Don't try to build sql.json tables with plugins/sql if we don't have sqlite3 -ifeq ($(HAVE_SQLITE3),0) -SCHEMAS := $(filter-out doc/schemas/sql.json, $(SCHEMAS)) -endif - check-fmt-schemas: $(SCHEMAS:%=check-fmt-schema/%) fmt-schemas: $(SCHEMAS:%=fmt-schema/%) diff --git a/doc/getting-started/getting-started/installation.md b/doc/getting-started/getting-started/installation.md index fbedcaac08e6..e7b7a70d9755 100644 --- a/doc/getting-started/getting-started/installation.md +++ b/doc/getting-started/getting-started/installation.md @@ -589,22 +589,10 @@ export LD=$target_host-ld export STRIP=$target_host-strip ``` -Two makefile targets should not be cross-compiled so we specify a native CC: -```shell -make CC=clang clean ccan/tools/configurator/configurator -make clean -C ccan/ccan/cdump/tools \ - && make CC=clang -C ccan/ccan/cdump/tools -``` - -Install the `qemu-user` package. - -This will allow you to properly configure the build for the target device environment. - Build with: ```shell -BUILD=x86_64 MAKE_HOST=arm-linux-androideabi \ - make PIE=1 \ - CONFIGURATOR_CC="arm-linux-androideabi-clang -static" +./configure --host=$target_host +make PIE=1 ``` ## To cross-compile for Raspberry Pi @@ -622,13 +610,7 @@ export CC=$target_host-gcc export CXX=$target_host-g++ export LD=$target_host-ld export STRIP=$target_host-strip -``` - -Install the `qemu-user` package. This will allow you to properly configure the build for the target device environment. - -Config the arm elf interpreter prefix: -```shell -export QEMU_LD_PREFIX=/path/to/raspberry/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/sysroot/ +export SYSROOT=/usr/$target_host ``` Obtain and install cross-compiled versions of sqlite3 and zlib: @@ -638,7 +620,7 @@ Download and build zlib: wget https://zlib.net/fossils/zlib-1.2.13.tar.gz tar xvf zlib-1.2.13.tar.gz cd zlib-1.2.13 -./configure --prefix=$QEMU_LD_PREFIX +./configure --prefix=$SYSROOT make make install ``` @@ -648,14 +630,16 @@ Download and build sqlite3: wget https://www.sqlite.org/2018/sqlite-src-3260000.zip unzip sqlite-src-3260000.zip cd sqlite-src-3260000 -./configure --enable-static --disable-readline --disable-threadsafe --disable-load-extension --host=$target_host --prefix=$QEMU_LD_PREFIX +./configure --enable-static --disable-readline --disable-threadsafe --disable-load-extension --disable-tcl --host=$target_host --prefix=$SYSROOT make make install ``` Then, build Core Lightning with the following commands: ``` -./configure +export SQLITE3_CFLAGS=-I$SYSROOT/include +export SQLITE3_LDLIBS=-lsqlite3 +./configure --host=$target_host make ``` diff --git a/external/Makefile b/external/Makefile index e3e3306f5567..efe6be80b07f 100644 --- a/external/Makefile +++ b/external/Makefile @@ -6,7 +6,7 @@ SUBMODULES = \ TOP := ../.. ifdef BUILD -CROSSCOMPILE_OPTS := --host="$(MAKE_HOST)" --build="$(BUILD)" +CROSSCOMPILE_OPTS := --host="$(HOST)" --build="$(BUILD)" endif LIBWALLY_HEADERS := external/libwally-core/include/wally_bip32.h \