Fix frequent rebuild of options target (#7450)
authorGereon Kremer <nafur42@gmail.com>
Tue, 26 Oct 2021 12:10:10 +0000 (05:10 -0700)
committerGitHub <noreply@github.com>
Tue, 26 Oct 2021 12:10:10 +0000 (12:10 +0000)
The mkoptions.py script only updates its output files if their content would actually change. This avoid a full rebuild on every run, and makes sure that only parts that actually change are rebuild.
Unfortunately this interacts badly with how cmake/make/... do inter-target dependency tracking.
This PR adds a stamp file options.stamp that is always updated by mkoptions.py and used by cmake as main output.

src/CMakeLists.txt
src/options/mkoptions.py

index a2ffc1f34a3e4fd3b7ac8961240b33786acfa5da..2cb3457e18248aa9c9c47ef72b96c8b0bf67eef1 100644 (file)
@@ -1244,36 +1244,43 @@ if (BUILD_DOCS)
   )
 endif()
 
+# The mkoptions.py script only updates its output files if their content would
+# actually change. This mechanism makes sure that running the script does not
+# automatically trigger a full rebuild, but only a rebuild of those parts that
+# include files that did actually change.
+# This approach also means that the output files (which gen-options used to
+# depend on) may not actually be updated and thus cmake would keep re-running
+# mkoptions.py over and over again.
+# We thus have an artificial options.stamp file that mkoptions.py always writes
+# to, and can thus be used to communicate that all options files have been
+# properly updated.
 add_custom_command(
-    OUTPUT
-      ${options_gen_cpp_files} ${options_gen_h_files}
-      ${options_gen_doc_files}
-    COMMAND
-      ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/options
-    COMMAND
-      ${PYTHON_EXECUTABLE}
-      ${CMAKE_CURRENT_LIST_DIR}/options/mkoptions.py
-      ${CMAKE_CURRENT_LIST_DIR}
-      ${CMAKE_BINARY_DIR}
-      ${CMAKE_CURRENT_BINARY_DIR}
-      ${abs_toml_files}
-    DEPENDS
-      options/mkoptions.py
-      ${options_toml_files}
-      main/options_template.cpp
-      options/module_template.h
-      options/module_template.cpp
-      options/options_public_template.cpp
-      options/options_template.h
-      options/options_template.cpp
-)
-
-add_custom_target(gen-options
+  OUTPUT
+    options/options.stamp
+  COMMAND
+    ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/options
+  COMMAND
+    ${PYTHON_EXECUTABLE}
+    ${CMAKE_CURRENT_LIST_DIR}/options/mkoptions.py
+    ${CMAKE_CURRENT_LIST_DIR}
+    ${CMAKE_BINARY_DIR}
+    ${CMAKE_CURRENT_BINARY_DIR}
+    ${abs_toml_files}
+  BYPRODUCTS
+    ${options_gen_cpp_files} ${options_gen_h_files} ${options_gen_doc_files}
   DEPENDS
-    ${options_gen_cpp_files}
-    ${options_gen_h_files}
+    options/mkoptions.py
+    ${options_toml_files}
+    main/options_template.cpp
+    options/module_template.h
+    options/module_template.cpp
+    options/options_public_template.cpp
+    options/options_template.h
+    options/options_template.cpp
 )
 
+add_custom_target(gen-options DEPENDS options/options.stamp)
+
 
 #-----------------------------------------------------------------------------#
 
index badfd59f01be6f9de907984731eb44d6c3ede32b..7288ede51b790a24ceb74f81cc5f69e8366a1248 100644 (file)
@@ -1047,6 +1047,9 @@ def mkoptions_main():
         codegen_module(module, dst_dir, module_tpls)
     codegen_all_modules(modules, build_dir, dst_dir, global_tpls)
 
+    # Generate output file to signal cmake when this script was run last
+    open(os.path.join(dst_dir, 'options/options.stamp'), 'w').write('')
+
 
 if __name__ == "__main__":
     mkoptions_main()