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 20d4aedff053..ce2e41bb9657 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,91 @@ 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 = +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 + +# 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) @@ -100,136 +185,151 @@ 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 \ + 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_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/, \ + 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) @@ -239,6 +339,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 := @@ -289,8 +390,14 @@ 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 -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) + +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 @@ -302,8 +409,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 +418,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) @@ -330,16 +431,21 @@ FORCE: endif show-flags: config.vars - @$(ECHO) "CC: $(CC) $(CFLAGS) -c -o" - @$(ECHO) "LD: $(LINK.o) $(filter-out %.a,$^) $(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 @if [ ! -f config.vars ]; then echo 'File config.vars not found: you must run ./configure before running make.' >&2; exit 1; fi ./configure --reconfigure -%.o: %.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) +%/: + @$(MKDIR_P) $(@D) + +# 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) @@ -354,6 +460,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_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) @if $(call SHA256STAMP_CHANGED); then \ @@ -459,11 +567,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 \ @@ -473,7 +584,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 $@", \ @@ -485,7 +597,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)) @@ -757,11 +869,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"). @@ -775,30 +885,34 @@ 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: 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) +.INTERMEDIATE: $(CCAN_OBJS) $(CCAN_BUILD_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)) +$(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_PROGRAMS) $(ALL_TEST_PROGRAMS) $(ALL_FUZZ_TARGETS): $(EXTERNAL_LIBS) libccan.a +# All host-machine programs require the external libs and ccan. +$(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 +# 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 # 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): - @$(call VERBOSE, "ld $@", $(LINK.o) $(filter-out %.a,$^) $(filter-out external/%,$(filter %.a,$^)) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $($(@)_LDLIBS) -o $@) +$(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 $@) endif @@ -819,14 +933,14 @@ 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,$^) $(addprefix $(BUILDDIR)/,libcommon.a libccan.a) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $(FUZZ_LDFLAGS) -o $@) ifeq ($(OS),Darwin) @$(call VERBOSE, "dsymutil $@", dsymutil $@) 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 @@ -861,19 +975,24 @@ maintainer-clean: distclean # We used to have gen_ files, now we have _gen files. # We used to generate doc/schemas/lightning-sql.json. -obsclean: +# 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)/%=%) + $(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) $(BUILDDIR_FOR_BUILD) $(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 @@ -932,7 +1051,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) @@ -946,10 +1065,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 = : @@ -958,28 +1111,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 @@ -993,13 +1144,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 @@ -1019,44 +1172,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 @@ -1072,7 +1202,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. @@ -1084,114 +1214,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 $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-base64.o: $(CCANDIR)/ccan/base64/base64.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-tal.o: $(CCANDIR)/ccan/tal/tal.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-tal-str.o: $(CCANDIR)/ccan/tal/str/str.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-tal-link.o: $(CCANDIR)/ccan/tal/link/link.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-tal-path.o: $(CCANDIR)/ccan/tal/path/path.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-tal-grab_file.o: $(CCANDIR)/ccan/tal/grab_file/grab_file.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-take.o: $(CCANDIR)/ccan/take/take.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-list.o: $(CCANDIR)/ccan/list/list.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-asort.o: $(CCANDIR)/ccan/asort/asort.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-ptr_valid.o: $(CCANDIR)/ccan/ptr_valid/ptr_valid.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-read_write_all.o: $(CCANDIR)/ccan/read_write_all/read_write_all.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-str.o: $(CCANDIR)/ccan/str/str.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-opt.o: $(CCANDIR)/ccan/opt/opt.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-opt-helpers.o: $(CCANDIR)/ccan/opt/helpers.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-opt-parse.o: $(CCANDIR)/ccan/opt/parse.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-opt-usage.o: $(CCANDIR)/ccan/opt/usage.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-err.o: $(CCANDIR)/ccan/err/err.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-noerr.o: $(CCANDIR)/ccan/noerr/noerr.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-str-hex.o: $(CCANDIR)/ccan/str/hex/hex.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-crc32c.o: $(CCANDIR)/ccan/crc32c/crc32c.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-crypto-hmac.o: $(CCANDIR)/ccan/crypto/hmac_sha256/hmac_sha256.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-crypto-hkdf.o: $(CCANDIR)/ccan/crypto/hkdf_sha256/hkdf_sha256.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -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 $@ $<) -ccan-crypto-sha256.o: $(CCANDIR)/ccan/crypto/sha256/sha256.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-crypto-ripemd160.o: $(CCANDIR)/ccan/crypto/ripemd160/ripemd160.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-cdump.o: $(CCANDIR)/ccan/cdump/cdump.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-strmap.o: $(CCANDIR)/ccan/strmap/strmap.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-strset.o: $(CCANDIR)/ccan/strset/strset.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-crypto-siphash24.o: $(CCANDIR)/ccan/crypto/siphash24/siphash24.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-htable.o: $(CCANDIR)/ccan/htable/htable.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-ilog.o: $(CCANDIR)/ccan/ilog/ilog.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-intmap.o: $(CCANDIR)/ccan/intmap/intmap.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-isaac.o: $(CCANDIR)/ccan/isaac/isaac.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-isaac64.o: $(CCANDIR)/ccan/isaac/isaac64.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-time.o: $(CCANDIR)/ccan/time/time.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-timer.o: $(CCANDIR)/ccan/timer/timer.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-io-io.o: $(CCANDIR)/ccan/io/io.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-io-poll.o: $(CCANDIR)/ccan/io/poll.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-io-fdpass.o: $(CCANDIR)/ccan/io/fdpass/fdpass.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-pipecmd.o: $(CCANDIR)/ccan/pipecmd/pipecmd.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-mem.o: $(CCANDIR)/ccan/mem/mem.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-fdpass.o: $(CCANDIR)/ccan/fdpass/fdpass.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-bitops.o: $(CCANDIR)/ccan/bitops/bitops.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-rbuf.o: $(CCANDIR)/ccan/rbuf/rbuf.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-str-base32.o: $(CCANDIR)/ccan/str/base32/base32.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-utf8.o: $(CCANDIR)/ccan/utf8/utf8.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-bitmap.o: $(CCANDIR)/ccan/bitmap/bitmap.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-membuf.o: $(CCANDIR)/ccan/membuf/membuf.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-json_escape.o: $(CCANDIR)/ccan/json_escape/json_escape.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-json_out.o: $(CCANDIR)/ccan/json_out/json_out.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-closefrom.o: $(CCANDIR)/ccan/closefrom/closefrom.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-rune-rune.o: $(CCANDIR)/ccan/rune/rune.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<) -ccan-rune-coding.o: $(CCANDIR)/ccan/rune/coding.c - @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -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* @@ -1201,3 +1223,12 @@ 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 $@ $<) + +$(BUILDDIR_FOR_BUILD)/%.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/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 $@ +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/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/configure b/configure index 0cd88749dc92..c7c80db031ea 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() { @@ -134,12 +139,12 @@ check_command() name="$1" shift 1 - echo -n "checking for $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 } @@ -169,11 +174,15 @@ 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 # 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 +191,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} @@ -211,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)} @@ -223,7 +243,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 } @@ -236,21 +256,36 @@ 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" 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 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" @@ -277,9 +312,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" @@ -314,7 +349,16 @@ 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=}";; + 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;; @@ -334,10 +378,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 +391,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 @@ -371,26 +415,38 @@ 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" - COPTFLAGS="$COPTFLAGS -ffunction-sections" -else - HAVE_FUNCTION_SECTIONS=0 - LDFLAGS= +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 + 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! -echo -n "Compiling $CONFIGURATOR..." -$CC ${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS $LDFLAGS -o $CONFIGURATOR $CONFIGURATOR.c -echo "done" +printf 'Compiling %s...' "${CONFIGURATOR}" >&2 +$CC_FOR_BUILD $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD -o $CONFIGURATOR $CONFIGURATOR.c +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,123 +457,109 @@ 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 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. 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 < -#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" @@ -528,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" @@ -604,12 +646,21 @@ 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" add_var CWARNFLAGS "$CWARNFLAGS" add_var CDEBUGFLAGS "$CDEBUGFLAGS" 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 @@ -637,7 +688,6 @@ add_var FUZZING "$FUZZING" add_var RUST "$RUST" add_var PYTHON "$PYTHON" add_var SED "$SED" -add_var HAVE_FUNCTION_SECTIONS "$HAVE_FUNCTION_SECTIONS" # Hack to avoid sha256 name clash with libwally: will be fixed when that # becomes a standalone shared lib. 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..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 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" "$@"; +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 4ff220539eb5..efe6be80b07f 100644 --- a/external/Makefile +++ b/external/Makefile @@ -6,10 +6,7 @@ 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) +CROSSCOMPILE_OPTS := --host="$(HOST)" --build="$(BUILD)" 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/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 */ 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 2d86221df962..d7fff6e5806a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,42 +1,34 @@ #! /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) 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! -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.$$$$ $@ +$(TOOLS): $(BUILDDIR)/libcommon.a -$(TOOLS): libcommon.a +$(BUILDDIR)/tools/lightning-hsmtool: $(BUILDDIR)/tools/lightning-hsmtool.o +$(BUILDDIR)/tools/lightning-downgrade.o: CFLAGS:=$(CFLAGS) -DCLN_PREV_VERSION=$(CLN_PREV_VERSION) -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) - -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/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; -} 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