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.
This commit is contained in:
Corentin Wallez 2018-08-02 23:19:55 +02:00 committed by Corentin Wallez
parent 21a23857dc
commit c0494762b7
2 changed files with 22 additions and 16 deletions

View File

@ -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

View File

@ -291,14 +291,6 @@ 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)
@ -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,6 +410,11 @@ def main():
with open(args.json[0]) as f:
loaded_json = json.loads(f.read())
# 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 = {