1cc277de8SChris Kay# 2cc277de8SChris Kay# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved. 3cc277de8SChris Kay# 4cc277de8SChris Kay# SPDX-License-Identifier: BSD-3-Clause 5cc277de8SChris Kay# 6cc277de8SChris Kay 7cc277de8SChris Kay# 8cc277de8SChris Kay# TF-A uses three toolchains: 9cc277de8SChris Kay# 10cc277de8SChris Kay# - The host toolchain (`host`) for building native tools 11291e7182SChris Kay# - The AArch32 toolchain (`aarch32`) for building Arm AArch32 images 12cc277de8SChris Kay# - The AArch64 toolchain (`aarch64`) for building Arm AArch64 images 13cc277de8SChris Kay# 14cc277de8SChris Kay# In the main Makefile only one of the two Arm toolchains is enabled in any 15cc277de8SChris Kay# given build, but individual tools and libraries may need access to both. 16cc277de8SChris Kay# 17cc277de8SChris Kay 18291e7182SChris Kayifndef toolchain-mk 19291e7182SChris Kay toolchain-mk := $(lastword $(MAKEFILE_LIST)) 20291e7182SChris Kay 21cc277de8SChris Kay toolchains ?= host $(ARCH) 22cc277de8SChris Kay 23cc277de8SChris Kay include $(dir $(lastword $(MAKEFILE_LIST)))build_env.mk 244731c00bSChris Kay include $(dir $(lastword $(MAKEFILE_LIST)))utilities.mk 254731c00bSChris Kay 26cc277de8SChris Kay include $(addprefix $(dir $(lastword $(MAKEFILE_LIST)))toolchains/, \ 27cc277de8SChris Kay $(addsuffix .mk,$(toolchains))) 28cc277de8SChris Kay 29cc277de8SChris Kay # 30cc277de8SChris Kay # Configure tool classes that we recognize. 31cc277de8SChris Kay # 32291e7182SChris Kay # In the context of this build system, a tool class identifies a 33291e7182SChris Kay # specific role or type of tool in the toolchain. 34cc277de8SChris Kay # 35cc277de8SChris Kay 36*14260dbfSChris Kay toolchain-tool-classes := cc 37*14260dbfSChris Kay toolchain-tool-class-name-cc := C compiler 38cc277de8SChris Kay 39*14260dbfSChris Kay toolchain-tool-classes += cpp 40*14260dbfSChris Kay toolchain-tool-class-name-cpp := C preprocessor 41cc277de8SChris Kay 42*14260dbfSChris Kay toolchain-tool-classes += as 43*14260dbfSChris Kay toolchain-tool-class-name-as := assembler 44cc277de8SChris Kay 45*14260dbfSChris Kay toolchain-tool-classes += ld 46*14260dbfSChris Kay toolchain-tool-class-name-ld := linker 473d6c7e59SChris Kay 48*14260dbfSChris Kay toolchain-tool-classes += oc 49*14260dbfSChris Kay toolchain-tool-class-name-oc := object copier 503d6c7e59SChris Kay 51*14260dbfSChris Kay toolchain-tool-classes += od 52*14260dbfSChris Kay toolchain-tool-class-name-od := object dumper 533d6c7e59SChris Kay 54*14260dbfSChris Kay toolchain-tool-classes += ar 55*14260dbfSChris Kay toolchain-tool-class-name-ar := archiver 563d6c7e59SChris Kay 57*14260dbfSChris Kay toolchain-tool-classes += dtc 58*14260dbfSChris Kay toolchain-tool-class-name-dtc := device tree compiler 59cc277de8SChris Kay 60cc277de8SChris Kay # 61cc277de8SChris Kay # Configure tools that we recognize. 62cc277de8SChris Kay # 63291e7182SChris Kay # Here we declare the list of specific toolchain tools that we know how 64291e7182SChris Kay # to interact with. We don't organize these into tool classes yet - that 65291e7182SChris Kay # happens further down. 66cc277de8SChris Kay # 67cc277de8SChris Kay 68291e7182SChris Kay # Arm® Compiler for Embedded 69*14260dbfSChris Kay toolchain-tools := arm-clang 70*14260dbfSChris Kay toolchain-tool-name-arm-clang := Arm® Compiler for Embedded `armclang` 713d6c7e59SChris Kay 72*14260dbfSChris Kay toolchain-tools += arm-link 73*14260dbfSChris Kay toolchain-tool-name-arm-link := Arm® Compiler for Embedded `armlink` 743d6c7e59SChris Kay 75*14260dbfSChris Kay toolchain-tools += arm-ar 76*14260dbfSChris Kay toolchain-tool-name-arm-ar := Arm® Compiler for Embedded `armar` 773d6c7e59SChris Kay 78*14260dbfSChris Kay toolchain-tools += arm-fromelf 79*14260dbfSChris Kay toolchain-tool-name-arm-fromelf := Arm® Compiler for Embedded `fromelf` 80cc277de8SChris Kay 81cc277de8SChris Kay # LLVM Project 82*14260dbfSChris Kay toolchain-tools += llvm-clang 83*14260dbfSChris Kay toolchain-tool-name-llvm-clang := LLVM Clang (`clang`) 843d6c7e59SChris Kay 85*14260dbfSChris Kay toolchain-tools += llvm-lld 86*14260dbfSChris Kay toolchain-tool-name-llvm-lld := LLVM LLD (`lld`) 873d6c7e59SChris Kay 88*14260dbfSChris Kay toolchain-tools += llvm-objcopy 89*14260dbfSChris Kay toolchain-tool-name-llvm-objcopy := LLVM `llvm-objcopy` 903d6c7e59SChris Kay 91*14260dbfSChris Kay toolchain-tools += llvm-objdump 92*14260dbfSChris Kay toolchain-tool-name-llvm-objdump := LLVM `llvm-objdump` 933d6c7e59SChris Kay 94*14260dbfSChris Kay toolchain-tools += llvm-ar 95*14260dbfSChris Kay toolchain-tool-name-llvm-ar := LLVM `llvm-ar` 96cc277de8SChris Kay 97cc277de8SChris Kay # GNU Compiler Collection & GNU Binary Utilities 98*14260dbfSChris Kay toolchain-tools += gnu-gcc 99*14260dbfSChris Kay toolchain-tool-name-gnu-gcc := GNU GCC (`gcc`) 1003d6c7e59SChris Kay 101*14260dbfSChris Kay toolchain-tools += gnu-ld 102*14260dbfSChris Kay toolchain-tool-name-gnu-ld := GNU LD (`ld.bfd`) 1033d6c7e59SChris Kay 104*14260dbfSChris Kay toolchain-tools += gnu-objcopy 105*14260dbfSChris Kay toolchain-tool-name-gnu-objcopy := GNU `objcopy` 1063d6c7e59SChris Kay 107*14260dbfSChris Kay toolchain-tools += gnu-objdump 108*14260dbfSChris Kay toolchain-tool-name-gnu-objdump := GNU `objdump` 1093d6c7e59SChris Kay 110*14260dbfSChris Kay toolchain-tools += gnu-ar 111*14260dbfSChris Kay toolchain-tool-name-gnu-ar := GNU `ar` 112cc277de8SChris Kay 113cc277de8SChris Kay # Other tools 114*14260dbfSChris Kay toolchain-tools += generic-dtc 115*14260dbfSChris Kay toolchain-tool-name-generic-dtc := Device Tree Compiler (`dtc`) 116cc277de8SChris Kay 117cc277de8SChris Kay # 118cc277de8SChris Kay # Assign tools to tool classes. 119cc277de8SChris Kay # 120291e7182SChris Kay # Multifunctional tools, i.e. tools which can perform multiple roles in 121291e7182SChris Kay # a toolchain, may be specified in multiple tool class lists. For 122291e7182SChris Kay # example, a C compiler which can also perform the role of a linker may 123*14260dbfSChris Kay # be placed in both `toolchain-tools-cc` and `toolchain-tools-ld`. 124cc277de8SChris Kay # 125cc277de8SChris Kay 126cc277de8SChris Kay # C-related tools 127*14260dbfSChris Kay toolchain-tools-cc := arm-clang llvm-clang gnu-gcc # C compilers 128*14260dbfSChris Kay toolchain-tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors 129cc277de8SChris Kay 130cc277de8SChris Kay # Assembly-related tools 131*14260dbfSChris Kay toolchain-tools-as := arm-clang llvm-clang gnu-gcc # Assemblers 132cc277de8SChris Kay 133cc277de8SChris Kay # Linking and object-handling tools 134*14260dbfSChris Kay toolchain-tools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers 135*14260dbfSChris Kay toolchain-tools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers 136*14260dbfSChris Kay toolchain-tools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers 137*14260dbfSChris Kay toolchain-tools-ar := arm-ar llvm-ar gnu-ar # Archivers 138cc277de8SChris Kay 139cc277de8SChris Kay # Other tools 140*14260dbfSChris Kay toolchain-tools-dtc := generic-dtc # Device tree compilers 141cc277de8SChris Kay 142cc277de8SChris Kay # 143cc277de8SChris Kay # Default tools for each toolchain. 144cc277de8SChris Kay # 145291e7182SChris Kay # Toolchains can specify a default path to any given tool with a tool 146291e7182SChris Kay # class. These values are used in the absence of user-specified values, 147291e7182SChris Kay # and are configured by the makefile for each toolchain using variables 148291e7182SChris Kay # of the form: 149cc277de8SChris Kay # 150cc277de8SChris Kay # - $(toolchain)-$(tool-class)-default 151cc277de8SChris Kay # 152291e7182SChris Kay # For example, the default C compiler for the AArch32 and AArch64 153291e7182SChris Kay # toolchains could be configured with: 154cc277de8SChris Kay # 155cc277de8SChris Kay # - aarch32-cc-default 156cc277de8SChris Kay # - aarch64-cc-default 157cc277de8SChris Kay # 158cc277de8SChris Kay 159*14260dbfSChris Kay define toolchain-check-tool-class-default 160*14260dbfSChris Kay ifndef $(1)-$(tool-class)-default 161*14260dbfSChris Kay $$(error no default value specified for tool class `$(2)` of toolchain `$(1)`) 162cc277de8SChris Kay endif 163cc277de8SChris Kay endef 164cc277de8SChris Kay 165*14260dbfSChris Kay define toolchain-check-tool-class-defaults 166*14260dbfSChris Kay $(foreach tool-class,$(toolchain-tool-classes), \ 167*14260dbfSChris Kay $(eval $(call toolchain-check-tool-class-default,$(1),$(tool-class)))) 168cc277de8SChris Kay endef 169cc277de8SChris Kay 170cc277de8SChris Kay $(foreach toolchain,$(toolchains), \ 171*14260dbfSChris Kay $(eval $(call toolchain-check-tool-class-defaults,$(toolchain)))) 172cc277de8SChris Kay 173cc277de8SChris Kay # 174cc277de8SChris Kay # Helper functions to identify toolchain tools. 175cc277de8SChris Kay # 176291e7182SChris Kay # The functions defined in this section return a tool identifier when 177291e7182SChris Kay # given a path to a binary. We generally check a help or version string 178291e7182SChris Kay # to more reliably identify tools than by looking at the path alone 179291e7182SChris Kay # (e.g. `gcc` on macOS is actually Apple Clang). 180cc277de8SChris Kay # 181*14260dbfSChris Kay # Each tool-guessing function (`toolchain-guess-tool-$(tool)`) takes a 182*14260dbfSChris Kay # single argument giving the path to the tool to guess, and returns a 183*14260dbfSChris Kay # non-empty value if the tool corresponds to the tool identifier 184*14260dbfSChris Kay # `$(tool)`: 185cc277de8SChris Kay # 186*14260dbfSChris Kay # $(call toolchain-guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty> 187*14260dbfSChris Kay # $(call toolchain-guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty> 188cc277de8SChris Kay # 189*14260dbfSChris Kay # The `toolchain-guess-tool` function tries to find the corresponding tool 190291e7182SChris Kay # identifier for a tool given its path. It takes two arguments: 191cc277de8SChris Kay # 192cc277de8SChris Kay # - $(1): a list of candidate tool identifiers to check 193cc277de8SChris Kay # - $(2): the path to the tool to identify 194cc277de8SChris Kay # 195291e7182SChris Kay # If any of the guess functions corresponding to candidate tool 196291e7182SChris Kay # identifiers return a non-empty value then the tool identifier of the 197291e7182SChris Kay # first function to do so is returned: 198cc277de8SChris Kay # 199*14260dbfSChris Kay # $(call toolchain-guess-tool,gnu-gcc llvm-clang,armclang) # <empty> 200*14260dbfSChris Kay # $(call toolchain-guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang 201*14260dbfSChris Kay # $(call toolchain-guess-tool,gnu-gcc llvm-clang,aarch64-none-elf-gcc-12) # gnu-gcc 202cc277de8SChris Kay # 203*14260dbfSChris Kay # Tools are checked in the order that they are provided, and the first 204*14260dbfSChris Kay # match is returned. 205cc277de8SChris Kay # 206cc277de8SChris Kay 207cc277de8SChris Kay # Arm Compiler for Embedded 208*14260dbfSChris Kay toolchain-guess-tool-arm-clang = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armclang") 209*14260dbfSChris Kay toolchain-guess-tool-arm-link = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: armlink") 210*14260dbfSChris Kay toolchain-guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: fromelf") 211*14260dbfSChris Kay toolchain-guess-tool-arm-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armar") 212cc277de8SChris Kay 213cc277de8SChris Kay # LLVM Project 214*14260dbfSChris Kay toolchain-guess-tool-llvm-clang = $(shell $(1) -v 2>&1 <$(nul) | grep -o "clang version") 215*14260dbfSChris Kay toolchain-guess-tool-llvm-lld = $(shell $(1) --help 2>&1 <$(nul) | grep -o "OVERVIEW: lld") 216*14260dbfSChris Kay toolchain-guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm-objcopy tool") 217*14260dbfSChris Kay toolchain-guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm object file dumper") 218*14260dbfSChris Kay toolchain-guess-tool-llvm-ar = $(shell $(1) --help 2>&1 <$(nul) | grep -o "LLVM Archiver") 219cc277de8SChris Kay 220cc277de8SChris Kay # GNU Compiler Collection & GNU Binary Utilities 221*14260dbfSChris Kay toolchain-guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 <$(nul) | grep -o "gcc version") 222*14260dbfSChris Kay toolchain-guess-tool-gnu-ld = $(shell $(1) -v 2>&1 <$(nul) | grep -o "GNU ld") 223*14260dbfSChris Kay toolchain-guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objcopy") 224*14260dbfSChris Kay toolchain-guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objdump") 225*14260dbfSChris Kay toolchain-guess-tool-gnu-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU ar") 226cc277de8SChris Kay 227cc277de8SChris Kay # Other tools 228*14260dbfSChris Kay toolchain-guess-tool-generic-dtc = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Version: DTC") 229cc277de8SChris Kay 230*14260dbfSChris Kay toolchain-guess-tool = $(firstword $(foreach candidate,$(1), \ 231*14260dbfSChris Kay $(if $(call toolchain-guess-tool-$(candidate),$(2)),$(candidate)))) 232cc277de8SChris Kay 233cc277de8SChris Kay # 234cc277de8SChris Kay # Locate and identify tools belonging to each toolchain. 235cc277de8SChris Kay # 236cc277de8SChris Kay # Each tool class in each toolchain receives a variable of the form 237291e7182SChris Kay # `$(toolchain)-$(tool)` giving the associated path to the program. For 238291e7182SChris Kay # example: 239cc277de8SChris Kay # 240cc277de8SChris Kay # - `aarch64-ld` gives the linker for the AArch64 toolchain, 241cc277de8SChris Kay # - `aarch32-oc` gives the object copier for the AArch32 toolchain, and 242cc277de8SChris Kay # - `host-cc` gives the C compiler for the host toolchain. 243cc277de8SChris Kay # 244291e7182SChris Kay # For each of these variables, if no program path is explicitly provided 245291e7182SChris Kay # by the parent Makefile then the C compiler is queried (if supported) 246*14260dbfSChris Kay # for its location. 247cc277de8SChris Kay # 248*14260dbfSChris Kay # If the C compiler cannot provide the location (or the tool class *is* 249*14260dbfSChris Kay # the C compiler), then it is assigned a default value specific for that 250*14260dbfSChris Kay # toolchain. 251cc277de8SChris Kay # 252cc277de8SChris Kay 253*14260dbfSChris Kay toolchain-guess-arm-clang-cpp = $(1) 254*14260dbfSChris Kay toolchain-guess-arm-clang-as = $(1) 255*14260dbfSChris Kay toolchain-guess-arm-clang-ld = # Fall back to `$(toolchain)-ld-default` 256*14260dbfSChris Kay toolchain-guess-arm-clang-oc = # Fall back to `$(toolchain)-oc-default` 257*14260dbfSChris Kay toolchain-guess-arm-clang-od = # Fall back to `$(toolchain)-od-default` 258*14260dbfSChris Kay toolchain-guess-arm-clang-ar = # Fall back to `$(toolchain)-ar-default` 259cc277de8SChris Kay 260*14260dbfSChris Kay toolchain-guess-llvm-clang-cpp = $(1) 261*14260dbfSChris Kay toolchain-guess-llvm-clang-as = $(1) 262*14260dbfSChris Kay toolchain-guess-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>$(nul)) 263*14260dbfSChris Kay toolchain-guess-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>$(nul)) 264*14260dbfSChris Kay toolchain-guess-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>$(nul)) 265*14260dbfSChris Kay toolchain-guess-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>$(nul)) 266cc277de8SChris Kay 267*14260dbfSChris Kay toolchain-guess-gnu-gcc-cpp = $(1) 268*14260dbfSChris Kay toolchain-guess-gnu-gcc-as = $(1) 269*14260dbfSChris Kay toolchain-guess-gnu-gcc-ld = $(1) 270*14260dbfSChris Kay toolchain-guess-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>$(nul)) 271*14260dbfSChris Kay toolchain-guess-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>$(nul)) 272*14260dbfSChris Kay toolchain-guess-gnu-gcc-ar = $(shell $(1) --print-prog-name ar 2>$(nul)) 273cc277de8SChris Kay 274e01c7126SChris Kay define toolchain-warn-unrecognized 2753d6c7e59SChris Kay $$(warning ) 276*14260dbfSChris Kay $$(warning The configured $$($(1)-name) $$(toolchain-tool-class-name-$(2)) could not be identified and may not be supported:) 2773d6c7e59SChris Kay $$(warning ) 278e01c7126SChris Kay $$(warning $$(space) $$($(1)-$(2))) 2793d6c7e59SChris Kay $$(warning ) 280*14260dbfSChris Kay $$(warning The default $$($(1)-name) $$(toolchain-tool-class-name-$(2)) is:) 2813d6c7e59SChris Kay $$(warning ) 282e01c7126SChris Kay $$(warning $$(space) $$($(1)-$(2)-default)) 2833d6c7e59SChris Kay $$(warning ) 2843d6c7e59SChris Kay $$(warning The following tools are supported:) 2853d6c7e59SChris Kay $$(warning ) 2863d6c7e59SChris Kay 287*14260dbfSChris Kay $$(foreach tool,$$(toolchain-tools-$(2)), \ 288*14260dbfSChris Kay $$(warning $$(space) - $$(toolchain-tool-name-$$(tool)))) 2893d6c7e59SChris Kay 2903d6c7e59SChris Kay $$(warning ) 291*14260dbfSChris Kay $$(warning The build system will treat this $$(toolchain-tool-class-name-$(2)) as $$(toolchain-tool-name-$$($(1)-$(2)-id-default)).) 2923d6c7e59SChris Kay $$(warning ) 2933d6c7e59SChris Kay endef 2943d6c7e59SChris Kay 295e01c7126SChris Kay define toolchain-determine-tool 296e01c7126SChris Kay $(1)-$(2)-guess = $$(if $$(filter-out cc,$(2)),$\ 297*14260dbfSChris Kay $$(call toolchain-guess-$$($(1)-cc-id)-$(2),$$($(1)-cc))) 298cc277de8SChris Kay 299e01c7126SChris Kay $(1)-$(2) := $$(or $$($(1)-$(2)),$$($(1)-$(2)-guess)) 300e01c7126SChris Kay $(1)-$(2) := $$(or $$($(1)-$(2)),$$($(1)-$(2)-default)) 3013d6c7e59SChris Kay 302e01c7126SChris Kay ifneq ($$(call which,$$($(1)-$(2))),) 303e01c7126SChris Kay # If we can resolve this tool to a program on the `PATH` 304e01c7126SChris Kay # then escape it for use in a shell, which allows us to 305*14260dbfSChris Kay # preserve spaces. 3063d6c7e59SChris Kay 307e01c7126SChris Kay $(1)-$(2) := $$(call escape-shell,$$($(1)-$(2))) 3083d6c7e59SChris Kay endif 3093d6c7e59SChris Kay 310*14260dbfSChris Kay $(1)-$(2)-id := $$(call toolchain-guess-tool,$$(toolchain-tools-$(2)),$$($(1)-$(2))) 311e01c7126SChris Kay 312e01c7126SChris Kay ifndef $(1)-$(2)-id 313e01c7126SChris Kay $(1)-$(2)-id := $$($(1)-$(2)-id-default) 314e01c7126SChris Kay 315e01c7126SChris Kay $$(eval $$(call toolchain-warn-unrecognized,$(1),$(2))) 316e01c7126SChris Kay endif 317cc277de8SChris Kay endef 318cc277de8SChris Kay 319e01c7126SChris Kay define toolchain-determine 320*14260dbfSChris Kay $$(foreach tool-class,$$(toolchain-tool-classes), \ 321e01c7126SChris Kay $$(eval $$(call toolchain-determine-tool,$(1),$$(tool-class)))) 322cc277de8SChris Kay endef 323cc277de8SChris Kay 324cc277de8SChris Kay $(foreach toolchain,$(toolchains), \ 325e01c7126SChris Kay $(eval $(call toolchain-determine,$(toolchain)))) 326291e7182SChris Kayendif 327