From c0494762b70124dcf3b5d2ba3253918181e78e7b Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Thu, 2 Aug 2018 23:19:55 +0200 Subject: [PATCH] Speed up the code generator for exec_script. The code generator doesn't need to load the JSON file to compute the dependencies our outputs for a codegen target. To better integrate in noop builds, the lazy-write of generated file is removed because it led to the code generator running even in noop build (the timestamp of generated file not being updated). Also document what could be done to avoid exec_script calls for the Dawn code generator. --- BUILD.gn | 17 +++++++++++++---- generator/main.py | 21 +++++++++------------ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index db9bd4a0d6..5744826da3 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -57,7 +57,16 @@ template("dawn_generator") { target, ] - # TODO(cwallez@chromium.org): Use depfile instead of this exec_script + # Gather the inputs and outputs of the code generator. + # TODO(cwallez@chromium.org): These exec_script are cheap but are done on + # every GN invocation. However we can't use a depfile because the generator + # can have multiple outputs which ninja doesn't support in depfiles. + # We could avoid exec_script by making the code generator generate a single + # output such as a tarball: + # - The outputs would be the tarball + # - The inputs could be handled via a depfile + # Then another action would depend on the generator target and decompress the + # tarball. script_inputs = exec_script(generator, common_args + [ "--print-dependencies", @@ -65,8 +74,6 @@ template("dawn_generator") { ], "list lines", [ json ]) - - # Gather the outputs of the code generator for this target. script_outputs = exec_script(generator, common_args + [ "--print-outputs", @@ -93,7 +100,9 @@ template("dawn_generator") { # Make a target with a custom target_type that will contain the outputs of # the code generator in sources. target(invoker.target_type, target_name) { - deps = [ ":" + target_name + "_gen" ] + deps = [ + ":" + target_name + "_gen", + ] sources = script_outputs # Forward variables from the invoker. deps, configs and source are diff --git a/generator/main.py b/generator/main.py index b295bae002..6df2750c65 100644 --- a/generator/main.py +++ b/generator/main.py @@ -291,16 +291,8 @@ def do_renders(renders, template_dir, output_dir): if not os.path.exists(directory): os.makedirs(directory) - content = "" - try: - with open(output_file, 'r') as outfile: - content = outfile.read() - except: - pass - - if output != content: - with open(output_file, 'w') as outfile: - outfile.write(output) + with open(output_file, 'w') as outfile: + outfile.write(output) ############################################################# # MAIN SOMETHING WHATEVER @@ -408,7 +400,7 @@ def main(): parser.add_argument('-T', '--targets', default=None, type=str, help='Comma-separated subset of targets to output. Available targets: ' + ', '.join(targets)) parser.add_argument('--print-dependencies', action='store_true', help='Prints a space separated list of file dependencies, used for CMake integration') parser.add_argument('--print-outputs', action='store_true', help='Prints a space separated list of file outputs, used for CMake integration') - parser.add_argument('--gn', action='store_true', help='Make the printing of dependencies by GN friendly') + parser.add_argument('--gn', action='store_true', help='Make the printing of dependencies/outputs GN-friendly') args = parser.parse_args() @@ -418,7 +410,12 @@ def main(): with open(args.json[0]) as f: loaded_json = json.loads(f.read()) - api_params = parse_json(loaded_json) + # A fake api_params to avoid parsing the JSON when just querying dependencies and outputs + api_params = { + 'types': {} + } + if not args.print_outputs and not args.print_dependencies: + api_params = parse_json(loaded_json) base_params = { 'enumerate': enumerate,