1# Copyright 2021 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_assert/backend.gni") 18import("$dir_pw_bloat/bloat.gni") 19import("$dir_pw_boot/backend.gni") 20import("$dir_pw_build/cc_library.gni") 21import("$dir_pw_chrono/backend.gni") 22import("$dir_pw_interrupt/backend.gni") 23import("$dir_pw_log/backend.gni") 24import("$dir_pw_log_string/backend.gni") 25import("$dir_pw_malloc/backend.gni") 26import("$dir_pw_sync/backend.gni") 27import("$dir_pw_sys_io/backend.gni") 28import("$dir_pw_thread/backend.gni") 29import("$dir_pw_toolchain/arm_gcc/toolchains.gni") 30import("$dir_pw_toolchain/generate_toolchain.gni") 31import("$dir_pw_toolchain/host_clang/toolchains.gni") 32import("$dir_pw_toolchain/host_gcc/toolchains.gni") 33import("$dir_pw_unit_test/test.gni") 34import("backend.gni") 35import("freertos_backends.gni") 36import("stl_backends.gni") 37 38# This scope is essentially an enum for pw_system_target's `cpu` selection. 39PW_SYSTEM_CPU = { 40 CORTEX_M4F = "cortex-m4f" 41 CORTEX_M3 = "cortex-m3" 42 CORTEX_M7F = "cortex-m7f" 43 44 # Native builds for the host CPU. 45 NATIVE = "native" 46} 47 48# This scope is essentially an enum for pw_system_target's `scheduler` 49# selection. 50PW_SYSTEM_SCHEDULER = { 51 FREERTOS = "freertos" 52 53 # Native uses the host OS's native scheduler and OS primitives as provided 54 # through the Standard Template Library. 55 NATIVE = "native" 56} 57 58# Defines a target toolchain, automatically setting many required build 59# arguments to simplify instantiation of a target. 60# 61# Args: 62# cpu: (required) The architecture to target. 63# Supported choices: PW_SYSTEM_CPU.CORTEX_M7F, PW_SYSTEM_CPU.CORTEX_M4F, PW_SYSTEM_CPU.CORTEX_M3, PW_SYSTEM_CPU.NATIVE 64# scheduler: (required) The scheduler implementation and API to use for this 65# target. 66# Supported choices: PW_SYSTEM_SCHEDULER.FREERTOS, PW_SYSTEM_SCHEDULER.NATIVE 67# use_pw_malloc: Whether or not to replace the default malloc implementation 68# with pw_malloc. Defaults enabled for supported targets. 69# link_deps: Additional link-time dependencies required for all executables. 70# This is a list of source sets. 71# build_args: Additional overrides for GN build arguments. 72# global_configs: Configs that will be globally applied to all pw_source_set, 73# pw_static_library, and pw_executable targets. 74template("pw_system_target") { 75 _OPTIMIZATION_LEVELS = { 76 SIZE_OPTIMIZED = "size_optimized" 77 SPEED_OPTIMIZED = "speed_optimized" 78 DEBUG = "debug" 79 } 80 81 # Generic defaults. 82 _default_configs = [ "$dir_pw_build:extra_strict_warnings" ] 83 if (defined(invoker.global_configs)) { 84 foreach(cfg, invoker.global_configs) { 85 _default_configs += [ get_path_info(cfg, "abspath") ] 86 } 87 } 88 89 _link_deps = [ 90 "$dir_pw_assert:impl", 91 "$dir_pw_log:impl", 92 ] 93 if (defined(invoker.link_deps)) { 94 _link_deps += invoker.link_deps 95 } 96 _final_binary_extension = "" 97 98 _default_build_args = { 99 pw_system_RPC_SERVER_BACKEND = "$dir_pw_system:hdlc_rpc_server" 100 pw_system_IO_BACKEND = "$dir_pw_system:sys_io_target_io" 101 102 # TODO(amontanez): This should be set to pw_assert_log ASAP. 103 pw_assert_BACKEND = dir_pw_assert_basic 104 105 # TODO(amontanez): This should be set to pw_log_tokenized when support 106 # is added. 107 pw_log_BACKEND = dir_pw_log_basic 108 109 pw_rpc_CONFIG = "$dir_pw_rpc:use_global_mutex" 110 111 # TODO(amontanez): This should be set to a "$dir_pw_unit_test:rpc_main" 112 # when RPC is working. 113 pw_unit_test_MAIN = "$dir_pw_unit_test:logging_main" 114 } 115 116 # Populate architecture-specific build args. 117 assert( 118 defined(invoker.cpu), 119 "Please select a `cpu` for $target_name. Options: PW_SYSTEM_CPU.CORTEX_M7, PW_SYSTEM_CPU.CORTEX_M4F, PW_SYSTEM_CPU.CORTEX_M3, PW_SYSTEM_CPU.NATIVE") 120 if (invoker.cpu == PW_SYSTEM_CPU.CORTEX_M7F) { 121 _current_cpu = "arm" 122 _default_configs += [ "$dir_pw_toolchain/arm_gcc:enable_float_printf" ] 123 _arch_build_args = { 124 pw_bloat_BLOATY_CONFIG = "$dir_pw_boot_cortex_m/bloaty_config.bloaty" 125 pw_boot_BACKEND = "$dir_pw_boot_cortex_m:armv7m" 126 pw_interrupt_CONTEXT_BACKEND = "$dir_pw_interrupt_cortex_m:context_armv7m" 127 } 128 129 _final_binary_extension = ".elf" 130 131 _toolchains = [ 132 { 133 toolchain_base = pw_toolchain_arm_gcc.cortex_m7f_debug 134 level_name = _OPTIMIZATION_LEVELS.DEBUG 135 }, 136 { 137 toolchain_base = pw_toolchain_arm_gcc.cortex_m7f_size_optimized 138 level_name = _OPTIMIZATION_LEVELS.SIZE_OPTIMIZED 139 }, 140 { 141 toolchain_base = pw_toolchain_arm_gcc.cortex_m7f_speed_optimized 142 level_name = _OPTIMIZATION_LEVELS.SPEED_OPTIMIZED 143 }, 144 ] 145 } else if (invoker.cpu == PW_SYSTEM_CPU.CORTEX_M4F) { 146 _current_cpu = "arm" 147 _default_configs += [ "$dir_pw_toolchain/arm_gcc:enable_float_printf" ] 148 _arch_build_args = { 149 pw_bloat_BLOATY_CONFIG = "$dir_pw_boot_cortex_m/bloaty_config.bloaty" 150 pw_boot_BACKEND = "$dir_pw_boot_cortex_m:armv7m" 151 pw_interrupt_CONTEXT_BACKEND = "$dir_pw_interrupt_cortex_m:context_armv7m" 152 } 153 154 _final_binary_extension = ".elf" 155 156 _toolchains = [ 157 { 158 toolchain_base = pw_toolchain_arm_gcc.cortex_m4f_debug 159 level_name = _OPTIMIZATION_LEVELS.DEBUG 160 }, 161 { 162 toolchain_base = pw_toolchain_arm_gcc.cortex_m4f_size_optimized 163 level_name = _OPTIMIZATION_LEVELS.SIZE_OPTIMIZED 164 }, 165 { 166 toolchain_base = pw_toolchain_arm_gcc.cortex_m4f_speed_optimized 167 level_name = _OPTIMIZATION_LEVELS.SPEED_OPTIMIZED 168 }, 169 ] 170 } else if (invoker.cpu == PW_SYSTEM_CPU.CORTEX_M3) { 171 _current_cpu = "arm" 172 _arch_build_args = { 173 pw_bloat_BLOATY_CONFIG = "$dir_pw_boot_cortex_m/bloaty_config.bloaty" 174 pw_boot_BACKEND = "$dir_pw_boot_cortex_m:armv7m" 175 pw_interrupt_CONTEXT_BACKEND = "$dir_pw_interrupt_cortex_m:context_armv7m" 176 } 177 178 _final_binary_extension = ".elf" 179 180 _toolchains = [ 181 { 182 toolchain_base = pw_toolchain_arm_gcc.cortex_m3_debug 183 level_name = _OPTIMIZATION_LEVELS.DEBUG 184 }, 185 { 186 toolchain_base = pw_toolchain_arm_gcc.cortex_m3_size_optimized 187 level_name = _OPTIMIZATION_LEVELS.SIZE_OPTIMIZED 188 }, 189 { 190 toolchain_base = pw_toolchain_arm_gcc.cortex_m3_speed_optimized 191 level_name = _OPTIMIZATION_LEVELS.SPEED_OPTIMIZED 192 }, 193 ] 194 } else if (invoker.cpu == PW_SYSTEM_CPU.NATIVE) { 195 _current_cpu = host_cpu 196 _arch_build_args = { 197 pw_log_BACKEND = dir_pw_log_string 198 pw_log_string_HANDLER_BACKEND = "$dir_pw_system:log_backend" 199 pw_sys_io_BACKEND = "$dir_pw_sys_io_stdio" 200 pw_system_IO_BACKEND = "$dir_pw_system:socket_target_io" 201 } 202 _link_deps += [ "$dir_pw_log_string:handler.impl" ] 203 204 if (host_os != "win") { 205 _toolchains = [ 206 { 207 toolchain_base = pw_toolchain_host_clang.debug 208 level_name = _OPTIMIZATION_LEVELS.DEBUG 209 }, 210 { 211 toolchain_base = pw_toolchain_host_clang.size_optimized 212 level_name = _OPTIMIZATION_LEVELS.SIZE_OPTIMIZED 213 }, 214 { 215 toolchain_base = pw_toolchain_host_clang.speed_optimized 216 level_name = _OPTIMIZATION_LEVELS.SPEED_OPTIMIZED 217 }, 218 ] 219 } else { 220 _toolchains = [ 221 { 222 toolchain_base = pw_toolchain_host_gcc.debug 223 level_name = _OPTIMIZATION_LEVELS.DEBUG 224 }, 225 { 226 toolchain_base = pw_toolchain_host_gcc.size_optimized 227 level_name = _OPTIMIZATION_LEVELS.SIZE_OPTIMIZED 228 }, 229 { 230 toolchain_base = pw_toolchain_host_gcc.speed_optimized 231 level_name = _OPTIMIZATION_LEVELS.SPEED_OPTIMIZED 232 }, 233 ] 234 } 235 } 236 assert(defined(_arch_build_args), 237 "Unknown cpu choice for $target_name: `${invoker.cpu}`") 238 239 # Populate OS-specific build args. 240 assert( 241 defined(invoker.scheduler), 242 "Please select an `scheduler` for $target_name. Options: PW_SYSTEM_SCHEDULER.FREERTOS, PW_SYSTEM_SCHEDULER.NATIVE") 243 if (invoker.scheduler == PW_SYSTEM_SCHEDULER.FREERTOS) { 244 _current_os = "freertos" 245 _os_build_args = PW_SYSTEM_FREERTOS_BACKENDS 246 } else if (invoker.scheduler == PW_SYSTEM_SCHEDULER.NATIVE) { 247 _current_os = host_os 248 _os_build_args = PW_SYSTEM_STL_BACKENDS 249 } 250 assert(defined(_os_build_args), 251 "Unknown scheduler choice for $target_name: `${invoker.scheduler}`") 252 253 # Configure malloc defaults. 254 _use_pw_malloc = false 255 if (defined(invoker.use_pw_malloc)) { 256 _use_pw_malloc = invoker.use_pw_malloc 257 } else if (invoker.cpu != PW_SYSTEM_CPU.NATIVE) { 258 _use_pw_malloc = true 259 } 260 261 if (_use_pw_malloc) { 262 _default_configs += [ "$dir_pw_malloc:pw_malloc_wrapper_config" ] 263 _link_deps += [ dir_pw_malloc ] 264 _malloc_build_args = { 265 pw_malloc_BACKEND = dir_pw_malloc_freelist 266 } 267 } else { 268 _malloc_build_args = { 269 } 270 } 271 272 foreach(toolchain_and_level, _toolchains) { 273 # Clear from previous iteration. 274 _base = { 275 } 276 _base = toolchain_and_level.toolchain_base 277 278 generate_toolchain("${target_name}.${toolchain_and_level.level_name}") { 279 forward_variables_from(_base, 280 "*", 281 [ 282 "defaults", 283 "name", 284 ]) 285 final_binary_extension = _final_binary_extension 286 defaults = { 287 current_os = _current_os 288 current_cpu = _current_cpu 289 forward_variables_from(_base.defaults, "*") 290 forward_variables_from(_default_build_args, "*") 291 forward_variables_from(_arch_build_args, "*") 292 forward_variables_from(_os_build_args, "*") 293 forward_variables_from(_malloc_build_args, "*") 294 default_configs += _default_configs 295 if (!defined(pw_build_LINK_DEPS)) { 296 pw_build_LINK_DEPS = [] 297 } 298 pw_build_LINK_DEPS += _link_deps 299 300 if (defined(invoker.build_args)) { 301 forward_variables_from(invoker.build_args, "*") 302 } 303 } 304 } 305 } 306} 307