From 168ad335da3b9e321d175da1320dc10654670b82 Mon Sep 17 00:00:00 2001
From: Matt Whitlock <c-lightning@mattwhitlock.name>
Date: Sat, 7 Mar 2026 08:28:31 -0500
Subject: [PATCH] Makefile: use standard variables for compiling and linking C
 programs

Make predefines variables COMPILE.c and LINK.c, providing the default
commands for compiling and linking C programs:

COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

Use these variables where appropriate.

A few points of interest:

* Using $(LINK.o) to link a C program is not correct, as it does not pass
  $(CFLAGS) to the linker driver. Passing $(CFLAGS) may be necessary for
  correct operation. For instance, -m32 can be specified in CFLAGS to build
  for a 32-bit ABI on a 64-bit-native system, and -flto can be specified in
  CFLAGS to enable link-time optimization. The linker driver needs to be
  told both of these in order to produce correct output.

* CFLAGS is not supposed to subsume CPPFLAGS. The latter are logically the
  flags for the C preprocessor, while the former are the flags for the C
  compiler. The standard COMPILE.c variable incorporates both sets of flags
  since it invokes both the preprocessor and the compiler with one command.
  The standard LINK.c variable also incorporates both since it can be used
  to preprocess, compile, and link a C program all in one shot. In its more
  typical usage (linking precompiled object files), the linker driver
  accepts but makes no use of any preprocessor flags supplied to it.

* CFLAGS logically shouldn't include any -D (or -U) options, as those are
  meant for the preprocessor and not the compiler. It arguably shouldn't
  include any -I options either, but I didn't make that fix here.

Changelog-None
---
 Makefile | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index fb9bd91102054a46126a2056f309d0fdbd3965d9..9b19fb08c807123ee6d0e4937aedc0c42538d1ba 100644
--- a/Makefile
+++ b/Makefile
@@ -289,8 +289,8 @@ 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)
+CPPFLAGS += -DCLN_NEXT_VERSION="\"$(CLN_NEXT_VERSION)\"" -DPKGLIBEXECDIR="\"$(pkglibexecdir)\"" -DBINDIR="\"$(bindir)\"" -DPLUGINDIR="\"$(plugindir)\"" -DCCAN_TAL_NEVER_RETURN_NULL=1 -DSHACHAIN_BITS=48 -DJSMN_PARENT_LINKS
+CFLAGS = $(CWARNFLAGS) $(CDEBUGFLAGS) $(COPTFLAGS) -I $(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I . -I$(CPATH) $(SQLITE3_CFLAGS) $(SODIUM_CFLAGS) $(POSTGRES_INCLUDE) $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) $(PIE_CFLAGS) $(COMPAT_CFLAGS) $(CSANFLAGS)
 
 # 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
@@ -330,8 +330,8 @@ 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) $(filter-out %.a,$^) $(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
@@ -339,7 +339,7 @@ ccan/config.h config.vars &: configure ccan/tools/configurator/configurator.c
 	./configure --reconfigure
 
 %.o: %.c
-	@$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<)
+	@$(call VERBOSE, "cc $<", $(COMPILE.c) -o $@ $<)
 
 # tools/update-mocks.sh does nasty recursive make, must not do this!
 ifeq ($(SUPPRESS_GENERATION),1)
@@ -760,7 +760,7 @@ $(ALL_TEST_PROGRAMS) $(ALL_FUZZ_TARGETS): %: %.o
 # (as per EXTERNAL_LDLIBS) so we filter them out here.  We have to put the other
 # .a files (if any) at the end of the link line.
 $(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS):
-	@$(call VERBOSE, "ld $@", $(LINK.o) $(filter-out %.a,$^) $(filter-out external/%,$(filter %.a,$^)) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $($(@)_LDLIBS) -o $@)
+	@$(call VERBOSE, "ld $@", $(LINK.c) $(filter-out %.a,$^) $(filter-out external/%,$(filter %.a,$^)) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) $($(@)_LDLIBS) -o $@)
 ifeq ($(OS),Darwin)
 	@$(call VERBOSE, "dsymutil $@", dsymutil $@)
 endif
