1# Copyright 2022 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14 15import("//build_overrides/pigweed.gni") 16 17import("$dir_pw_build/defaults.gni") 18 19declare_args() { 20 # Additional build targets to add as dependencies for pw_executable, 21 # pw_static_library, and pw_shared_library targets. The 22 # $dir_pw_build:link_deps target pulls in these libraries. 23 # 24 # pw_build_LINK_DEPS can be used to break circular dependencies for low-level 25 # libraries such as pw_assert. 26 pw_build_LINK_DEPS = [] 27 28 # pw_build_TOOLCHAIN_LINK_DEPS is used by pw_toolchain module to set default 29 # libary dependencies. Generally, this is not intended to be user-facing, but 30 # if something is introduced here that you need to remove, you can do so by 31 # overriding this variable in your own toolchain. 32 pw_build_TOOLCHAIN_LINK_DEPS = [] 33 34 # The name of the GN target type used to build Pigweed executables. 35 # 36 # If this is a custom template, the .gni file containing the template must 37 # be imported at the top of the target configuration file to make it globally 38 # available. 39 pw_build_EXECUTABLE_TARGET_TYPE = "executable" 40 41 # The path to the .gni file that defines pw_build_EXECUTABLE_TARGET_TYPE. 42 # 43 # If pw_build_EXECUTABLE_TARGET_TYPE is not the default of `executable`, this 44 # .gni file is imported to provide the template definition. 45 pw_build_EXECUTABLE_TARGET_TYPE_FILE = "" 46} 47 48# This template is the underlying implementation that defines what makes 49# pw_source_set, pw_executable, pw_shared_library, and pw_static_library unique. 50# For more information, see the documentation at 51# https://pigweed.dev/pw_build/?highlight=pw_executable#target-types 52# 53# In addition to the arguments supported by the underlying native target types, 54# this template introduces the following arguments: 55# 56# add_global_link_deps: (required) If true, adds global link dependencies as 57# specified by the current toolchain via pw_build_LINK_DEPS as dependencies 58# to all instantiations of the current target type. 59# underlying_target_type: (required) The underlying target type to use for this 60# template. This is done so different C/C++ build target types can share the 61# same underlying wrapper implementation. 62# target_type_file: (optional) If the underlying target type is not one of GN's 63# builtin types, the path to the .gni file that defines the template 64# referenced by underlying_target_type. This is exclusively to support 65# pw_exeuctable's behavior that allows a pw_executable to be essentially 66# aliased to a custom target type. 67# remove_configs: (optional) A list of configs to remove from the set of 68# default configs specified by the current toolchain configuration. 69# remove_public_deps: (optional) A list of targets to remove from the set of 70# default public_deps specified by the current toolchain configuration. 71template("pw_internal_build_target") { 72 assert(defined(invoker.underlying_target_type), 73 "Build targets using this template must specify a target type") 74 _pw_source_files = [] 75 _supported_toolchain_defaults = [ 76 "configs", 77 "public_deps", 78 ] 79 80 # Boilerplate for tracking target sources. For more information see 81 # https://pigweed.dev/pw_build/#target-types 82 if (defined(invoker.sources)) { 83 foreach(path, invoker.sources) { 84 _pw_source_files += [ path ] 85 } 86 } 87 if (defined(invoker.public)) { 88 foreach(path, invoker.public) { 89 _pw_source_files += [ path ] 90 } 91 } 92 93 _builtin_target_types = [ 94 "executable", 95 "rust_library", 96 "rust_proc_macro", 97 "shared_library", 98 "source_set", 99 "static_library", 100 ] 101 if (filter_include(_builtin_target_types, 102 [ invoker.underlying_target_type ]) == []) { 103 assert( 104 defined(invoker.target_type_file) && invoker.target_type_file != "", 105 string_join( 106 ", ", 107 [ 108 "Unknown target type ${invoker.underlying_target_type}", 109 "set target_type_file to the .gni file that defines this type.", 110 ])) 111 import(invoker.target_type_file) 112 } 113 114 target(invoker.underlying_target_type, target_name) { 115 forward_variables_from( 116 invoker, 117 "*", 118 _supported_toolchain_defaults + [ "target_type_file" ]) 119 120 # Ensure that we don't overwrite metadata forwarded from the invoker above. 121 if (defined(metadata)) { 122 metadata.pw_source_files = _pw_source_files 123 } else { 124 metadata = { 125 pw_source_files = _pw_source_files 126 } 127 } 128 129 _default_configs = 130 filter_exclude(pw_build_INTERNAL_DEFAULTS.default_configs, 131 pw_build_INTERNAL_DEFAULTS.remove_default_configs) 132 if (!defined(remove_configs)) { 133 remove_configs = [] 134 } 135 136 # Check if configs is already defined. 137 # configs will already exist if set_defaults() is used. 138 if (!defined(configs)) { 139 configs = [] 140 } 141 142 # `configs` was not forwarded initially to support flag ordering. 143 configs += filter_exclude(_default_configs, remove_configs) 144 145 # Add the public_deps from the actual target last so they are prioritized. 146 # This set of public_deps MUST be added last because it affects flag 147 # ordering. If this list is added later, flags from the default list will 148 # take precedence. 149 if (defined(invoker.configs)) { 150 configs += invoker.configs 151 } 152 153 _default_public_deps = 154 filter_exclude(pw_build_INTERNAL_DEFAULTS.default_public_deps, 155 pw_build_INTERNAL_DEFAULTS.remove_default_public_deps) 156 if (!defined(remove_public_deps)) { 157 remove_public_deps = [] 158 } 159 160 # `public_deps` was not forwarded initially to support flag ordering. 161 public_deps = filter_exclude(_default_public_deps, remove_public_deps) 162 163 # Add the public_deps from the actual target last so they are prioritized. 164 # This set of public_deps MUST be added last because it affects flag 165 # ordering. If this list is added later, flags from the default list will 166 # take precedence. 167 if (defined(invoker.public_deps)) { 168 public_deps += invoker.public_deps 169 } 170 171 assert(defined(add_global_link_deps), 172 "All targets MUST specify whether or not to include link deps") 173 if (!defined(deps)) { 174 deps = [] 175 } 176 if (add_global_link_deps) { 177 deps += [ "$dir_pw_build:link_deps" ] 178 } 179 180 if (!defined(visibility)) { 181 visibility = pw_build_DEFAULT_VISIBILITY 182 } 183 } 184} 185