Subject: [PATCH v5] build: regenerate config-list.h when Documentation changes

From: "D. Ben Knoble" <[email-masked]>
Date: Wed, 18 Feb 2026 09:37:59 -0500

The Meson-based build doesn't know when to rebuild config-list.h, so the
header is sometimes stale.

For example, an old build directory might have config-list.h from before
4173df5187 (submodule: introduce extensions.submodulePathConfig,
2026-01-12), which added submodule.<name>.gitdir to the list. Without
it, t9902-completion.sh fails. Regenerating the config-list.h artifact
from sources fixes the artifact and the test.

Teach the meson build to depend on the Documentation files that
generate-configlist.sh reads by having it an additional output as a list
of dependency files, since Meson does not have (or want) builtin support
for globbing like Make. We assume that if a user adds a new file under
Documentation/config then they will also edit one of the existing files
to include that new file, and that will trigger a rebuild. Also mark the
generator script as a dependency.

While we're at it, teach the Makefile to use the same "the script knows
it's dependencies" logic.

For Meson, combining the following commands helps debug dependencies:

    ninja -C <builddir> -t deps config-list.h
    ninja -C <builddir> -t browse config-list.h

The former lists all the dependencies discovered from our output ".d"
file (the config documentation) and the latter shows the dependency on
the script itself, among other useful edges in the dependency graph.

Helped-by: Patrick Steinhardt <[email-masked]>
Helped-by: Phillip Wood <[email-masked]>
Signed-off-by: D. Ben Knoble <[email-masked]>
---

Notes (benknoble/commits):
    Changes from v4 (<9cdcc9de0[email-masked]>):
    
    • Include Patrick's suggested Makefile changes. Note there's no quiet
      equivalent for mdkir that isn't for the current target's containing
      directory…
    • Make depfile output efficient again, thanks to Phillip.
    
    I've kept printf instead of echo (from Patrick/Junio) because I think it
    is easier to reason about ("it works" vs. "did I use this in a way that
    might cause problems").
    
    Junio asked about other problematic bytes: the other one I could think
    of (since all the inputs should be paths, anyway) is newlines. I gave
    meson's depfile.py a glance [1], and it looks like they don't handle
    newlines in paths. Other whitespace doesn't appear to be an issue (see
    "elif c in {' ', '\n'}"); I think _most_ characters are just added to
    the filename.
    
    [1]: https://github.com/mesonbuild/meson/blob/master/mesonbuild/depfile.py

 Makefile               |  5 +++--
 generate-configlist.sh | 11 ++++++++++-
 meson.build            |  5 ++++-
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index 7f37ad8f58..6f926ffb1f 100644
--- a/Makefile
+++ b/Makefile
@@ -2688,9 +2688,10 @@ $(BUILT_INS): git$X
 	cp $< $@
 
 config-list.h: generate-configlist.sh
+	@mkdir -p .depend
+	$(QUIET_GEN)$(SHELL_PATH) ./generate-configlist.sh . $@ .depend/config-list.h.d
 
-config-list.h: Documentation/*config.adoc Documentation/config/*.adoc
-	$(QUIET_GEN)$(SHELL_PATH) ./generate-configlist.sh . $@
+-include .depend/config-list.h.d
 
 command-list.h: generate-cmdlist.sh command-list.txt
 
diff --git a/generate-configlist.sh b/generate-configlist.sh
index 75c39ade20..39ac8845ab 100755
--- a/generate-configlist.sh
+++ b/generate-configlist.sh
@@ -2,10 +2,11 @@
 
 SOURCE_DIR="$1"
 OUTPUT="$2"
+DEPFILE="$3"
 
 if test -z "$SOURCE_DIR" || ! test -d "$SOURCE_DIR" || test -z "$OUTPUT"
 then
-	echo >&2 "USAGE: $0 <SOURCE_DIR> <OUTPUT>"
+	echo >&2 "USAGE: $0 <SOURCE_DIR> <OUTPUT> [<DEPFILE>]"
 	exit 1
 fi
 
@@ -36,3 +37,11 @@ print_config_list () {
 	echo
 	print_config_list
 } >"$OUTPUT"
+
+if test -n "$DEPFILE"
+then
+	QUOTED_OUTPUT="$(printf '%s\n' "$OUTPUT" | sed 's,[&/\],\\&,g')"
+	printf '%s\n' "$SOURCE_DIR"/Documentation/*config.adoc \
+		"$SOURCE_DIR"/Documentation/config/*.adoc |
+		sed -e 's/[# ]/\\&/g' -e "s/^/$QUOTED_OUTPUT: /" >"$DEPFILE"
+fi
diff --git a/meson.build b/meson.build
index 762e2d0fc0..74b459b004 100644
--- a/meson.build
+++ b/meson.build
@@ -720,11 +720,14 @@ endif
 
 builtin_sources += custom_target(
   output: 'config-list.h',
+  depfile: 'config-list.h.d',
+  depend_files: [ 'generate-configlist.sh' ],
   command: [
     shell,
-    meson.current_source_dir() + '/generate-configlist.sh',
+    meson.current_source_dir() / 'generate-configlist.sh',
     meson.current_source_dir(),
     '@OUTPUT@',
+    '@DEPFILE@',
   ],
   env: script_environment,
 )

Diff-intervalle contre v4 :
1:  e2f4e1f9ba < -:  ---------- completion: add stash import, export
2:  9cdcc9de04 ! 1:  611a94cd98 meson: regenerate config-list.h when Documentation changes
    @@ Metadata
     Author: D. Ben Knoble <[email-masked]>
     
      ## Commit message ##
    -    meson: regenerate config-list.h when Documentation changes
    +    build: regenerate config-list.h when Documentation changes
     
         The Meson-based build doesn't know when to rebuild config-list.h, so the
         header is sometimes stale.
    @@ Commit message
         of dependency files, since Meson does not have (or want) builtin support
         for globbing like Make. We assume that if a user adds a new file under
         Documentation/config then they will also edit one of the existing files
    -    to include that new file, and that will trigger a rebuild.
    +    to include that new file, and that will trigger a rebuild. Also mark the
    +    generator script as a dependency.
     
    -    Also mark the generator script as a dependency.
    +    While we're at it, teach the Makefile to use the same "the script knows
    +    it's dependencies" logic.
     
    -    Combining the following commands helps debug dependencies:
    +    For Meson, combining the following commands helps debug dependencies:
     
             ninja -C <builddir> -t deps config-list.h
             ninja -C <builddir> -t browse config-list.h
    @@ Commit message

      ## Notes (benknoble/commits) ##
    -    Changes from v3 (<0a344f1f3[email-masked]>):
    +    Changes from v4 (<9cdcc9de0[email-masked]>):
     
    -    • Include the script itself as a dependency via depfile
    -    • Fix output path escaping (spaces, octothorpes; drop backslashes) for
    -      Ninja (I've used a loop because I couldn't find a portable construct
    -      that could escape only the remainder of the lines in the way I
    -      wanted).
    -    • Mention our assumptions about Documentation updates triggering
    -      rebuilds
    -    • Also include some debugging information in the commit message
    +    • Include Patrick's suggested Makefile changes. Note there's no quiet
    +      equivalent for mdkir that isn't for the current target's containing
    +      directory…
    +    • Make depfile output efficient again, thanks to Phillip.
    +
    +    I've kept printf instead of echo (from Patrick/Junio) because I think it
    +    is easier to reason about ("it works" vs. "did I use this in a way that
    +    might cause problems").
    +
    +    Junio asked about other problematic bytes: the other one I could think
    +    of (since all the inputs should be paths, anyway) is newlines. I gave
    +    meson's depfile.py a glance [1], and it looks like they don't handle
    +    newlines in paths. Other whitespace doesn't appear to be an issue (see
    +    "elif c in {' ', '\n'}"); I think _most_ characters are just added to
    +    the filename.
    +
    +    [1]: https://github.com/mesonbuild/meson/blob/master/mesonbuild/depfile.py
    +
    + ## Makefile ##
    +@@ Makefile: $(BUILT_INS): git$X
    + 	cp $< $@
    + 
    + config-list.h: generate-configlist.sh
    ++	@mkdir -p .depend
    ++	$(QUIET_GEN)$(SHELL_PATH) ./generate-configlist.sh . $@ .depend/config-list.h.d
    + 
    +-config-list.h: Documentation/*config.adoc Documentation/config/*.adoc
    +-	$(QUIET_GEN)$(SHELL_PATH) ./generate-configlist.sh . $@
    ++-include .depend/config-list.h.d
    + 
    + command-list.h: generate-cmdlist.sh command-list.txt
    + 
     
      ## generate-configlist.sh ##
     @@
    @@ generate-configlist.sh: print_config_list () {
     +
     +if test -n "$DEPFILE"
     +then
    -+	for doc in "$SOURCE_DIR"/Documentation/*config.adoc \
    -+		"$SOURCE_DIR"/Documentation/config/*.adoc
    -+	do
    -+		printf "$OUTPUT: %s\n" "$(printf '%s\n' "$doc" | sed 's/[# ]/\\&/g')"
    -+	done >"$DEPFILE"
    ++	QUOTED_OUTPUT="$(printf '%s\n' "$OUTPUT" | sed 's,[&/\],\\&,g')"
    ++	printf '%s\n' "$SOURCE_DIR"/Documentation/*config.adoc \
    ++		"$SOURCE_DIR"/Documentation/config/*.adoc |
    ++		sed -e 's/[# ]/\\&/g' -e "s/^/$QUOTED_OUTPUT: /" >"$DEPFILE"
     +fi
     
      ## meson.build ##

base-commit: f7e9f6c205466443107228e036b20acb7baa8c50
-- 
2.53.0