# Copyright 2019 The Dawn Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import("../scripts/dawn_overrides_with_defaults.gni") # Template to help invoking Dawn code generators based on generator_lib # # dawn_generator("my_target_gen") { # # The script and generator specific arguments # script = [ "my_awesome_generator.py" ] # args = [ # "--be-awesome", # "yes" # ] # # # The list of expected outputs, generation fails if there's a mismatch # outputs = [ # "MyAwesomeTarget.cpp", # "MyAwesomeTarget.h", # ] # # # Optional, use a custom generated file directory. # custom_gen_dir = "${target_gen_dir}/.." # } # # Using the generated files is done like so: # # shared_library("my_target") { # deps = [ ":my_target_gen "] # sources = get_target_outputs(":my_target_gen") # } # template("dawn_generator") { generator_args = [] if (defined(invoker.args)) { generator_args += invoker.args } generator_args += [ "--template-dir", rebase_path("${dawn_root}/generator/templates", root_build_dir), ] # Use the Jinja2 version pulled from the DEPS file. We do it so we don't # have version problems, and users don't have to install Jinja2. jinja2_python_path = rebase_path("${dawn_jinja2_dir}/..") generator_args += [ "--extra-python-path", jinja2_python_path, ] # Chooses either the default gen_dir or the custom one required by the # invoker. This allows moving the definition of code generators in different # BUILD.gn files without changing the location of generated file. Without # this generated headers could cause issues when old headers aren't removed. gen_dir = target_gen_dir if (defined(invoker.custom_gen_dir)) { gen_dir = invoker.custom_gen_dir } # For build parallelism GN wants to know the exact inputs and outputs of # action targets like we use for our code generator. We avoid asking the # generator about its inputs by using the "depfile" feature of GN/Ninja. # # A ninja limitation is that the depfile is a subset of Makefile that can # contain a single target, so we output a single "JSON-tarball" instead. json_tarball = "${gen_dir}/${target_name}.json_tarball" json_tarball_depfile = "${json_tarball}.d" generator_args += [ "--output-json-tarball", rebase_path(json_tarball, root_build_dir), "--depfile", rebase_path(json_tarball_depfile, root_build_dir), ] # After the JSON tarball is created we need an action target to extract it # with a list of its outputs. The invoker provided a list of expected # outputs. To make sure the list is in sync between the generator and the # build files, we write it to a file and ask the generator to assert it is # correct. expected_outputs_file = "${gen_dir}/${target_name}.expected_outputs" write_file(expected_outputs_file, invoker.outputs) generator_args += [ "--expected-outputs-file", rebase_path(expected_outputs_file, root_build_dir), ] # The code generator invocation that will write the JSON tarball, check the # outputs are what's expected and write a depfile for Ninja. action("${target_name}_json_tarball") { script = invoker.script outputs = [ json_tarball, ] depfile = json_tarball_depfile args = generator_args } # Extract the JSON tarball into the gen_dir action(target_name) { script = "${dawn_root}/generator/extract_json.py" args = [ rebase_path(json_tarball, root_build_dir), rebase_path(gen_dir, root_build_dir), ] deps = [ ":${target_name}_json_tarball", ] inputs = [ json_tarball, ] # The expected output list is relative to the gen_dir but action # target outputs are from the root dir so we need to rebase them. outputs = [] foreach(source, invoker.outputs) { outputs += [ "${gen_dir}/${source}" ] } } } # Helper generator for calling the generator from dawn.json # # dawn_json_generator("my_target_gen") { # # Which generator target to output # target = "my_target" # # # Also supports `outputs` and `custom_gen_dir` like dawn_generator. # } template("dawn_json_generator") { dawn_generator(target_name) { script = "${dawn_root}/generator/dawn_json_generator.py" # The base arguments for the generator: from this dawn.json, generate this # target using templates in this directory. args = [ "--dawn-json", rebase_path("${dawn_root}/dawn.json", root_build_dir), "--wire-json", rebase_path("${dawn_root}/dawn_wire.json", root_build_dir), "--targets", invoker.target, ] forward_variables_from(invoker, "*", [ "target" ]) } }