From: Phillip Wood Date: Wed, 11 Feb 2026 10:57:10 GMT Subject: Re: [PATCH] meson: regenerate config-list.h when Documentation changes Message-ID: <81ff4cc8-676e-43fe-8193-609887b887d6@gmail.com> In-Reply-To: <4a566010-821b-4078-9563-9ca00ada55a0@gmail.com> On 11/02/2026 09:44, Phillip Wood wrote: > On 11/02/2026 07:42, Patrick Steinhardt wrote: >> On Mon, Feb 09, 2026 at 04:50:06PM -0500, D. Ben Knoble wrote: >>>> On Sat, Feb 07, 2026 at 04:59:17PM -0500, D. Ben Knoble wrote: >> [snip] >>> Only, things are behaving oddly. For example: >>> >>>      λ meson setup build2 >>>      λ ninja -C build2 >>> >>> works fine, but >>> >>>      λ ls -l build2/config* >>>      -rw-r--r-- 1 benknoble benknoble 17169  9 févr. 16:39 build2/ >>> config-list.h >>> >>> I don't see the dependency file. I've just had a play with this and I don't see the dependency file either - I wonder if ninja deletes it after it has read it. If I delete Documentation/config/add.adoc then config-list.h is rebuilt. However if I edit generate-configlist.sh it is not rebuilt - I guess we need to add the script to the dependency file. Thanks Phillip >>> Further, re-building seems to get stuck (I get >>> similar symptoms if I add or remove a relevant config.adoc file, but >>> let's keep >>> it simple for now): >>> >>>      λ ninja -C build2 >>>      ninja: Entering directory `build2' >>>      [1/28] Generating GIT-VERSION-FILE with a custom command >>> (wrapped by meson to set env) >> >> With "stuck" you mean that it doesn't do anything, or that it doesn't >> actually rebuild? >> >> I guess it kind of makes sense that a new file wouldn't trigger a >> rebuild, even though I would have expected a removed one to trigger one. >> After all, the dependency file only tracks the set of _existing_ files >> so that we know when to rebuild, and of course the dependency file only >> gets regenerated in case any of those files changes. > > If anyone adds a new file under Documentation/config/ they will need to > update Documentation/config.adoc which should then trigger the rebuild. > That rebuld will then add the new file to the list of dependencies. If > they remove a file we should pick that up with the dependencies that are > already listed. > > Do we need to create the depfile when meson is setup? What does meson do > when the depfile is missing? > >> The thing is that build systems like Meson really want to know the list >> of files ahead of time so that they can have an optimal build graph. So >> we could of course list all the files that we actually depend on. But I >> guess that's something we want to avoid? >> >> There's another, alternative approach: you can have a separate build >> step that's marked as `build_always_stale: true` that lists all the >> config files. This step would then always run, and it would only update >> its target file in case any of the files has changed. > > It would be really nice if we can avoid regenerating the depfile with > every build. > > Thanks > > Phillip > >> Combined with the depfile we'd then rebuild in all cases: >> >>    - When a file gets added or removed, as that would cause the >>      `build_always_stale` target to be rewritten. >> >>    - When any of the files changes, because that would cause the >>      dependencies in the depfile to change. >> >> Something like the attached patch (note that I don't perform the >> necessary changes for the Makefile). I confirmed that it works for all >> of the above cases. >> >> Thanks! >> >> Patrick >> >> --- >8 --- >> >> diff --git a/generate-configlist.sh b/generate-configlist.sh >> index 75c39ade20..17605e6f77 100755 >> --- a/generate-configlist.sh >> +++ b/generate-configlist.sh >> @@ -1,13 +1,6 @@ >>   #!/bin/sh >> -SOURCE_DIR="$1" >> -OUTPUT="$2" >> - >> -if test -z "$SOURCE_DIR" || ! test -d "$SOURCE_DIR" || test -z "$OUTPUT" >> -then >> -    echo >&2 "USAGE: $0 " >> -    exit 1 >> -fi >> +set -e >>   print_config_list () { >>       cat <> @@ -30,9 +23,50 @@ EOF >>   EOF >>   } >> -{ >> -    echo "/* Automatically generated by generate-configlist.sh */" >> -    echo >> -    echo >> -    print_config_list >> -} >"$OUTPUT" >> +case "$1" in >> +generate) >> +    SOURCE_DIR="$2" >> +    OUTPUT="$3" >> +    DEPFILE="$4" >> + >> +    if test -z "$SOURCE_DIR" || ! test -d "$SOURCE_DIR" || test -z >> "$OUTPUT" >> +    then >> +        echo >&2 "USAGE: $0 generate " >> +        exit 1 >> +    fi >> + >> +    if test -n "$DEPFILE" >> +    then >> +        printf "$OUTPUT: %s\n" "$SOURCE_DIR"/Documentation/ >> *config.adoc \ >> +            "$SOURCE_DIR"/Documentation/config/*.adoc >"$DEPFILE" >> +    fi >> + >> +    { >> +        echo "/* Automatically generated by generate-configlist.sh */" >> +        echo >> +        echo >> +        print_config_list >> +    } >"$OUTPUT" >> +    ;; >> +deps) >> +    SOURCE_DIR="$2" >> +    OUTPUT="$3" >> + >> +    if test -z "$SOURCE_DIR" || ! test -d "$SOURCE_DIR" || test -z >> "$OUTPUT" >> +    then >> +        echo >&2 "USAGE: $0 deps " >> +        exit 1 >> +    fi >> + >> +    TMPFILE=$(mktemp "$OUTPUT".XXXXXX) >> +    printf "%s\n" "$SOURCE_DIR"/Documentation/*config.adoc \ >> +        "$SOURCE_DIR"/Documentation/config/*.adoc | sort >"$TMPFILE" >> + >> +    if ! test -f "$OUTPUT" || ! cmp "$TMPFILE" "$OUTPUT" >/dev/null >> +    then >> +        mv "$TMPFILE" "$OUTPUT" >> +    else >> +        rm "$TMPFILE" >> +    fi >> +    ;; >> +esac >> diff --git a/meson.build b/meson.build >> index dd52efd1c8..6b9147a39a 100644 >> --- a/meson.build >> +++ b/meson.build >> @@ -716,14 +716,29 @@ if not get_option('breaking_changes') >>     builtin_sources += 'builtin/pack-redundant.c' >>   endif >> +configlist_deps = custom_target( >> +  output: 'config-list.h.deps', >> +  command: [ >> +    meson.current_source_dir() + '/generate-configlist.sh', >> +    'deps', >> +    meson.current_source_dir(), >> +    '@OUTPUT@', >> +  ], >> +  build_always_stale: true, >> +) >> + >>   builtin_sources += custom_target( >>     output: 'config-list.h', >>     command: [ >>       shell, >>       meson.current_source_dir() + '/generate-configlist.sh', >> +    'generate', >>       meson.current_source_dir(), >>       '@OUTPUT@', >> +    '@OUTPUT@.d', >>     ], >> +  depends: [ configlist_deps, ], >> +  depfile: 'config-list.h.d', >>     env: script_environment, >>   ) >> >