xref: /rk3399_ARM-atf/make_helpers/toolchain.mk (revision cc277de81692cf72f067354ada6e84f5e996f6b8)
1*cc277de8SChris Kay#
2*cc277de8SChris Kay# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
3*cc277de8SChris Kay#
4*cc277de8SChris Kay# SPDX-License-Identifier: BSD-3-Clause
5*cc277de8SChris Kay#
6*cc277de8SChris Kay
7*cc277de8SChris Kay#
8*cc277de8SChris Kay# TF-A uses three toolchains:
9*cc277de8SChris Kay#
10*cc277de8SChris Kay#   - The host toolchain (`host`) for building native tools
11*cc277de8SChris Kay#   - The AArch32 toolchain (`aarch32`) for building Arm AArch32 images
12*cc277de8SChris Kay#   - The AArch64 toolchain (`aarch64`) for building Arm AArch64 images
13*cc277de8SChris Kay#
14*cc277de8SChris Kay# In the main Makefile only one of the two Arm toolchains is enabled in any
15*cc277de8SChris Kay# given build, but individual tools and libraries may need access to both.
16*cc277de8SChris Kay#
17*cc277de8SChris Kay
18*cc277de8SChris Kaytoolchains ?= host $(ARCH)
19*cc277de8SChris Kay
20*cc277de8SChris Kayifneq ($(filter host,$(toolchains)),)
21*cc277de8SChris Kay        host-cc := $(HOSTCC)
22*cc277de8SChris Kay        host-cpp := $(HOSTCPP)
23*cc277de8SChris Kay
24*cc277de8SChris Kay        host-as := $(HOSTAS)
25*cc277de8SChris Kay
26*cc277de8SChris Kay        host-ld := $(HOSTLD)
27*cc277de8SChris Kay        host-oc := $(HOSTOC)
28*cc277de8SChris Kay        host-od := $(HOSTOD)
29*cc277de8SChris Kay        host-ar := $(HOSTAR)
30*cc277de8SChris Kay
31*cc277de8SChris Kay        host-dtc := $(HOSTDTC)
32*cc277de8SChris Kayendif
33*cc277de8SChris Kay
34*cc277de8SChris Kayifneq ($(filter aarch32,$(toolchains)),)
35*cc277de8SChris Kay        aarch32-cc := $(if $(filter-out default,$(origin CC)),$(CC))
36*cc277de8SChris Kay        aarch32-cpp := $(if $(filter-out default,$(origin CPP)),$(CPP))
37*cc277de8SChris Kay
38*cc277de8SChris Kay        aarch32-as := $(if $(filter-out default,$(origin AS)),$(AS))
39*cc277de8SChris Kay
40*cc277de8SChris Kay        aarch32-ld := $(if $(filter-out default,$(origin LD)),$(LD))
41*cc277de8SChris Kay        aarch32-oc := $(if $(filter-out default,$(origin OC)),$(OC))
42*cc277de8SChris Kay        aarch32-od := $(if $(filter-out default,$(origin OD)),$(OD))
43*cc277de8SChris Kay        aarch32-ar := $(if $(filter-out default,$(origin AR)),$(AR))
44*cc277de8SChris Kay
45*cc277de8SChris Kay        aarch32-dtc := $(if $(filter-out default,$(origin DTC)),$(DTC))
46*cc277de8SChris Kayendif
47*cc277de8SChris Kay
48*cc277de8SChris Kayifneq ($(filter aarch64,$(toolchains)),)
49*cc277de8SChris Kay        aarch64-cc := $(if $(filter-out default,$(origin CC)),$(CC))
50*cc277de8SChris Kay        aarch64-cpp := $(if $(filter-out default,$(origin CPP)),$(CPP))
51*cc277de8SChris Kay
52*cc277de8SChris Kay        aarch64-as := $(if $(filter-out default,$(origin AS)),$(AS))
53*cc277de8SChris Kay
54*cc277de8SChris Kay        aarch64-ld := $(if $(filter-out default,$(origin LD)),$(LD))
55*cc277de8SChris Kay        aarch64-oc := $(if $(filter-out default,$(origin OC)),$(OC))
56*cc277de8SChris Kay        aarch64-od := $(if $(filter-out default,$(origin OD)),$(OD))
57*cc277de8SChris Kay        aarch64-ar := $(if $(filter-out default,$(origin AR)),$(AR))
58*cc277de8SChris Kay
59*cc277de8SChris Kay        aarch64-dtc := $(if $(filter-out default,$(origin DTC)),$(DTC))
60*cc277de8SChris Kayendif
61*cc277de8SChris Kay
62*cc277de8SChris Kayinclude $(dir $(lastword $(MAKEFILE_LIST)))build_env.mk
63*cc277de8SChris Kayinclude $(addprefix $(dir $(lastword $(MAKEFILE_LIST)))toolchains/, \
64*cc277de8SChris Kay        $(addsuffix .mk,$(toolchains)))
65*cc277de8SChris Kay
66*cc277de8SChris Kay#
67*cc277de8SChris Kay# Configure tool classes that we recognize.
68*cc277de8SChris Kay#
69*cc277de8SChris Kay# In the context of this build system, a tool class identifies a specific role
70*cc277de8SChris Kay# or type of tool in the toolchain.
71*cc277de8SChris Kay#
72*cc277de8SChris Kay
73*cc277de8SChris Kay# C-related tools
74*cc277de8SChris Kaytool-classes := cc # C compilers
75*cc277de8SChris Kaytool-classes += cpp # C preprocessors
76*cc277de8SChris Kay
77*cc277de8SChris Kay# Assembly-related tools
78*cc277de8SChris Kaytool-classes += as # Assemblers
79*cc277de8SChris Kay
80*cc277de8SChris Kay# Linking and object-handling tools
81*cc277de8SChris Kaytool-classes += ld # Linkers
82*cc277de8SChris Kaytool-classes += oc # Object copiers
83*cc277de8SChris Kaytool-classes += od # Object dumpers
84*cc277de8SChris Kaytool-classes += ar # Archivers
85*cc277de8SChris Kay
86*cc277de8SChris Kay# Other tools
87*cc277de8SChris Kaytool-classes += dtc # Device tree compilers
88*cc277de8SChris Kay
89*cc277de8SChris Kay#
90*cc277de8SChris Kay# Configure tools that we recognize.
91*cc277de8SChris Kay#
92*cc277de8SChris Kay# Here we declare the list of specific toolchain tools that we know how to
93*cc277de8SChris Kay# interact with. We don't organize these into tool classes yet - that happens
94*cc277de8SChris Kay# further down.
95*cc277de8SChris Kay#
96*cc277de8SChris Kay
97*cc277de8SChris Kay# Arm Compiler for Embedded
98*cc277de8SChris Kaytools := arm-clang # armclang
99*cc277de8SChris Kaytools += arm-link # armlink
100*cc277de8SChris Kaytools += arm-ar # armar
101*cc277de8SChris Kaytools += arm-fromelf # fromelf
102*cc277de8SChris Kay
103*cc277de8SChris Kay# LLVM Project
104*cc277de8SChris Kaytools += llvm-clang # clang
105*cc277de8SChris Kaytools += llvm-lld # lld
106*cc277de8SChris Kaytools += llvm-objcopy # llvm-objcopy
107*cc277de8SChris Kaytools += llvm-objdump # llvm-objdump
108*cc277de8SChris Kaytools += llvm-ar # llvm-ar
109*cc277de8SChris Kay
110*cc277de8SChris Kay# GNU Compiler Collection & GNU Binary Utilities
111*cc277de8SChris Kaytools += gnu-gcc # gcc
112*cc277de8SChris Kaytools += gnu-ld # ld
113*cc277de8SChris Kaytools += gnu-objcopy # objcopy
114*cc277de8SChris Kaytools += gnu-objdump # objdump
115*cc277de8SChris Kaytools += gnu-ar # gcc-ar
116*cc277de8SChris Kay
117*cc277de8SChris Kay# Other tools
118*cc277de8SChris Kaytools += dtc # Device Tree Compiler
119*cc277de8SChris Kay
120*cc277de8SChris Kay#
121*cc277de8SChris Kay# Assign tools to tool classes.
122*cc277de8SChris Kay#
123*cc277de8SChris Kay# Multifunctional tools, i.e. tools which can perform multiple roles in a
124*cc277de8SChris Kay# toolchain, may be specified in multiple tool class lists. For example, a C
125*cc277de8SChris Kay# compiler which can also perform the role of a linker may be placed in both
126*cc277de8SChris Kay# `tools-cc` and `tools-ld`.
127*cc277de8SChris Kay#
128*cc277de8SChris Kay
129*cc277de8SChris Kay# C-related tools
130*cc277de8SChris Kaytools-cc := arm-clang llvm-clang gnu-gcc # C compilers
131*cc277de8SChris Kaytools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors
132*cc277de8SChris Kay
133*cc277de8SChris Kay# Assembly-related tools
134*cc277de8SChris Kaytools-as := arm-clang llvm-clang gnu-gcc # Assemblers
135*cc277de8SChris Kay
136*cc277de8SChris Kay# Linking and object-handling tools
137*cc277de8SChris Kaytools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers
138*cc277de8SChris Kaytools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers
139*cc277de8SChris Kaytools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers
140*cc277de8SChris Kaytools-ar := arm-ar llvm-ar gnu-ar # Archivers
141*cc277de8SChris Kay
142*cc277de8SChris Kay# Other tools
143*cc277de8SChris Kaytools-dtc := dtc # Device tree compilers
144*cc277de8SChris Kay
145*cc277de8SChris Kaydefine check-tool-class-tools
146*cc277de8SChris Kay        $(eval tool-class := $(1))
147*cc277de8SChris Kay
148*cc277de8SChris Kay        ifndef tools-$(tool-class)
149*cc277de8SChris Kay                $$(error no tools registered to handle tool class `$(tool-class)`)
150*cc277de8SChris Kay        endif
151*cc277de8SChris Kayendef
152*cc277de8SChris Kay
153*cc277de8SChris Kay$(foreach tool-class,$(tool-classes), \
154*cc277de8SChris Kay        $(eval $(call check-tool-class-tools,$(tool-class))))
155*cc277de8SChris Kay
156*cc277de8SChris Kay#
157*cc277de8SChris Kay# Default tools for each toolchain.
158*cc277de8SChris Kay#
159*cc277de8SChris Kay# Toolchains can specify a default path to any given tool with a tool class.
160*cc277de8SChris Kay# These values are used in the absence of user-specified values, and are
161*cc277de8SChris Kay# configured by the parent Makefile using variables of the form:
162*cc277de8SChris Kay#
163*cc277de8SChris Kay#   - $(toolchain)-$(tool-class)-default
164*cc277de8SChris Kay#
165*cc277de8SChris Kay# For example, the default C compiler for the AArch32 and AArch64 toolchains
166*cc277de8SChris Kay# could be configured with:
167*cc277de8SChris Kay#
168*cc277de8SChris Kay#   - aarch32-cc-default
169*cc277de8SChris Kay#   - aarch64-cc-default
170*cc277de8SChris Kay#
171*cc277de8SChris Kay
172*cc277de8SChris Kaydefine check-toolchain-tool-class-default
173*cc277de8SChris Kay        $(eval toolchain := $(1))
174*cc277de8SChris Kay        $(eval tool-class := $(2))
175*cc277de8SChris Kay
176*cc277de8SChris Kay        ifndef $(toolchain)-$(tool-class)-default
177*cc277de8SChris Kay                $$(error no default value specified for tool class `$(tool-class)` of toolchain `$(toolchain)`)
178*cc277de8SChris Kay        endif
179*cc277de8SChris Kayendef
180*cc277de8SChris Kay
181*cc277de8SChris Kaydefine check-toolchain-tool-class-defaults
182*cc277de8SChris Kay        $(eval toolchain := $(1))
183*cc277de8SChris Kay
184*cc277de8SChris Kay        $(foreach tool-class,$(tool-classes), \
185*cc277de8SChris Kay                $(eval $(call check-toolchain-tool-class-default,$(toolchain),$(tool-class))))
186*cc277de8SChris Kayendef
187*cc277de8SChris Kay
188*cc277de8SChris Kay$(foreach toolchain,$(toolchains), \
189*cc277de8SChris Kay        $(eval $(call check-toolchain-tool-class-defaults,$(toolchain))))
190*cc277de8SChris Kay
191*cc277de8SChris Kay#
192*cc277de8SChris Kay# Helper functions to identify toolchain tools.
193*cc277de8SChris Kay#
194*cc277de8SChris Kay# The functions defined in this section return a tool identifier when given a
195*cc277de8SChris Kay# path to a binary. We generally check a help or version string to more reliably
196*cc277de8SChris Kay# identify tools than by looking at the path alone (e.g. `gcc` on macOS is
197*cc277de8SChris Kay# actually Apple Clang).
198*cc277de8SChris Kay#
199*cc277de8SChris Kay# Each tool-guessing function (`guess-tool-$(tool)`) takes a single argument
200*cc277de8SChris Kay# giving the path to the tool to guess, and returns a non-empty value if the
201*cc277de8SChris Kay# tool corresponds to the tool identifier `$(tool)`:
202*cc277de8SChris Kay#
203*cc277de8SChris Kay#     $(call guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty>
204*cc277de8SChris Kay#     $(call guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty>
205*cc277de8SChris Kay#
206*cc277de8SChris Kay# The `guess-tool` function tries to find the corresponding tool identifier
207*cc277de8SChris Kay# for a tool given its path. It takes two arguments:
208*cc277de8SChris Kay#
209*cc277de8SChris Kay#   - $(1): a list of candidate tool identifiers to check
210*cc277de8SChris Kay#   - $(2): the path to the tool to identify
211*cc277de8SChris Kay#
212*cc277de8SChris Kay# If any of the guess functions corresponding to candidate tool identifiers
213*cc277de8SChris Kay# return a non-empty value then the tool identifier of the first function to do
214*cc277de8SChris Kay# so is returned:
215*cc277de8SChris Kay#
216*cc277de8SChris Kay#     $(call guess-tool,gnu-gcc llvm-clang,armclang) # <empty>
217*cc277de8SChris Kay#     $(call guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang
218*cc277de8SChris Kay#     $(call guess-tool,gnu-gcc llvm-clang,aarch64-none-elf-gcc-12) # gnu-gcc
219*cc277de8SChris Kay#
220*cc277de8SChris Kay# Tools are checked in the order that they appear in `tools-$(tool-class)`, and
221*cc277de8SChris Kay# the first match is returned.
222*cc277de8SChris Kay#
223*cc277de8SChris Kay
224*cc277de8SChris Kay# Arm Compiler for Embedded
225*cc277de8SChris Kayguess-tool-arm-clang = $(shell $(1) --version 2>&1 | grep -o "Tool: armclang")
226*cc277de8SChris Kayguess-tool-arm-link = $(shell $(1) --help 2>&1 | grep -o "Tool: armlink")
227*cc277de8SChris Kayguess-tool-arm-fromelf = $(shell $(1) --help 2>&1 | grep -o "Tool: fromelf")
228*cc277de8SChris Kayguess-tool-arm-ar = $(shell $(1) --version 2>&1 | grep -o "Tool: armar")
229*cc277de8SChris Kay
230*cc277de8SChris Kay# LLVM Project
231*cc277de8SChris Kayguess-tool-llvm-clang = $(shell $(1) -v 2>&1 | grep -o "clang version")
232*cc277de8SChris Kayguess-tool-llvm-lld = $(shell $(1) --help 2>&1 | grep -o "OVERVIEW: lld")
233*cc277de8SChris Kayguess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 | grep -o "llvm-objcopy tool")
234*cc277de8SChris Kayguess-tool-llvm-objdump = $(shell $(1) --help 2>&1 | grep -o "llvm object file dumper")
235*cc277de8SChris Kayguess-tool-llvm-ar = $(shell $(1) --help 2>&1 | grep -o "LLVM Archiver")
236*cc277de8SChris Kay
237*cc277de8SChris Kay# GNU Compiler Collection & GNU Binary Utilities
238*cc277de8SChris Kayguess-tool-gnu-gcc = $(shell $(1) -v 2>&1 | grep -o "gcc version")
239*cc277de8SChris Kayguess-tool-gnu-ld = $(shell $(1) -v 2>&1 | grep -o "GNU ld")
240*cc277de8SChris Kayguess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 | grep -o "GNU objcopy")
241*cc277de8SChris Kayguess-tool-gnu-objdump = $(shell $(1) --version 2>&1 | grep -o "GNU objdump")
242*cc277de8SChris Kayguess-tool-gnu-ar = $(shell $(1) --version 2>&1 | grep -o "GNU ar")
243*cc277de8SChris Kay
244*cc277de8SChris Kay# Other tools
245*cc277de8SChris Kayguess-tool-dtc = $(shell $(1) --version 2>&1 | grep -o "Version: DTC")
246*cc277de8SChris Kay
247*cc277de8SChris Kayguess-tool = $(firstword $(foreach candidate,$(1), \
248*cc277de8SChris Kay        $(if $(call guess-tool-$(candidate),$(2)),$(candidate))))
249*cc277de8SChris Kay
250*cc277de8SChris Kay#
251*cc277de8SChris Kay# Locate and identify tools belonging to each toolchain.
252*cc277de8SChris Kay#
253*cc277de8SChris Kay# Each tool class in each toolchain receives a variable of the form
254*cc277de8SChris Kay# `$(toolchain)-$(tool)` giving the associated path to the program. For example:
255*cc277de8SChris Kay#
256*cc277de8SChris Kay#   - `aarch64-ld` gives the linker for the AArch64 toolchain,
257*cc277de8SChris Kay#   - `aarch32-oc` gives the object copier for the AArch32 toolchain, and
258*cc277de8SChris Kay#   - `host-cc` gives the C compiler for the host toolchain.
259*cc277de8SChris Kay#
260*cc277de8SChris Kay# For each of these variables, if no program path is explicitly provided by the
261*cc277de8SChris Kay# parent Makefile then the C compiler is queried (if supported) for its
262*cc277de8SChris Kay# location. This is done via the `guess-$(tool)-$(tool-class)` set of functions.
263*cc277de8SChris Kay# For example:
264*cc277de8SChris Kay#
265*cc277de8SChris Kay#   - `guess-arm-clang-ld` guesses the linker via Arm Clang,
266*cc277de8SChris Kay#   - `guess-llvm-clang-as` guesses the assembler via LLVM Clang, and
267*cc277de8SChris Kay#   - `guess-gnu-gcc-od` guesses the object dumper via GNU GCC.
268*cc277de8SChris Kay#
269*cc277de8SChris Kay# If the C compiler cannot provide the location (or the tool class is the C
270*cc277de8SChris Kay# compiler), then it is assigned the value of the `$(toolchain)-$(tool)-default`
271*cc277de8SChris Kay# variable.
272*cc277de8SChris Kay#
273*cc277de8SChris Kay
274*cc277de8SChris Kayguess-arm-clang-cpp = $(1) # Use the C compiler
275*cc277de8SChris Kayguess-arm-clang-as = $(1) # Use the C compiler
276*cc277de8SChris Kayguess-arm-clang-ld = # Fall back to `$(toolchain)-ld-default`
277*cc277de8SChris Kayguess-arm-clang-oc = # Fall back to `$(toolchain)-oc-default`
278*cc277de8SChris Kayguess-arm-clang-od = # Fall back to `$(toolchain)-od-default`
279*cc277de8SChris Kayguess-arm-clang-ar = # Fall back to `$(toolchain)-ar-default`
280*cc277de8SChris Kay
281*cc277de8SChris Kayguess-llvm-clang-cpp = $(1) # Use the C compiler
282*cc277de8SChris Kayguess-llvm-clang-as = $(1) # Use the C compiler
283*cc277de8SChris Kayguess-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>$(nul))
284*cc277de8SChris Kayguess-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>$(nul))
285*cc277de8SChris Kayguess-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>$(nul))
286*cc277de8SChris Kayguess-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>$(nul))
287*cc277de8SChris Kay
288*cc277de8SChris Kayguess-gnu-gcc-cpp = $(1) # Use the C compiler
289*cc277de8SChris Kayguess-gnu-gcc-as = $(1) # Use the C compiler
290*cc277de8SChris Kayguess-gnu-gcc-ld = $(if $(filter 1,$(ENABLE_LTO)),$(1),$(shell $(1) --print-prog-name ld.bfd 2>$(nul)))
291*cc277de8SChris Kayguess-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>$(nul))
292*cc277de8SChris Kayguess-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>$(nul))
293*cc277de8SChris Kayguess-gnu-gcc-ar = $(patsubst %$(notdir $(1)),%$(subst gcc,gcc-ar,$(notdir $(1))),$(1))
294*cc277de8SChris Kay
295*cc277de8SChris Kaydefine locate-toolchain-tool-cc
296*cc277de8SChris Kay        $(eval toolchain := $(1))
297*cc277de8SChris Kay
298*cc277de8SChris Kay        $(toolchain)-cc := $$(strip \
299*cc277de8SChris Kay                $$(or $$($(toolchain)-cc),$$($(toolchain)-cc-default)))
300*cc277de8SChris Kay        $(toolchain)-cc-id := $$(strip \
301*cc277de8SChris Kay                $$(call guess-tool,$$(tools-cc),$$($(toolchain)-cc)))
302*cc277de8SChris Kayendef
303*cc277de8SChris Kay
304*cc277de8SChris Kaydefine locate-toolchain-tool
305*cc277de8SChris Kay        $(eval toolchain := $(1))
306*cc277de8SChris Kay        $(eval tool-class := $(2))
307*cc277de8SChris Kay
308*cc277de8SChris Kay        ifndef $(toolchain)-$(tool-class)
309*cc277de8SChris Kay                $(toolchain)-$(tool-class) := $$(strip \
310*cc277de8SChris Kay                        $$(call guess-$$($(toolchain)-cc-id)-$(tool-class),$$($(toolchain)-cc)))
311*cc277de8SChris Kay
312*cc277de8SChris Kay                ifeq ($$($(toolchain)-$(tool-class)),)
313*cc277de8SChris Kay                        $(toolchain)-$(tool-class) := $$(strip \
314*cc277de8SChris Kay                                $$($(toolchain)-$(tool-class)-default))
315*cc277de8SChris Kay                endif
316*cc277de8SChris Kay        endif
317*cc277de8SChris Kay
318*cc277de8SChris Kay        $(toolchain)-$(tool-class)-id := $$(strip \
319*cc277de8SChris Kay                $$(call guess-tool,$$(tools-$(tool-class)),$$($$(toolchain)-$(tool-class))))
320*cc277de8SChris Kayendef
321*cc277de8SChris Kay
322*cc277de8SChris Kaydefine canonicalize-toolchain-tool-path
323*cc277de8SChris Kay        $(eval toolchain := $(1))
324*cc277de8SChris Kay        $(eval tool-class := $(2))
325*cc277de8SChris Kay
326*cc277de8SChris Kay        $(toolchain)-$(tool-class) := $$(strip $$(or \
327*cc277de8SChris Kay                $$(call which,$$($(toolchain)-$(tool-class))), \
328*cc277de8SChris Kay                $$($(toolchain)-$(tool-class))))
329*cc277de8SChris Kayendef
330*cc277de8SChris Kay
331*cc277de8SChris Kaydefine locate-toolchain
332*cc277de8SChris Kay        $(eval toolchain := $(1))
333*cc277de8SChris Kay
334*cc277de8SChris Kay        $$(eval $$(call locate-toolchain-tool-cc,$(toolchain)))
335*cc277de8SChris Kay        $$(eval $$(call canonicalize-toolchain-tool-path,$(toolchain),cc))
336*cc277de8SChris Kay
337*cc277de8SChris Kay        $$(foreach tool-class,$$(filter-out cc,$$(tool-classes)), \
338*cc277de8SChris Kay                $$(eval $$(call locate-toolchain-tool,$(toolchain),$$(tool-class))) \
339*cc277de8SChris Kay                $$(eval $$(call canonicalize-toolchain-tool-path,$(toolchain),$$(tool-class))))
340*cc277de8SChris Kayendef
341*cc277de8SChris Kay
342*cc277de8SChris Kay$(foreach toolchain,$(toolchains), \
343*cc277de8SChris Kay        $(eval $(call locate-toolchain,$(toolchain))))
344