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 17declare_args() { 18 # Additional build targets to add as dependencies for pw_executable, 19 # pw_static_library, and pw_shared_library targets. The 20 # $dir_pw_build:link_deps target pulls in these libraries. 21 # 22 # pw_build_LINK_DEPS can be used to break circular dependencies for low-level 23 # libraries such as pw_assert. 24 pw_build_LINK_DEPS = [] 25 26 # The name of the GN target type used to build Pigweed executables. 27 # 28 # If this is a custom template, the .gni file containing the template must 29 # be imported at the top of the target configuration file to make it globally 30 # available. 31 pw_build_EXECUTABLE_TARGET_TYPE = "executable" 32 33 # The path to the .gni file that defines pw_build_EXECUTABLE_TARGET_TYPE. 34 # 35 # If pw_build_EXECUTABLE_TARGET_TYPE is not the default of `executable`, this 36 # .gni file is imported to provide the template definition. 37 pw_build_EXECUTABLE_TARGET_TYPE_FILE = "" 38} 39 40# This template is the underlying implementation that defines what makes 41# pw_source_set, pw_executable, pw_shared_library, and pw_static_library unique. 42# For more information, see the documentation at 43# https://pigweed.dev/pw_build/?highlight=pw_executable#target-types 44# 45# In addition to the arguments supported by the underlying native target types, 46# this template introduces the following arguments: 47# 48# add_global_link_deps: (required) If true, adds global link dependencies as 49# specified by the current toolchain via pw_build_LINK_DEPS as dependencies 50# to all instantiations of the current target type. 51# underlying_target_type: (required) The underlying target type to use for this 52# template. This is done so different C/C++ build target types can share the 53# same underlying wrapper implementation. 54# target_type_file: (optional) If the underlying target type is not one of GN's 55# builtin types, the path to the .gni file that defines the template 56# referenced by underlying_target_type. This is exclusively to support 57# pw_exeuctable's behavior that allows a pw_executable to be essentially 58# aliased to a custom target type. 59# remove_configs: (optional) A list of configs to remove from the set of 60# default configs specified by the current toolchain configuration. 61# remove_public_deps: (optional) A list of targets to remove from the set of 62# default public_deps specified by the current toolchain configuration. 63template("pw_internal_build_target") { 64 assert(defined(invoker.underlying_target_type), 65 "Build targets using this template must specify a target type") 66 _pw_source_files = [] 67 _supported_toolchain_defaults = [ 68 "configs", 69 "public_deps", 70 ] 71 72 # Boilerplate for tracking target sources. For more information see 73 # https://pigweed.dev/pw_build/#target-types 74 if (defined(invoker.sources)) { 75 foreach(path, invoker.sources) { 76 _pw_source_files += [ path ] 77 } 78 } 79 if (defined(invoker.public)) { 80 foreach(path, invoker.public) { 81 _pw_source_files += [ path ] 82 } 83 } 84 85 _builtin_target_types = [ 86 "executable", 87 "rust_library", 88 "shared_library", 89 "source_set", 90 "static_library", 91 ] 92 if (filter_include(_builtin_target_types, 93 [ invoker.underlying_target_type ]) == []) { 94 assert( 95 defined(invoker.target_type_file) && invoker.target_type_file != "", 96 string_join( 97 ", ", 98 [ 99 "Unknown target type ${invoker.underlying_target_type}", 100 "set target_type_file to the .gni file that defines this type.", 101 ])) 102 import(invoker.target_type_file) 103 } 104 105 target(invoker.underlying_target_type, target_name) { 106 # TODO(b/260111641): This import is terrible, and breaks typical Pigweed GN 107 # build arg naming patterns. 108 import("$dir_pw_build/defaults.gni") 109 forward_variables_from( 110 invoker, 111 "*", 112 _supported_toolchain_defaults + [ "target_type_file" ]) 113 114 # Ensure that we don't overwrite metadata forwarded from the invoker above. 115 if (defined(metadata)) { 116 metadata.pw_source_files = _pw_source_files 117 } else { 118 metadata = { 119 pw_source_files = _pw_source_files 120 } 121 } 122 123 if (!defined(configs)) { 124 configs = [] 125 } 126 if (defined(pw_build_defaults.configs)) { 127 configs += pw_build_defaults.configs 128 } 129 if (defined(remove_configs)) { 130 if (remove_configs != [] && remove_configs[0] == "*") { 131 configs = [] 132 } else { 133 configs -= filter_include(configs, remove_configs) 134 } 135 } 136 if (defined(invoker.configs)) { 137 configs += invoker.configs 138 } 139 140 if (defined(pw_build_defaults.public_deps)) { 141 public_deps = pw_build_defaults.public_deps 142 } else { 143 public_deps = [] 144 } 145 if (defined(remove_public_deps)) { 146 if (remove_public_deps != [] && remove_public_deps[0] == "*") { 147 public_deps = [] 148 } else { 149 public_deps += remove_public_deps 150 public_deps -= remove_public_deps 151 } 152 } 153 if (defined(invoker.public_deps)) { 154 public_deps += invoker.public_deps 155 } 156 157 assert(defined(add_global_link_deps), 158 "All targets MUST specify whether or not to include link deps") 159 if (!defined(deps)) { 160 deps = [] 161 } 162 if (add_global_link_deps) { 163 deps += [ "$dir_pw_build:link_deps" ] 164 } 165 166 if (defined(pw_build_defaults.visibility) && !defined(visibility)) { 167 visibility = pw_build_defaults.visibility 168 } 169 } 170} 171