| # 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 |
| } |
| } |
| } |