| # Copyright 2026 The Pigweed 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 | |
| # | |
| # https://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/pigweed.gni") | |
| import("$dir_pw_build/python_action.gni") | |
| import("$dir_pw_build/target_types.gni") | |
| import("$dir_pw_toolchain/generate_toolchain.gni") | |
| # Defines a C++ source set that automatically enables versioned enum | |
| # tokenization. | |
| # | |
| # Args: | |
| # enum_headers: List of standard .h files containing enum definitions to tokenize (required). | |
| # include_dirs: List containing exactly one path to include for generated headers (required). | |
| # public: Optional list of general public C++ headers. | |
| # sources: Optional list of C++ implementation source files. | |
| # deps: Dependencies. | |
| # public_deps: Public dependencies. | |
| template("pw_cc_enum_source_set") { | |
| assert(defined(invoker.enum_headers), | |
| "pw_cc_enum_source_set requires enum_headers") | |
| assert(defined(invoker.include_dirs), | |
| "pw_cc_enum_source_set requires include_dirs") | |
| _include_dirs = invoker.include_dirs | |
| assert(_include_dirs == [ _include_dirs[0] ], | |
| "include_dirs must have exactly one path") | |
| assert( | |
| _include_dirs[0] != ".", | |
| "pw_cc_enum_source_set does not allow '.' as include_dirs. " + | |
| "Since GN doesn't isolate headers, it is too easy for sources to " + | |
| "accidentally include original headers instead of generated ones.") | |
| _out_dir = "${target_gen_dir}/${target_name}" | |
| _out_files = [] | |
| foreach(_hdr, invoker.enum_headers) { | |
| _out_files += [ "$_out_dir/include/" + rebase_path(_hdr, _include_dirs[0]) ] | |
| } | |
| _base_cc_file = "$_out_dir/${target_name}.base.cc" | |
| write_file(_base_cc_file, [ "// placeholder" ]) | |
| _base_target = "${target_name}._base" | |
| pw_source_set(_base_target) { | |
| forward_variables_from(invoker, [ "testonly" ]) | |
| sources = [ _base_cc_file ] | |
| _deps = [] | |
| if (defined(invoker.deps)) { | |
| _deps += invoker.deps | |
| } | |
| if (defined(invoker.public_deps)) { | |
| _deps += invoker.public_deps | |
| } | |
| deps = _deps | |
| include_dirs = _include_dirs | |
| public_deps = [ | |
| "$dir_pw_enum:_generate_internal_do_not_use", | |
| "$dir_pw_tokenizer", | |
| ] | |
| visibility = [ ":*" ] | |
| } | |
| _generate_target = "${target_name}.generate" | |
| pw_python_action(_generate_target) { | |
| forward_variables_from(invoker, [ "testonly" ]) | |
| module = "pw_enum.generate_gn" | |
| python_deps = [ "$dir_pw_enum/py" ] | |
| inputs = invoker.enum_headers | |
| outputs = _out_files | |
| args = rebase_path(invoker.enum_headers, root_build_dir) + [ "--outputs" ] + | |
| rebase_path(_out_files, root_build_dir) + | |
| [ | |
| "--base-cc", | |
| rebase_path(_base_cc_file, root_build_dir), | |
| "--toolchain-ninja", | |
| rebase_path("$root_out_dir/toolchain.ninja", root_build_dir), | |
| "--target-ninja", | |
| rebase_path(get_label_info(":$_base_target", "target_out_dir") + | |
| "/$_base_target.ninja", | |
| root_build_dir), | |
| ] | |
| deps = [ ":$_base_target" ] | |
| visibility = [ ":*" ] | |
| } | |
| config("${target_name}.public_includes") { | |
| # Use -iquote so generated headers take priority over source directories. | |
| cflags_cc = [ "-iquote" + rebase_path("$_out_dir/include", root_build_dir) ] | |
| include_dirs = [ "$_out_dir/include" ] | |
| visibility = [ ":*" ] | |
| } | |
| config("${target_name}.original_includes") { | |
| include_dirs = _include_dirs | |
| visibility = [ ":*" ] | |
| } | |
| pw_source_set(target_name) { | |
| forward_variables_from(invoker, | |
| "*", | |
| [ | |
| "public", | |
| "include_dirs", | |
| "deps", | |
| "public_deps", | |
| "enum_headers", | |
| "public_configs", | |
| ]) | |
| public = _out_files | |
| if (defined(invoker.public)) { | |
| public += invoker.public | |
| } | |
| public_deps = [ | |
| "$dir_pw_enum:_generate_internal_do_not_use", | |
| "$dir_pw_tokenizer", | |
| ] | |
| if (defined(invoker.public_deps)) { | |
| public_deps += invoker.public_deps | |
| } | |
| deps = [ ":$_generate_target" ] | |
| if (defined(invoker.deps)) { | |
| deps += invoker.deps | |
| } | |
| public_configs = [ | |
| ":${target_name}.public_includes", | |
| ":${target_name}.original_includes", | |
| ] | |
| if (defined(invoker.public_configs)) { | |
| public_configs += invoker.public_configs | |
| } | |
| } | |
| } |