Skip to content

Pedantic fixes to build system (configure, Makefile) - #8933

Open
whitslack wants to merge 7 commits into
ElementsProject:masterfrom
whitslack:build-system-pedantry
Open

Pedantic fixes to build system (configure, Makefile)#8933
whitslack wants to merge 7 commits into
ElementsProject:masterfrom
whitslack:build-system-pedantry

Conversation

@whitslack

Copy link
Copy Markdown
Collaborator

Checklist

Before submitting the PR, ensure the following tasks are completed. If an item is not applicable to your PR, please mark it as checked:

  • The changelog has been updated in the relevant commit(s) according to the guidelines.
  • Tests have been added or modified to reflect the changes. (N/A)
  • Documentation has been reviewed and updated as needed. (N/A)
  • Related issues have been listed and linked, including any that this PR closes. (N/A)
  • Important All PRs must consider how to reverse any persistent changes for tools/lightning-downgrade (N/A)

@whitslack
whitslack force-pushed the build-system-pedantry branch from 39e6288 to d8f5abf Compare March 7, 2026 20:09
Comment thread Makefile
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 -DSHACHAIN_BITS=48 -DJSMN_PARENT_LINKS $(CPPFLAGS)
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) $(CFLAGS)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isnt the old CFLAGS = $(CPPFLAGS) $(CWARNFLAGS) . . . included CPPFLAGS directly, and new CFLAGS := $(CWARNFLAGS) $(CDEBUGFLAGS) . . . $(CFLAGS) does not - CPPFLAGS now only reaches the compiler through $(COMPILE.c), which the pr only wires into the generic %.o: %.c pattern rule. But Makefile has some explicit rules like:

ccan-tal.o: $(CCANDIR)/ccan/tal/tal.c
    @$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<)

And these still call $(CC) $(CFLAGS) directly?, so they now lose everything that moved into CPPFLAGS, plus any macOS Homebrew -I paths. The worst case is ccan-tal.o, and ccan/tal/tal.c has:

static void *null_alloc_failed(void)
{
#ifdef CCAN_TAL_NEVER_RETURN_NULL
    abort();
#else
    return NULL;
#endif
}

Without -DCCAN_TAL_NEVER_RETURN_NULL=1, an out of memory tal_alloc now returns NULL instead of aborting? - while the rest of the codebase (compiled through the fixed pattern rule) is written on the assumption tal never returns NULL?

Maybe we need to keep CPPFLAGS folded into CFLAGS (drop the split), or update every explicit compile rule to use $(COMPILE.c) or at minimum $(CC) $(CPPFLAGS) $(CFLAGS) instead of $(CC) $(CFLAGS)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I missed that. I'm on vacation now, but I'll do a thorough review for other direct invocations of $(CC) after I return (in a few days). The correct usage is $(COMPILE.c) when $(CC) is being invoked to compile a C source file to produce an object file. There really isn't a common scenario in which $(CC) should be used in a Make recipe except perhaps when querying/testing for compiler features. When asking the compiler to do something, the more specific variables should be used.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I have now fixed all the explicit compile rules to use $(COMPILE.c) rather than $(CC). There are still some instances in the Makefiles in the ccan and jsmn submodules, but I think that those Makefiles are not actually used by the CLN build and so can be ignored.

Comment thread configure
echo "Warning: dsymutil not found. Install Xcode Command Line Tools for better debug support."
fi
else
CDEBUGFLAGS=${CDEBUGFLAGS--std=gnu11 -g -fstack-protector-strong}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add $CFLAGS to all of these invocations, or keep -std=gnu11 centralized in one flags variable that all of them already reference??

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some build systems put the -std= option directly in CC (and CXX if applicable). I don't really like that, as some code assumes that CC and friends contain simple path names with no arguments. However, there isn't a great place to specify the -std= option. It needs to be passed to the preprocessor, as feature test macros are affected by the C/C++ standard in use, but naïvely adding the -std= option to CPPFLAGS is suboptimal because C++ code will need a different standard than C code. Some build systems work around this by introducing a CXXCPPFLAGS variable that is specific to the C++ preprocessor, but that's very non-standard. I usually make the compromise of locally overriding the value of CPPFLAGS just for C++ source files. This won't be an issue for CLN for the time being since it currently has no C++ source files.

@madelinevibes madelinevibes added this to the v26.09 milestone Aug 7, 2026
It's not POSIX-compatible. Use printf instead.

Changelog-None
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
It doesn't logically belong in CDEBUGFLAGS.

Makefile now *prepends* its default CPPFLAGS and CFLAGS to the environment-
supplied flags. This allows the user to override individual flags by setting
these variables through configure, without disturbing all the rest of the
flags that Makefile wants by default.

Changelog-None
The code intends to pass "$DEFAULT_COPTFLAGS" and "$DEBUGBUILD" as arguments
$1 and $4 to default_cwarnflags(), but it had mistakenly doubled the double-
quotes, which would have caused the values of those variables to be subjected
to word splitting after substitution. Remove the extra double-quote marks.

Changelog-None
@whitslack
whitslack force-pushed the build-system-pedantry branch from 7238aa2 to b1aea32 Compare August 11, 2026 14:17
Passing -Wl,--gc-sections to the compiler driver does exactly nothing
unless the driver is instructed to invoke the linker. When it is not,
Clang helpfully raises a warning, which -Werror turns into an error:

    error: -Wl,--gc-sections: 'linker' input unused [-Werror,-Wunused-command-line-argument]

Remove the '-c' flag from the command line in have_function_sections()
so that the linker will actually be invoked and thus the linker's
support for --gc-sections will actually be tested.

Changelog-None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants