configure.py: fix the 'configure' rule generated during regeneration

The Ninja makefile (build.ninja) generated by the ./configure.py script
is smart enough to notice when the configure.py script is modified and
re-runs the script in order to regenerate itself. However, this
operation is currently not idempotent and quickly breaks because
information about the Ninja makefile's name is not passed properly.

This is the rule used for makefile's regeneration:

```
rule configure
  command = {python} configure.py --out={buildfile}.new $configure_args && mv {buildfile}.new {buildfile}
  generator = 1
  description = CONFIGURE $configure_args
```

The `buildfile` variable holds the value of the `--out` option which is
set to `build.ninja` if not provided explicitly.

Note that regenerating the makefile passes a name with the `.new` suffix
added to the end; we want to first write the file in full and then
overwrite the old file via a rename. However, notice that the script was
called with `--out=build.ninja.new`; the `configure` rule in the
regenerated file will have `configure.py --out=build.ninja.new.new` and
then `mv build.ninja.new.new build.ninja.new`. So, second regeneration
will just leave a build.ninja.new file which is not useful.

Fix this by introducing an additional parameter `--out-final-name`.
This parameter is only supposed to be used in the regeneration rule and
its purpose is to preserve information about the original file name.
After this change I no longer see `build.ninja.new` being created after
a sequence of `touch configure.py && ninja` calls.

Closes scylladb/scylladb#19428
This commit is contained in:
Piotr Dulikowski
2024-06-21 20:44:44 +02:00
committed by Nadav Har'El
parent a4c6ae688a
commit 85219e9294

View File

@@ -688,6 +688,11 @@ all_artifacts = apps | tests | other | wasms
arg_parser = argparse.ArgumentParser('Configure scylla')
arg_parser.add_argument('--out', dest='buildfile', action='store', default='build.ninja',
help='Output build-file name (by default build.ninja)')
arg_parser.add_argument('--out-final-name', dest="buildfile_final_name", action='store',
help='If set, rules will be generated as if this were the actual name of the file instead of the name passed by the --out option. \
This option is rather not useful for developers, it is intended to be used by Ninja when it decides to regenerate the makefile \
(a makefile with the same name but with a ".new" suffix is generated, then it is renamed to overwrite the old file; \
the new file\'s regeneration rule itself needs to refer to the correct filename).')
arg_parser.add_argument('--mode', action='append', choices=list(modes.keys()), dest='selected_modes',
help="Build modes to generate ninja files for. The available build modes are:\n{}".format("; ".join(["{} - {}".format(m, cfg['description']) for m, cfg in modes.items()])))
arg_parser.add_argument('--with', dest='artifacts', action='append', default=[],
@@ -1571,6 +1576,8 @@ selected_modes = args.selected_modes or modes.keys()
default_modes = args.selected_modes or [mode for mode, mode_cfg in modes.items() if mode_cfg["default"]]
build_modes = {m: modes[m] for m in selected_modes}
buildfile_final_name = args.buildfile_final_name or args.buildfile
if args.artifacts:
build_artifacts = set()
for artifact in args.artifacts:
@@ -2391,10 +2398,10 @@ def write_build_file(f,
f.write(textwrap.dedent('''\
rule configure
command = {python} configure.py --out={buildfile}.new $configure_args && mv {buildfile}.new {buildfile}
command = {python} configure.py --out={buildfile_final_name}.new --out-final-name={buildfile_final_name} $configure_args && mv {buildfile_final_name}.new {buildfile_final_name}
generator = 1
description = CONFIGURE $configure_args
build {buildfile} {build_ninja_list}: configure | configure.py SCYLLA-VERSION-GEN $builddir/SCYLLA-PRODUCT-FILE $builddir/SCYLLA-VERSION-FILE $builddir/SCYLLA-RELEASE-FILE {args.seastar_path}/CMakeLists.txt
build {buildfile_final_name} {build_ninja_list}: configure | configure.py SCYLLA-VERSION-GEN $builddir/SCYLLA-PRODUCT-FILE $builddir/SCYLLA-VERSION-FILE $builddir/SCYLLA-RELEASE-FILE {args.seastar_path}/CMakeLists.txt
rule cscope
command = find -name '*.[chS]' -o -name "*.cc" -o -name "*.hh" | cscope -bq -i-
description = CSCOPE