| # Copyright (c) 2022 Project CHIP 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("//build_overrides/build.gni") |
| import("//build_overrides/chip.gni") |
| import("//build_overrides/pigweed.gni") |
| |
| import("$dir_pw_build/python.gni") |
| import("${chip_root}/scripts/idl/files.gni") |
| |
| declare_args() { |
| # Location where code has been pre-generated |
| chip_code_pre_generated_directory = "" |
| } |
| |
| # Code generation that will happen at build time. |
| # |
| # |
| template("_chip_build_time_codegen") { |
| _name = target_name |
| _generator = invoker.generator |
| |
| config("${_name}_config") { |
| include_dirs = [ target_gen_dir ] |
| } |
| |
| pw_python_action("${_name}_codegen") { |
| script = "${chip_root}/scripts/codegen.py" |
| |
| # TODO: this seems to touch internals. Is this ok? speeds up builds! |
| _pw_internal_run_in_venv = false |
| |
| _idl_file = invoker.input |
| _expected_outputs = "${target_gen_dir}/${_name}.expected.outputs" |
| |
| write_file(_expected_outputs, invoker.outputs, "list lines") |
| |
| args = [ |
| "--generator", |
| _generator, |
| "--output-dir", |
| rebase_path(target_gen_dir, root_build_dir), |
| "--expected-outputs", |
| rebase_path(_expected_outputs, root_build_dir), |
| rebase_path(_idl_file, root_build_dir), |
| ] |
| |
| inputs = [ |
| _idl_file, |
| _expected_outputs, |
| ] |
| |
| # ensure any change in codegen files will result in a rebuild |
| inputs += matter_idl_generator_files |
| |
| sources = [ _idl_file ] |
| |
| outputs = [] |
| foreach(name, invoker.outputs) { |
| outputs += [ "${target_gen_dir}/${name}" ] |
| } |
| } |
| |
| source_set(_name) { |
| sources = [] |
| foreach(name, invoker.outputs) { |
| sources += [ "${target_gen_dir}/${name}" ] |
| } |
| |
| public_configs = [ ":${_name}_config" ] |
| |
| if (defined(invoker.public_configs)) { |
| public_configs += invoker.public_configs |
| } |
| |
| forward_variables_from(invoker, [ "deps" ]) |
| |
| if (!defined(deps)) { |
| deps = [] |
| } |
| deps += [ ":${_name}_codegen" ] |
| } |
| } |
| |
| # Defines a target that runs code generation based on |
| # scripts/codegen.py |
| # |
| # Arguments: |
| # input |
| # The ".matter" file to use to start the code generation |
| # |
| # generator |
| # Name of the generator to use (e.g. java, cpp-app) |
| # |
| # outputs |
| # Explicit names of the expected outputs. Enforced to validate that |
| # expected outputs are generated when processing input files. |
| # |
| # deps, public_configs |
| # Forwarded to the resulting source set |
| # |
| # Command line parameters: |
| # |
| # chip_code_pre_generated_directory: |
| # - If this is set, generation will NOT happen at compile time but rather |
| # the code generation is assumed to have already happened and reside in |
| # the given location. |
| # - The TOP LEVEL directory is assumed to be given. Actual location for |
| # individual generators is expected to be of the form |
| # <top_dir>/<matter_path>/<generator> |
| # |
| # NOTE: content of "outputs" is verified to match the output of codegen.py |
| # exactly. It is not inferred on purpose, to make build-rules explicit |
| # and verifiable (even though codegen.py can at runtime report its outputs) |
| # |
| # To find the list of generated files, you can run codegen.py with the |
| # "--name-only" argument |
| # |
| # NOTE: |
| # the result of the target_name WILL BE a `source_set`. Treat it as such. |
| # |
| # Example usage: |
| # |
| # chip_codegen("java-jni-generate") { |
| # input = "controller-clusters.matter" |
| # generator = "java" |
| # |
| # outputs = [ |
| # "jni/IdentifyClient-ReadImpl.cpp", |
| # "jni/IdentifyClient-InvokeSubscribeImpl.cpp", |
| # # ... more to follow |
| # ] |
| # } |
| # |
| template("chip_codegen") { |
| if (chip_code_pre_generated_directory == "") { |
| _chip_build_time_codegen(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "generator", |
| "input", |
| "outputs", |
| "public_configs", |
| ]) |
| } |
| } else { |
| _name = target_name |
| |
| # This contstructs a path like: |
| # FROM all-clusters-app.matter (inside examples/all-clusters-app/all-clusters-common/) |
| # USING "cpp-app" for generator: |
| # => ${pregen_dir}/examples/all-clusters-app/all-clusters-common/all-clusters-app/codegen/cpp-app |
| _generation_dir = |
| chip_code_pre_generated_directory + "/" + |
| string_replace(rebase_path(invoker.input, chip_root), ".matter", "") + |
| "/codegen/" + invoker.generator |
| |
| config("${_name}_config") { |
| include_dirs = [ "${_generation_dir}" ] |
| } |
| |
| source_set(_name) { |
| public_configs = [ ":${_name}_config" ] |
| |
| if (defined(invoker.public_configs)) { |
| public_configs += invoker.public_configs |
| } |
| |
| forward_variables_from(invoker, [ "deps" ]) |
| |
| sources = [] |
| foreach(name, invoker.outputs) { |
| sources += [ "${_generation_dir}/${name}" ] |
| } |
| } |
| } |
| } |