blob: 8e55619670fe98d5c3971ffed18f4daee991a7ae [file] [log] [blame]
Chris Kayc8a47ba2023-10-20 09:17:33 +00001#
2# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6
7#
8# TF-A uses three toolchains:
9#
10# - The host toolchain (`host`) for building native tools
11#  - The AArch32 toolchain (`aarch32`) for building Arm AArch32 images
12# - The AArch64 toolchain (`aarch64`) for building Arm AArch64 images
13#
14# In the main Makefile only one of the two Arm toolchains is enabled in any
15# given build, but individual tools and libraries may need access to both.
16#
17
18toolchains ?= host $(ARCH)
19
Chris Kayc8a47ba2023-10-20 09:17:33 +000020include $(dir $(lastword $(MAKEFILE_LIST)))build_env.mk
Chris Kay2c09bf62024-04-09 16:30:52 +000021include $(dir $(lastword $(MAKEFILE_LIST)))utilities.mk
22
Chris Kayc8a47ba2023-10-20 09:17:33 +000023include $(addprefix $(dir $(lastword $(MAKEFILE_LIST)))toolchains/, \
24 $(addsuffix .mk,$(toolchains)))
25
26#
27# Configure tool classes that we recognize.
28#
29# In the context of this build system, a tool class identifies a specific role
30# or type of tool in the toolchain.
31#
32
Chris Kay24f3fb42024-04-16 17:19:20 +000033tool-classes := cc
34tool-class-name-cc := C compiler
Chris Kayc8a47ba2023-10-20 09:17:33 +000035
Chris Kay24f3fb42024-04-16 17:19:20 +000036tool-classes += cpp
37tool-class-name-cpp := C preprocessor
Chris Kayc8a47ba2023-10-20 09:17:33 +000038
Chris Kay24f3fb42024-04-16 17:19:20 +000039tool-classes += as
40tool-class-name-as := assembler
Chris Kayc8a47ba2023-10-20 09:17:33 +000041
Chris Kay24f3fb42024-04-16 17:19:20 +000042tool-classes += ld
43tool-class-name-ld := linker
44
45tool-classes += oc
46tool-class-name-oc := object copier
47
48tool-classes += od
49tool-class-name-od := object dumper
50
51tool-classes += ar
52tool-class-name-ar := archiver
53
54tool-classes += dtc
55tool-class-name-dtc := device tree compiler
Chris Kayc8a47ba2023-10-20 09:17:33 +000056
57#
58# Configure tools that we recognize.
59#
60# Here we declare the list of specific toolchain tools that we know how to
61# interact with. We don't organize these into tool classes yet - that happens
62# further down.
63#
64
Chris Kay24f3fb42024-04-16 17:19:20 +000065# Arm® Compiler for Embedded
66tools := arm-clang
67tool-name-arm-clang := Arm® Compiler for Embedded `armclang`
68
69tools += arm-link
70tool-name-arm-link := Arm® Compiler for Embedded `armlink`
71
72tools += arm-ar
73tool-name-arm-ar := Arm® Compiler for Embedded `armar`
74
75tools += arm-fromelf
76tool-name-arm-fromelf := Arm® Compiler for Embedded `fromelf`
Chris Kayc8a47ba2023-10-20 09:17:33 +000077
78# LLVM Project
Chris Kay24f3fb42024-04-16 17:19:20 +000079tools += llvm-clang
80tool-name-llvm-clang := LLVM Clang (`clang`)
81
82tools += llvm-lld
83tool-name-llvm-lld := LLVM LLD (`lld`)
84
85tools += llvm-objcopy
86tool-name-llvm-objcopy := LLVM `llvm-objcopy`
87
88tools += llvm-objdump
89tool-name-llvm-objdump := LLVM `llvm-objdump`
90
91tools += llvm-ar
92tool-name-llvm-ar := LLVM `llvm-ar`
Chris Kayc8a47ba2023-10-20 09:17:33 +000093
94# GNU Compiler Collection & GNU Binary Utilities
Chris Kay24f3fb42024-04-16 17:19:20 +000095tools += gnu-gcc
96tool-name-gnu-gcc := GNU GCC (`gcc`)
97
98tools += gnu-ld
99tool-name-gnu-ld := GNU LD (`ld.bfd`)
100
101tools += gnu-objcopy
102tool-name-gnu-objcopy := GNU `objcopy`
103
104tools += gnu-objdump
105tool-name-gnu-objdump := GNU `objdump`
106
107tools += gnu-ar
108tool-name-gnu-ar := GNU `ar`
Chris Kayc8a47ba2023-10-20 09:17:33 +0000109
110# Other tools
Chris Kay24f3fb42024-04-16 17:19:20 +0000111tools += generic-dtc
112tool-name-generic-dtc := Device Tree Compiler (`dtc`)
Chris Kayc8a47ba2023-10-20 09:17:33 +0000113
114#
115# Assign tools to tool classes.
116#
117# Multifunctional tools, i.e. tools which can perform multiple roles in a
118# toolchain, may be specified in multiple tool class lists. For example, a C
119# compiler which can also perform the role of a linker may be placed in both
120# `tools-cc` and `tools-ld`.
121#
122
123# C-related tools
124tools-cc := arm-clang llvm-clang gnu-gcc # C compilers
125tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors
126
127# Assembly-related tools
128tools-as := arm-clang llvm-clang gnu-gcc # Assemblers
129
130# Linking and object-handling tools
131tools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers
132tools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers
133tools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers
134tools-ar := arm-ar llvm-ar gnu-ar # Archivers
135
136# Other tools
Chris Kay24f3fb42024-04-16 17:19:20 +0000137tools-dtc := generic-dtc # Device tree compilers
Chris Kayc8a47ba2023-10-20 09:17:33 +0000138
139define check-tool-class-tools
140 $(eval tool-class := $(1))
141
142 ifndef tools-$(tool-class)
143 $$(error no tools registered to handle tool class `$(tool-class)`)
144 endif
145endef
146
147$(foreach tool-class,$(tool-classes), \
148 $(eval $(call check-tool-class-tools,$(tool-class))))
149
150#
151# Default tools for each toolchain.
152#
153# Toolchains can specify a default path to any given tool with a tool class.
154# These values are used in the absence of user-specified values, and are
Chris Kay0a2f8a02024-02-20 13:13:23 +0000155# configured by the makefile for each toolchain using variables of the form:
Chris Kayc8a47ba2023-10-20 09:17:33 +0000156#
157# - $(toolchain)-$(tool-class)-default
158#
159# For example, the default C compiler for the AArch32 and AArch64 toolchains
160# could be configured with:
161#
162# - aarch32-cc-default
163# - aarch64-cc-default
164#
165
166define check-toolchain-tool-class-default
167 $(eval toolchain := $(1))
168 $(eval tool-class := $(2))
169
170 ifndef $(toolchain)-$(tool-class)-default
171 $$(error no default value specified for tool class `$(tool-class)` of toolchain `$(toolchain)`)
172 endif
173endef
174
175define check-toolchain-tool-class-defaults
176 $(eval toolchain := $(1))
177
178 $(foreach tool-class,$(tool-classes), \
179 $(eval $(call check-toolchain-tool-class-default,$(toolchain),$(tool-class))))
180endef
181
182$(foreach toolchain,$(toolchains), \
183 $(eval $(call check-toolchain-tool-class-defaults,$(toolchain))))
184
185#
186# Helper functions to identify toolchain tools.
187#
188# The functions defined in this section return a tool identifier when given a
189# path to a binary. We generally check a help or version string to more reliably
190# identify tools than by looking at the path alone (e.g. `gcc` on macOS is
191# actually Apple Clang).
192#
193# Each tool-guessing function (`guess-tool-$(tool)`) takes a single argument
194# giving the path to the tool to guess, and returns a non-empty value if the
195# tool corresponds to the tool identifier `$(tool)`:
196#
197# $(call guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty>
198# $(call guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty>
199#
200# The `guess-tool` function tries to find the corresponding tool identifier
201# for a tool given its path. It takes two arguments:
202#
203# - $(1): a list of candidate tool identifiers to check
204# - $(2): the path to the tool to identify
205#
206# If any of the guess functions corresponding to candidate tool identifiers
207# return a non-empty value then the tool identifier of the first function to do
208# so is returned:
209#
210# $(call guess-tool,gnu-gcc llvm-clang,armclang) # <empty>
211# $(call guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang
212# $(call guess-tool,gnu-gcc llvm-clang,aarch64-none-elf-gcc-12) # gnu-gcc
213#
214# Tools are checked in the order that they appear in `tools-$(tool-class)`, and
215# the first match is returned.
216#
217
218# Arm Compiler for Embedded
Chris Kay24f3fb42024-04-16 17:19:20 +0000219guess-tool-arm-clang = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "Tool: armclang")
220guess-tool-arm-link = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "Tool: armlink")
221guess-tool-arm-fromelf = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "Tool: fromelf")
222guess-tool-arm-ar = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "Tool: armar")
Chris Kayc8a47ba2023-10-20 09:17:33 +0000223
224# LLVM Project
Chris Kay24f3fb42024-04-16 17:19:20 +0000225guess-tool-llvm-clang = $(shell $(call escape-shell,$(1)) -v 2>&1 <$(nul) | grep -o "clang version")
226guess-tool-llvm-lld = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "OVERVIEW: lld")
227guess-tool-llvm-objcopy = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "llvm-objcopy tool")
228guess-tool-llvm-objdump = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "llvm object file dumper")
229guess-tool-llvm-ar = $(shell $(call escape-shell,$(1)) --help 2>&1 <$(nul) | grep -o "LLVM Archiver")
Chris Kayc8a47ba2023-10-20 09:17:33 +0000230
231# GNU Compiler Collection & GNU Binary Utilities
Chris Kay24f3fb42024-04-16 17:19:20 +0000232guess-tool-gnu-gcc = $(shell $(call escape-shell,$(1)) -v 2>&1 <$(nul) | grep -o "gcc version")
233guess-tool-gnu-ld = $(shell $(call escape-shell,$(1)) -v 2>&1 <$(nul) | grep -o "GNU ld")
234guess-tool-gnu-objcopy = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "GNU objcopy")
235guess-tool-gnu-objdump = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "GNU objdump")
236guess-tool-gnu-ar = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "GNU ar")
Chris Kayc8a47ba2023-10-20 09:17:33 +0000237
238# Other tools
Chris Kay24f3fb42024-04-16 17:19:20 +0000239guess-tool-generic-dtc = $(shell $(call escape-shell,$(1)) --version 2>&1 <$(nul) | grep -o "Version: DTC")
Chris Kayc8a47ba2023-10-20 09:17:33 +0000240
241guess-tool = $(firstword $(foreach candidate,$(1), \
242 $(if $(call guess-tool-$(candidate),$(2)),$(candidate))))
243
244#
245# Locate and identify tools belonging to each toolchain.
246#
247# Each tool class in each toolchain receives a variable of the form
248# `$(toolchain)-$(tool)` giving the associated path to the program. For example:
249#
250# - `aarch64-ld` gives the linker for the AArch64 toolchain,
251# - `aarch32-oc` gives the object copier for the AArch32 toolchain, and
252# - `host-cc` gives the C compiler for the host toolchain.
253#
254# For each of these variables, if no program path is explicitly provided by the
255# parent Makefile then the C compiler is queried (if supported) for its
256# location. This is done via the `guess-$(tool)-$(tool-class)` set of functions.
257# For example:
258#
259# - `guess-arm-clang-ld` guesses the linker via Arm Clang,
260# - `guess-llvm-clang-as` guesses the assembler via LLVM Clang, and
261# - `guess-gnu-gcc-od` guesses the object dumper via GNU GCC.
262#
263# If the C compiler cannot provide the location (or the tool class is the C
264# compiler), then it is assigned the value of the `$(toolchain)-$(tool)-default`
265# variable.
266#
267
Chris Kay2c09bf62024-04-09 16:30:52 +0000268guess-arm-clang-cpp = $(1)
269guess-arm-clang-as = $(1)
Chris Kayc8a47ba2023-10-20 09:17:33 +0000270guess-arm-clang-ld = # Fall back to `$(toolchain)-ld-default`
271guess-arm-clang-oc = # Fall back to `$(toolchain)-oc-default`
272guess-arm-clang-od = # Fall back to `$(toolchain)-od-default`
273guess-arm-clang-ar = # Fall back to `$(toolchain)-ar-default`
274
Chris Kay2c09bf62024-04-09 16:30:52 +0000275guess-llvm-clang-cpp = $(1)
276guess-llvm-clang-as = $(1)
277guess-llvm-clang-ld = $(shell $(call escape-shell,$(1)) --print-prog-name ld.lld 2>$(nul))
278guess-llvm-clang-oc = $(shell $(call escape-shell,$(1)) --print-prog-name llvm-objcopy 2>$(nul))
279guess-llvm-clang-od = $(shell $(call escape-shell,$(1)) --print-prog-name llvm-objdump 2>$(nul))
280guess-llvm-clang-ar = $(shell $(call escape-shell,$(1)) --print-prog-name llvm-ar 2>$(nul))
Chris Kayc8a47ba2023-10-20 09:17:33 +0000281
Chris Kay2c09bf62024-04-09 16:30:52 +0000282guess-gnu-gcc-cpp = $(1)
283guess-gnu-gcc-as = $(1)
284guess-gnu-gcc-ld = $(1)
285guess-gnu-gcc-oc = $(shell $(call escape-shell,$(1)) --print-prog-name objcopy 2>$(nul))
286guess-gnu-gcc-od = $(shell $(call escape-shell,$(1)) --print-prog-name objdump 2>$(nul))
287guess-gnu-gcc-ar = $(call which,$(call decompat-path,$(patsubst %$(call file-name,$(1)),%$(subst gcc,gcc-ar,$(call file-name,$(1))),$(call compat-path,$(1)))))
Chris Kayc8a47ba2023-10-20 09:17:33 +0000288
Chris Kay24f3fb42024-04-16 17:19:20 +0000289define warn-unrecognized-tool
290 $(eval toolchain := $(1))
291 $(eval tool-class := $(2))
292
293 $$(warning )
294 $$(warning The configured $$($(toolchain)-name) $$(tool-class-name-$(tool-class)) could not be identified and may not be supported:)
295 $$(warning )
296 $$(warning $$(space) $$($(toolchain)-$(tool-class)))
297 $$(warning )
298 $$(warning The default $$($(toolchain)-name) $$(tool-class-name-$(tool-class)) is:)
299 $$(warning )
300 $$(warning $$(space) $$($(toolchain)-$(tool-class)-default))
301 $$(warning )
302 $$(warning The following tools are supported:)
303 $$(warning )
304
305 $$(foreach tool,$$(tools-$(tool-class)), \
306 $$(warning $$(space) - $$(tool-name-$$(tool))))
307
308 $$(warning )
309 $$(warning The build system will treat this $$(tool-class-name-$(tool-class)) as $$(tool-name-$$($(toolchain)-$(tool-class)-id-default)).)
310 $$(warning )
311endef
312
Chris Kayc8a47ba2023-10-20 09:17:33 +0000313define locate-toolchain-tool-cc
314 $(eval toolchain := $(1))
315
Chris Kay2c09bf62024-04-09 16:30:52 +0000316 $(toolchain)-cc := $$(or $$($(toolchain)-cc),$$($(toolchain)-cc-default))
317 $(toolchain)-cc-id := $$(call guess-tool,$$(tools-cc),$$($(toolchain)-cc))
Chris Kay24f3fb42024-04-16 17:19:20 +0000318
319 ifndef $(toolchain)-cc-id
320 $(toolchain)-cc-id := $$($(toolchain)-cc-id-default)
321
322 $$(eval $$(call warn-unrecognized-tool,$(toolchain),cc))
323 endif
324
325 $(toolchain)-cc-path := $$($(toolchain)-cc)
326 $(toolchain)-cc := $$(call escape-shell,$$($(toolchain)-cc))
Chris Kayc8a47ba2023-10-20 09:17:33 +0000327endef
328
329define locate-toolchain-tool
330 $(eval toolchain := $(1))
331 $(eval tool-class := $(2))
332
333 ifndef $(toolchain)-$(tool-class)
Chris Kay2c09bf62024-04-09 16:30:52 +0000334 $(toolchain)-$(tool-class) := $$(call guess-$$($(toolchain)-cc-id)-$(tool-class),$$($(toolchain)-cc-path))
Chris Kayc8a47ba2023-10-20 09:17:33 +0000335
Chris Kay24f3fb42024-04-16 17:19:20 +0000336 ifndef $(toolchain)-$(tool-class)
Chris Kay2c09bf62024-04-09 16:30:52 +0000337 $(toolchain)-$(tool-class) := $$($(toolchain)-$(tool-class)-default)
Chris Kayc8a47ba2023-10-20 09:17:33 +0000338 endif
339 endif
340
Chris Kay24f3fb42024-04-16 17:19:20 +0000341 $(toolchain)-$(tool-class)-id := $$(call guess-tool,$$(tools-$(tool-class)),$$($(toolchain)-$(tool-class)))
Chris Kayc8a47ba2023-10-20 09:17:33 +0000342
Chris Kay24f3fb42024-04-16 17:19:20 +0000343 ifndef $(toolchain)-$(tool-class)-id
344 $(toolchain)-$(tool-class)-id := $$($(toolchain)-$(tool-class)-id-default)
Chris Kayc8a47ba2023-10-20 09:17:33 +0000345
Chris Kay24f3fb42024-04-16 17:19:20 +0000346 $$(eval $$(call warn-unrecognized-tool,$(toolchain),$(tool-class)))
347 endif
Chris Kay2c09bf62024-04-09 16:30:52 +0000348
Chris Kay24f3fb42024-04-16 17:19:20 +0000349 $(toolchain)-$(tool-class) := $$(call escape-shell,$$($(toolchain)-$(tool-class)))
Chris Kayc8a47ba2023-10-20 09:17:33 +0000350endef
351
352define locate-toolchain
353 $(eval toolchain := $(1))
354
355 $$(eval $$(call locate-toolchain-tool-cc,$(toolchain)))
Chris Kayc8a47ba2023-10-20 09:17:33 +0000356
357 $$(foreach tool-class,$$(filter-out cc,$$(tool-classes)), \
Chris Kay24f3fb42024-04-16 17:19:20 +0000358 $$(eval $$(call locate-toolchain-tool,$(toolchain),$$(tool-class))))
Chris Kayc8a47ba2023-10-20 09:17:33 +0000359endef
360
361$(foreach toolchain,$(toolchains), \
362 $(eval $(call locate-toolchain,$(toolchain))))