Fix Unix Makefiles running discover_nodes.py every build

Touch the output file when any of the files it depends on are newer
to stop Unix Makefiles from running the generator for every build.

Also remove use of pathlib, gives 10-15% slowdown as it adds indirect
imports such as urllib without much benefit (joining a path).
This commit is contained in:
Campbell Barton
2023-08-11 17:12:16 +10:00
parent fd920ba39f
commit 00ffa63b8f
2 changed files with 41 additions and 10 deletions

View File

@@ -13,6 +13,13 @@ function(add_node_discovery
output_function
)
set(extra_args "")
# See `add_definitions(-DUSE_MAKEFILE_WORKAROUND)` comment for `makesrna`.
if(CMAKE_GENERATOR MATCHES ".*Unix Makefiles")
set(extra_args "--use-makefile-workaround")
endif()
add_custom_command(
OUTPUT
${output_file}
@@ -23,11 +30,12 @@ function(add_node_discovery
${output_file}
${output_function}
${sources}
${extra_args}
DEPENDS
${SRC}
${DISCOVER_NODES_PATH}
)
set_source_files_properties(${output_file} PROPERTIES GENERATED TRUE)
add_library(${lib_name} ${output_file})
endfunction()

View File

@@ -17,14 +17,38 @@ invoking `NOD_REGISTER_NODE(register_function_name)`.
This scripts finds all those macro invocations generates code that calls the functions.
'''
import os
import re
import sys
from pathlib import Path
source_root = Path(sys.argv[1])
output_cc_file = Path(sys.argv[2])
def filepath_is_older(filepath_test, filepath_compare):
import stat
mtime = os.stat(filepath_test)[stat.ST_MTIME]
for filepath_other in filepath_compare:
if mtime < os.stat(filepath_other)[stat.ST_MTIME]:
return True
return False
# The build system requires the geneated file to be touched if any files used to generate it are newer.
try:
sys.argv.remove("--use-makefile-workaround")
use_makefile_workaround = True
except ValueError:
use_makefile_workaround = False
# NOTE: avoid `pathlib`, pulls in many modules indirectly, path handling is simple enough.
source_root = sys.argv[1]
output_cc_file = sys.argv[2]
function_to_generate = sys.argv[3]
relative_source_files = sys.argv[4:]
source_cc_files = [
os.path.join(source_root, path)
for path in
sys.argv[4:]
if path.endswith(".cc")
]
macro_name = "NOD_REGISTER_NODE"
discover_suffix = "_discover"
@@ -45,11 +69,7 @@ re_namespace_end = r"^\} // namespace ([\w:]+)"
re_macro = r"MACRO\((\w+)\)".replace("MACRO", macro_name)
re_all = f"({re_namespace_begin})|({re_namespace_end})|({re_macro})"
for relative_source_file in relative_source_files:
if not relative_source_file.endswith(".cc"):
continue
path = source_root / relative_source_file
for path in source_cc_files:
# Read the source code.
with open(path, "r", encoding="utf-8") as f:
code = f.read()
@@ -96,3 +116,6 @@ new_generated_code = "\n".join(include_lines + decl_lines + [""] + func_lines)
if old_generated_code != new_generated_code:
with open(output_cc_file, "w", encoding="utf-8") as f:
f.write(new_generated_code)
elif use_makefile_workaround and filepath_is_older(output_cc_file, (__file__, *source_cc_files)):
# If the generated file is older than this command, this file would be generated every time.
os.utime(output_cc_file)