| # 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" ]) |
| } |
| } |