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
15_script_path = rebase_path("../py/pw_toolchain/clang_arm_toolchain.py")
16
17# This template generates a config that can be used to target ARM cores using
18# a clang compiler.
19#
20# Clang isn't a plug-and-play experience for Cortex-M baremetal targets; it's
21# missing C runtime libraries, C/C++ standard libraries, and a few other
22# things. This template uses the provided cflags, asmflags, ldflags, etc. to
23# generate a config that pulls the missing components from an arm-none-eabi-gcc
24# compiler on the system PATH. The end result is a clang-based compiler that
25# pulls in gcc-provided headers and libraries to complete the toolchain.
26#
27# Args:
28#   - asmflags, cflags, cflags_c, cflags_cc, ldflags: These flags are used to
29#         locate the correct architecture-specific libraries/headers. To
30#         properly drive the script, provide all architecture flags (e.g. -mcpu,
31#         -mabi, -mthumb, -mfloat-abi, -mfpu) in at least one of these
32#         variables.
33#
34# Generated targets:
35#   - $target_name: The final config to use with your clang toolchain.
36template("pw_clang_arm_config") {
37  config(target_name) {
38    # Pull all the compiler flags into a single list.
39    _compiler_flags = []
40    forward_variables_from(invoker, "*")
41    if (defined(asmflags)) {
42      _compiler_flags += asmflags
43    } else {
44      asmflags = []
45    }
46    if (defined(cflags)) {
47      _compiler_flags += cflags
48    } else {
49      cflags = []
50    }
51    if (defined(cflags_c)) {
52      _compiler_flags += cflags_c
53    } else {
54      cflags_c = []
55    }
56    if (defined(cflags_cc)) {
57      _compiler_flags += cflags_cc
58    } else {
59      cflags_cc = []
60    }
61    if (defined(ldflags)) {
62      _compiler_flags += ldflags
63    } else {
64      ldflags = []
65    }
66
67    # Invoke the script that will generate clang flags based on the current
68    # compiler version and desired arch.
69    _script_flags = [
70      "--gn-scope",
71      "--cflags",
72      "--ldflags",
73      "--",
74    ]
75    _script_flags += _compiler_flags
76    _arm_flags = exec_script(_script_path, _script_flags, "scope")
77
78    cflags += _arm_flags.cflags
79    ldflags += _arm_flags.cflags
80    ldflags += _arm_flags.ldflags
81  }
82}
83