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 363d6c7e59SChris Kay tool-classes := cc 373d6c7e59SChris Kay tool-class-name-cc := C compiler 38cc277de8SChris Kay 393d6c7e59SChris Kay tool-classes += cpp 403d6c7e59SChris Kay tool-class-name-cpp := C preprocessor 41cc277de8SChris Kay 423d6c7e59SChris Kay tool-classes += as 433d6c7e59SChris Kay tool-class-name-as := assembler 44cc277de8SChris Kay 453d6c7e59SChris Kay tool-classes += ld 463d6c7e59SChris Kay tool-class-name-ld := linker 473d6c7e59SChris Kay 483d6c7e59SChris Kay tool-classes += oc 493d6c7e59SChris Kay tool-class-name-oc := object copier 503d6c7e59SChris Kay 513d6c7e59SChris Kay tool-classes += od 523d6c7e59SChris Kay tool-class-name-od := object dumper 533d6c7e59SChris Kay 543d6c7e59SChris Kay tool-classes += ar 553d6c7e59SChris Kay tool-class-name-ar := archiver 563d6c7e59SChris Kay 573d6c7e59SChris Kay tool-classes += dtc 583d6c7e59SChris Kay 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 693d6c7e59SChris Kay tools := arm-clang 703d6c7e59SChris Kay tool-name-arm-clang := Arm® Compiler for Embedded `armclang` 713d6c7e59SChris Kay 723d6c7e59SChris Kay tools += arm-link 733d6c7e59SChris Kay tool-name-arm-link := Arm® Compiler for Embedded `armlink` 743d6c7e59SChris Kay 753d6c7e59SChris Kay tools += arm-ar 763d6c7e59SChris Kay tool-name-arm-ar := Arm® Compiler for Embedded `armar` 773d6c7e59SChris Kay 783d6c7e59SChris Kay tools += arm-fromelf 793d6c7e59SChris Kay tool-name-arm-fromelf := Arm® Compiler for Embedded `fromelf` 80cc277de8SChris Kay 81cc277de8SChris Kay # LLVM Project 823d6c7e59SChris Kay tools += llvm-clang 833d6c7e59SChris Kay tool-name-llvm-clang := LLVM Clang (`clang`) 843d6c7e59SChris Kay 853d6c7e59SChris Kay tools += llvm-lld 863d6c7e59SChris Kay tool-name-llvm-lld := LLVM LLD (`lld`) 873d6c7e59SChris Kay 883d6c7e59SChris Kay tools += llvm-objcopy 893d6c7e59SChris Kay tool-name-llvm-objcopy := LLVM `llvm-objcopy` 903d6c7e59SChris Kay 913d6c7e59SChris Kay tools += llvm-objdump 923d6c7e59SChris Kay tool-name-llvm-objdump := LLVM `llvm-objdump` 933d6c7e59SChris Kay 943d6c7e59SChris Kay tools += llvm-ar 953d6c7e59SChris Kay tool-name-llvm-ar := LLVM `llvm-ar` 96cc277de8SChris Kay 97cc277de8SChris Kay # GNU Compiler Collection & GNU Binary Utilities 983d6c7e59SChris Kay tools += gnu-gcc 993d6c7e59SChris Kay tool-name-gnu-gcc := GNU GCC (`gcc`) 1003d6c7e59SChris Kay 1013d6c7e59SChris Kay tools += gnu-ld 1023d6c7e59SChris Kay tool-name-gnu-ld := GNU LD (`ld.bfd`) 1033d6c7e59SChris Kay 1043d6c7e59SChris Kay tools += gnu-objcopy 1053d6c7e59SChris Kay tool-name-gnu-objcopy := GNU `objcopy` 1063d6c7e59SChris Kay 1073d6c7e59SChris Kay tools += gnu-objdump 1083d6c7e59SChris Kay tool-name-gnu-objdump := GNU `objdump` 1093d6c7e59SChris Kay 1103d6c7e59SChris Kay tools += gnu-ar 1113d6c7e59SChris Kay tool-name-gnu-ar := GNU `ar` 112cc277de8SChris Kay 113cc277de8SChris Kay # Other tools 1143d6c7e59SChris Kay tools += generic-dtc 1153d6c7e59SChris Kay 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 123291e7182SChris Kay # be placed in both `tools-cc` and `tools-ld`. 124cc277de8SChris Kay # 125cc277de8SChris Kay 126cc277de8SChris Kay # C-related tools 127cc277de8SChris Kay tools-cc := arm-clang llvm-clang gnu-gcc # C compilers 128cc277de8SChris Kay tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors 129cc277de8SChris Kay 130cc277de8SChris Kay # Assembly-related tools 131cc277de8SChris Kay tools-as := arm-clang llvm-clang gnu-gcc # Assemblers 132cc277de8SChris Kay 133cc277de8SChris Kay # Linking and object-handling tools 134cc277de8SChris Kay tools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers 135cc277de8SChris Kay tools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers 136cc277de8SChris Kay tools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers 137cc277de8SChris Kay tools-ar := arm-ar llvm-ar gnu-ar # Archivers 138cc277de8SChris Kay 139cc277de8SChris Kay # Other tools 1403d6c7e59SChris Kay tools-dtc := generic-dtc # Device tree compilers 141cc277de8SChris Kay 142cc277de8SChris Kay define check-tool-class-tools 143cc277de8SChris Kay $(eval tool-class := $(1)) 144cc277de8SChris Kay 145cc277de8SChris Kay ifndef tools-$(tool-class) 146cc277de8SChris Kay $$(error no tools registered to handle tool class `$(tool-class)`) 147cc277de8SChris Kay endif 148cc277de8SChris Kay endef 149cc277de8SChris Kay 150cc277de8SChris Kay $(foreach tool-class,$(tool-classes), \ 151cc277de8SChris Kay $(eval $(call check-tool-class-tools,$(tool-class)))) 152cc277de8SChris Kay 153cc277de8SChris Kay # 154cc277de8SChris Kay # Default tools for each toolchain. 155cc277de8SChris Kay # 156291e7182SChris Kay # Toolchains can specify a default path to any given tool with a tool 157291e7182SChris Kay # class. These values are used in the absence of user-specified values, 158291e7182SChris Kay # and are configured by the makefile for each toolchain using variables 159291e7182SChris Kay # of the form: 160cc277de8SChris Kay # 161cc277de8SChris Kay # - $(toolchain)-$(tool-class)-default 162cc277de8SChris Kay # 163291e7182SChris Kay # For example, the default C compiler for the AArch32 and AArch64 164291e7182SChris Kay # toolchains could be configured with: 165cc277de8SChris Kay # 166cc277de8SChris Kay # - aarch32-cc-default 167cc277de8SChris Kay # - aarch64-cc-default 168cc277de8SChris Kay # 169cc277de8SChris Kay 170cc277de8SChris Kay define check-toolchain-tool-class-default 171cc277de8SChris Kay $(eval toolchain := $(1)) 172cc277de8SChris Kay $(eval tool-class := $(2)) 173cc277de8SChris Kay 174cc277de8SChris Kay ifndef $(toolchain)-$(tool-class)-default 175cc277de8SChris Kay $$(error no default value specified for tool class `$(tool-class)` of toolchain `$(toolchain)`) 176cc277de8SChris Kay endif 177cc277de8SChris Kay endef 178cc277de8SChris Kay 179cc277de8SChris Kay define check-toolchain-tool-class-defaults 180cc277de8SChris Kay $(eval toolchain := $(1)) 181cc277de8SChris Kay 182cc277de8SChris Kay $(foreach tool-class,$(tool-classes), \ 183cc277de8SChris Kay $(eval $(call check-toolchain-tool-class-default,$(toolchain),$(tool-class)))) 184cc277de8SChris Kay endef 185cc277de8SChris Kay 186cc277de8SChris Kay $(foreach toolchain,$(toolchains), \ 187cc277de8SChris Kay $(eval $(call check-toolchain-tool-class-defaults,$(toolchain)))) 188cc277de8SChris Kay 189cc277de8SChris Kay # 190cc277de8SChris Kay # Helper functions to identify toolchain tools. 191cc277de8SChris Kay # 192291e7182SChris Kay # The functions defined in this section return a tool identifier when 193291e7182SChris Kay # given a path to a binary. We generally check a help or version string 194291e7182SChris Kay # to more reliably identify tools than by looking at the path alone 195291e7182SChris Kay # (e.g. `gcc` on macOS is actually Apple Clang). 196cc277de8SChris Kay # 197291e7182SChris Kay # Each tool-guessing function (`guess-tool-$(tool)`) takes a single 198291e7182SChris Kay # argument giving the path to the tool to guess, and returns a non-empty 199291e7182SChris Kay # value if the tool corresponds to the tool identifier `$(tool)`: 200cc277de8SChris Kay # 201cc277de8SChris Kay # $(call guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty> 202cc277de8SChris Kay # $(call guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty> 203cc277de8SChris Kay # 204291e7182SChris Kay # The `guess-tool` function tries to find the corresponding tool 205291e7182SChris Kay # identifier for a tool given its path. It takes two arguments: 206cc277de8SChris Kay # 207cc277de8SChris Kay # - $(1): a list of candidate tool identifiers to check 208cc277de8SChris Kay # - $(2): the path to the tool to identify 209cc277de8SChris Kay # 210291e7182SChris Kay # If any of the guess functions corresponding to candidate tool 211291e7182SChris Kay # identifiers return a non-empty value then the tool identifier of the 212291e7182SChris Kay # first function to do so is returned: 213cc277de8SChris Kay # 214cc277de8SChris Kay # $(call guess-tool,gnu-gcc llvm-clang,armclang) # <empty> 215cc277de8SChris Kay # $(call guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang 216cc277de8SChris Kay # $(call guess-tool,gnu-gcc llvm-clang,aarch64-none-elf-gcc-12) # gnu-gcc 217cc277de8SChris Kay # 218291e7182SChris Kay # Tools are checked in the order that they appear in 219291e7182SChris Kay # `tools-$(tool-class)`, and the first match is returned. 220cc277de8SChris Kay # 221cc277de8SChris Kay 222cc277de8SChris Kay # Arm Compiler for Embedded 223*e01c7126SChris Kay guess-tool-arm-clang = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armclang") 224*e01c7126SChris Kay guess-tool-arm-link = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: armlink") 225*e01c7126SChris Kay guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: fromelf") 226*e01c7126SChris Kay guess-tool-arm-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armar") 227cc277de8SChris Kay 228cc277de8SChris Kay # LLVM Project 229*e01c7126SChris Kay guess-tool-llvm-clang = $(shell $(1) -v 2>&1 <$(nul) | grep -o "clang version") 230*e01c7126SChris Kay guess-tool-llvm-lld = $(shell $(1) --help 2>&1 <$(nul) | grep -o "OVERVIEW: lld") 231*e01c7126SChris Kay guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm-objcopy tool") 232*e01c7126SChris Kay guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm object file dumper") 233*e01c7126SChris Kay guess-tool-llvm-ar = $(shell $(1) --help 2>&1 <$(nul) | grep -o "LLVM Archiver") 234cc277de8SChris Kay 235cc277de8SChris Kay # GNU Compiler Collection & GNU Binary Utilities 236*e01c7126SChris Kay guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 <$(nul) | grep -o "gcc version") 237*e01c7126SChris Kay guess-tool-gnu-ld = $(shell $(1) -v 2>&1 <$(nul) | grep -o "GNU ld") 238*e01c7126SChris Kay guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objcopy") 239*e01c7126SChris Kay guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objdump") 240*e01c7126SChris Kay guess-tool-gnu-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU ar") 241cc277de8SChris Kay 242cc277de8SChris Kay # Other tools 243*e01c7126SChris Kay guess-tool-generic-dtc = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Version: DTC") 244cc277de8SChris Kay 245cc277de8SChris Kay guess-tool = $(firstword $(foreach candidate,$(1), \ 246cc277de8SChris Kay $(if $(call guess-tool-$(candidate),$(2)),$(candidate)))) 247cc277de8SChris Kay 248cc277de8SChris Kay # 249cc277de8SChris Kay # Locate and identify tools belonging to each toolchain. 250cc277de8SChris Kay # 251cc277de8SChris Kay # Each tool class in each toolchain receives a variable of the form 252291e7182SChris Kay # `$(toolchain)-$(tool)` giving the associated path to the program. For 253291e7182SChris Kay # example: 254cc277de8SChris Kay # 255cc277de8SChris Kay # - `aarch64-ld` gives the linker for the AArch64 toolchain, 256cc277de8SChris Kay # - `aarch32-oc` gives the object copier for the AArch32 toolchain, and 257cc277de8SChris Kay # - `host-cc` gives the C compiler for the host toolchain. 258cc277de8SChris Kay # 259291e7182SChris Kay # For each of these variables, if no program path is explicitly provided 260291e7182SChris Kay # by the parent Makefile then the C compiler is queried (if supported) 261291e7182SChris Kay # for its location. This is done via the `guess-$(tool)-$(tool-class)` 262291e7182SChris Kay # set of functions. For example: 263cc277de8SChris Kay # 264cc277de8SChris Kay # - `guess-arm-clang-ld` guesses the linker via Arm Clang, 265cc277de8SChris Kay # - `guess-llvm-clang-as` guesses the assembler via LLVM Clang, and 266cc277de8SChris Kay # - `guess-gnu-gcc-od` guesses the object dumper via GNU GCC. 267cc277de8SChris Kay # 268291e7182SChris Kay # If the C compiler cannot provide the location (or the tool class is 269291e7182SChris Kay # the C compiler), then it is assigned the value of the 270291e7182SChris Kay # `$(toolchain)-$(tool)-default` variable. 271cc277de8SChris Kay # 272cc277de8SChris Kay 2734731c00bSChris Kay guess-arm-clang-cpp = $(1) 2744731c00bSChris Kay guess-arm-clang-as = $(1) 275cc277de8SChris Kay guess-arm-clang-ld = # Fall back to `$(toolchain)-ld-default` 276cc277de8SChris Kay guess-arm-clang-oc = # Fall back to `$(toolchain)-oc-default` 277cc277de8SChris Kay guess-arm-clang-od = # Fall back to `$(toolchain)-od-default` 278cc277de8SChris Kay guess-arm-clang-ar = # Fall back to `$(toolchain)-ar-default` 279cc277de8SChris Kay 2804731c00bSChris Kay guess-llvm-clang-cpp = $(1) 2814731c00bSChris Kay guess-llvm-clang-as = $(1) 282*e01c7126SChris Kay guess-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>$(nul)) 283*e01c7126SChris Kay guess-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>$(nul)) 284*e01c7126SChris Kay guess-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>$(nul)) 285*e01c7126SChris Kay guess-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>$(nul)) 286cc277de8SChris Kay 2874731c00bSChris Kay guess-gnu-gcc-cpp = $(1) 2884731c00bSChris Kay guess-gnu-gcc-as = $(1) 2894731c00bSChris Kay guess-gnu-gcc-ld = $(1) 290*e01c7126SChris Kay guess-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>$(nul)) 291*e01c7126SChris Kay guess-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>$(nul)) 2924731c00bSChris Kay guess-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))))) 293cc277de8SChris Kay 294*e01c7126SChris Kay define toolchain-warn-unrecognized 2953d6c7e59SChris Kay $$(warning ) 296*e01c7126SChris Kay $$(warning The configured $$($(1)-name) $$(tool-class-name-$(2)) could not be identified and may not be supported:) 2973d6c7e59SChris Kay $$(warning ) 298*e01c7126SChris Kay $$(warning $$(space) $$($(1)-$(2))) 2993d6c7e59SChris Kay $$(warning ) 300*e01c7126SChris Kay $$(warning The default $$($(1)-name) $$(tool-class-name-$(2)) is:) 3013d6c7e59SChris Kay $$(warning ) 302*e01c7126SChris Kay $$(warning $$(space) $$($(1)-$(2)-default)) 3033d6c7e59SChris Kay $$(warning ) 3043d6c7e59SChris Kay $$(warning The following tools are supported:) 3053d6c7e59SChris Kay $$(warning ) 3063d6c7e59SChris Kay 307*e01c7126SChris Kay $$(foreach tool,$$(tools-$(2)), \ 3083d6c7e59SChris Kay $$(warning $$(space) - $$(tool-name-$$(tool)))) 3093d6c7e59SChris Kay 3103d6c7e59SChris Kay $$(warning ) 311*e01c7126SChris Kay $$(warning The build system will treat this $$(tool-class-name-$(2)) as $$(tool-name-$$($(1)-$(2)-id-default)).) 3123d6c7e59SChris Kay $$(warning ) 3133d6c7e59SChris Kay endef 3143d6c7e59SChris Kay 315*e01c7126SChris Kay define toolchain-determine-tool 316*e01c7126SChris Kay $(1)-$(2)-guess = $$(if $$(filter-out cc,$(2)),$\ 317*e01c7126SChris Kay $$(call guess-$$($(1)-cc-id)-$(2),$$($(1)-cc))) 318cc277de8SChris Kay 319*e01c7126SChris Kay $(1)-$(2) := $$(or $$($(1)-$(2)),$$($(1)-$(2)-guess)) 320*e01c7126SChris Kay $(1)-$(2) := $$(or $$($(1)-$(2)),$$($(1)-$(2)-default)) 3213d6c7e59SChris Kay 322*e01c7126SChris Kay ifneq ($$(call which,$$($(1)-$(2))),) 323*e01c7126SChris Kay # If we can resolve this tool to a program on the `PATH` 324*e01c7126SChris Kay # then escape it for use in a shell, which allows us to 325*e01c7126SChris Kay # preserve spaces. 3263d6c7e59SChris Kay 327*e01c7126SChris Kay $(1)-$(2) := $$(call escape-shell,$$($(1)-$(2))) 3283d6c7e59SChris Kay endif 3293d6c7e59SChris Kay 330*e01c7126SChris Kay $(1)-$(2)-id := $$(call guess-tool,$$(tools-$(2)),$$($(1)-$(2))) 331*e01c7126SChris Kay 332*e01c7126SChris Kay ifndef $(1)-$(2)-id 333*e01c7126SChris Kay $(1)-$(2)-id := $$($(1)-$(2)-id-default) 334*e01c7126SChris Kay 335*e01c7126SChris Kay $$(eval $$(call toolchain-warn-unrecognized,$(1),$(2))) 336*e01c7126SChris Kay endif 337cc277de8SChris Kay endef 338cc277de8SChris Kay 339*e01c7126SChris Kay define toolchain-determine 340*e01c7126SChris Kay $$(foreach tool-class,$$(tool-classes), \ 341*e01c7126SChris Kay $$(eval $$(call toolchain-determine-tool,$(1),$$(tool-class)))) 342cc277de8SChris Kay endef 343cc277de8SChris Kay 344cc277de8SChris Kay $(foreach toolchain,$(toolchains), \ 345*e01c7126SChris Kay $(eval $(call toolchain-determine,$(toolchain)))) 346291e7182SChris Kayendif 347