From 85219e9294387263fa57ff7285a34255de04e770 Mon Sep 17 00:00:00 2001 From: Piotr Dulikowski Date: Fri, 21 Jun 2024 20:44:44 +0200 Subject: [PATCH] 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 --- configure.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/configure.py b/configure.py index 4b98033798..fa09dcee75 100755 --- a/configure.py +++ b/configure.py @@ -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