1cc277de8SChris Kay# 2c3273703SChris Kay# Copyright (c) 2023-2025, 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 213789c3c0SChris Kay include $(dir $(toolchain-mk))utilities.mk 22cc277de8SChris Kay 233789c3c0SChris Kay # 243789c3c0SChris Kay # Make assigns generic default values to `CC`, `CPP`, `AS`, etc. if they 253789c3c0SChris Kay # are not explicitly assigned values by the user. These are usually okay 263789c3c0SChris Kay # for very simple programs when building for the host system, but we 273789c3c0SChris Kay # need greater control over the toolchain flow. 283789c3c0SChris Kay # 293789c3c0SChris Kay # Therefore, we undefine these built-in variables if they have default 303789c3c0SChris Kay # values, so that we can provide our own default values later instead. 313789c3c0SChris Kay # 324731c00bSChris Kay 333789c3c0SChris Kay ifeq ($(origin CC),default) 343789c3c0SChris Kay undefine CC 353789c3c0SChris Kay endif 363789c3c0SChris Kay 373789c3c0SChris Kay ifeq ($(origin CPP),default) 383789c3c0SChris Kay undefine CPP 393789c3c0SChris Kay endif 403789c3c0SChris Kay 413789c3c0SChris Kay ifeq ($(origin AS),default) 423789c3c0SChris Kay undefine AS 433789c3c0SChris Kay endif 443789c3c0SChris Kay 453789c3c0SChris Kay ifeq ($(origin AR),default) 463789c3c0SChris Kay undefine AR 473789c3c0SChris Kay endif 483789c3c0SChris Kay 493789c3c0SChris Kay ifeq ($(origin LD),default) 503789c3c0SChris Kay undefine LD 513789c3c0SChris Kay endif 523789c3c0SChris Kay 533789c3c0SChris Kay # 543789c3c0SChris Kay # The full list of toolchains supported by TF-A. 553789c3c0SChris Kay # 563789c3c0SChris Kay # Each of these toolchains defines a file of the same name in the 573789c3c0SChris Kay # `toolchains` directory, which must configure the following variables: 583789c3c0SChris Kay # 593789c3c0SChris Kay # - <toolchain>-name 603789c3c0SChris Kay # 613789c3c0SChris Kay # A human-readable name for the toolchain, 623789c3c0SChris Kay # 633789c3c0SChris Kay # Additionally, for every tool class, it must also define: 643789c3c0SChris Kay # 653789c3c0SChris Kay # - <toolchain>-<tool-class>-parameter 663789c3c0SChris Kay # 673789c3c0SChris Kay # The command line or environment variable used to set the tool for 683789c3c0SChris Kay # for the given tool class. 693789c3c0SChris Kay # 709cea2c36SChris Kay # - <toolchain>-<tool-class>-default-id 713789c3c0SChris Kay # 723789c3c0SChris Kay # The default tool identifier used if the tool for the given tool 733789c3c0SChris Kay # class cannot be identified. 743789c3c0SChris Kay # 759cea2c36SChris Kay # - <toolchain>-<tool-class>-default 769cea2c36SChris Kay # 779cea2c36SChris Kay # The default commands to try, in the order defined, for the given 789cea2c36SChris Kay # tool class if the user does not explicitly provide one, and if the 799cea2c36SChris Kay # command could not be derived from the C compiler. 809cea2c36SChris Kay # 813789c3c0SChris Kay 823789c3c0SChris Kay toolchains := host # Used for host targets 833789c3c0SChris Kay toolchains += aarch32 # Used for AArch32 targets 843789c3c0SChris Kay toolchains += aarch64 # Used for AArch64 targets 853789c3c0SChris Kay toolchains += rk3399-m0 # Used for RK3399 Cortex-M0 targets 863789c3c0SChris Kay 873789c3c0SChris Kay include $(toolchains:%=$(dir $(toolchain-mk))toolchains/%.mk) 88cc277de8SChris Kay 89cc277de8SChris Kay # 90cc277de8SChris Kay # Configure tool classes that we recognize. 91cc277de8SChris Kay # 92291e7182SChris Kay # In the context of this build system, a tool class identifies a 93291e7182SChris Kay # specific role or type of tool in the toolchain. 94cc277de8SChris Kay # 95cc277de8SChris Kay 9614260dbfSChris Kay toolchain-tool-classes := cc 9714260dbfSChris Kay toolchain-tool-class-name-cc := C compiler 98cc277de8SChris Kay 9914260dbfSChris Kay toolchain-tool-classes += cpp 10014260dbfSChris Kay toolchain-tool-class-name-cpp := C preprocessor 101cc277de8SChris Kay 10214260dbfSChris Kay toolchain-tool-classes += as 10314260dbfSChris Kay toolchain-tool-class-name-as := assembler 104cc277de8SChris Kay 10514260dbfSChris Kay toolchain-tool-classes += ld 10614260dbfSChris Kay toolchain-tool-class-name-ld := linker 1073d6c7e59SChris Kay 10814260dbfSChris Kay toolchain-tool-classes += oc 10914260dbfSChris Kay toolchain-tool-class-name-oc := object copier 1103d6c7e59SChris Kay 11114260dbfSChris Kay toolchain-tool-classes += od 11214260dbfSChris Kay toolchain-tool-class-name-od := object dumper 1133d6c7e59SChris Kay 11414260dbfSChris Kay toolchain-tool-classes += ar 11514260dbfSChris Kay toolchain-tool-class-name-ar := archiver 1163d6c7e59SChris Kay 11714260dbfSChris Kay toolchain-tool-classes += dtc 11814260dbfSChris Kay toolchain-tool-class-name-dtc := device tree compiler 119cc277de8SChris Kay 120d2867397SChris Kay toolchain-tool-classes += poetry 121d2867397SChris Kay toolchain-tool-class-name-poetry := Python Poetry package manager 122d2867397SChris Kay 123cc277de8SChris Kay # 124cc277de8SChris Kay # Configure tools that we recognize. 125cc277de8SChris Kay # 126291e7182SChris Kay # Here we declare the list of specific toolchain tools that we know how 127291e7182SChris Kay # to interact with. We don't organize these into tool classes yet - that 128291e7182SChris Kay # happens further down. 129cc277de8SChris Kay # 130cc277de8SChris Kay 131291e7182SChris Kay # Arm® Compiler for Embedded 13214260dbfSChris Kay toolchain-tools := arm-clang 13314260dbfSChris Kay toolchain-tool-name-arm-clang := Arm® Compiler for Embedded `armclang` 1343d6c7e59SChris Kay 13514260dbfSChris Kay toolchain-tools += arm-link 13614260dbfSChris Kay toolchain-tool-name-arm-link := Arm® Compiler for Embedded `armlink` 1373d6c7e59SChris Kay 13814260dbfSChris Kay toolchain-tools += arm-ar 13914260dbfSChris Kay toolchain-tool-name-arm-ar := Arm® Compiler for Embedded `armar` 1403d6c7e59SChris Kay 14114260dbfSChris Kay toolchain-tools += arm-fromelf 14214260dbfSChris Kay toolchain-tool-name-arm-fromelf := Arm® Compiler for Embedded `fromelf` 143cc277de8SChris Kay 144cc277de8SChris Kay # LLVM Project 14514260dbfSChris Kay toolchain-tools += llvm-clang 14614260dbfSChris Kay toolchain-tool-name-llvm-clang := LLVM Clang (`clang`) 1473d6c7e59SChris Kay 14814260dbfSChris Kay toolchain-tools += llvm-lld 14914260dbfSChris Kay toolchain-tool-name-llvm-lld := LLVM LLD (`lld`) 1503d6c7e59SChris Kay 15114260dbfSChris Kay toolchain-tools += llvm-objcopy 15214260dbfSChris Kay toolchain-tool-name-llvm-objcopy := LLVM `llvm-objcopy` 1533d6c7e59SChris Kay 15414260dbfSChris Kay toolchain-tools += llvm-objdump 15514260dbfSChris Kay toolchain-tool-name-llvm-objdump := LLVM `llvm-objdump` 1563d6c7e59SChris Kay 15714260dbfSChris Kay toolchain-tools += llvm-ar 15814260dbfSChris Kay toolchain-tool-name-llvm-ar := LLVM `llvm-ar` 159cc277de8SChris Kay 160cc277de8SChris Kay # GNU Compiler Collection & GNU Binary Utilities 16114260dbfSChris Kay toolchain-tools += gnu-gcc 16214260dbfSChris Kay toolchain-tool-name-gnu-gcc := GNU GCC (`gcc`) 1633d6c7e59SChris Kay 16414260dbfSChris Kay toolchain-tools += gnu-ld 16514260dbfSChris Kay toolchain-tool-name-gnu-ld := GNU LD (`ld.bfd`) 1663d6c7e59SChris Kay 16714260dbfSChris Kay toolchain-tools += gnu-objcopy 16814260dbfSChris Kay toolchain-tool-name-gnu-objcopy := GNU `objcopy` 1693d6c7e59SChris Kay 17014260dbfSChris Kay toolchain-tools += gnu-objdump 17114260dbfSChris Kay toolchain-tool-name-gnu-objdump := GNU `objdump` 1723d6c7e59SChris Kay 17314260dbfSChris Kay toolchain-tools += gnu-ar 17414260dbfSChris Kay toolchain-tool-name-gnu-ar := GNU `ar` 175cc277de8SChris Kay 176cc277de8SChris Kay # Other tools 17714260dbfSChris Kay toolchain-tools += generic-dtc 17814260dbfSChris Kay toolchain-tool-name-generic-dtc := Device Tree Compiler (`dtc`) 179cc277de8SChris Kay 180d2867397SChris Kay toolchain-tools += generic-poetry 181d2867397SChris Kay toolchain-tool-name-generic-poetry := Poetry (`poetry`) 182d2867397SChris Kay 183cc277de8SChris Kay # 184cc277de8SChris Kay # Assign tools to tool classes. 185cc277de8SChris Kay # 186291e7182SChris Kay # Multifunctional tools, i.e. tools which can perform multiple roles in 187291e7182SChris Kay # a toolchain, may be specified in multiple tool class lists. For 188291e7182SChris Kay # example, a C compiler which can also perform the role of a linker may 18914260dbfSChris Kay # be placed in both `toolchain-tools-cc` and `toolchain-tools-ld`. 190cc277de8SChris Kay # 191cc277de8SChris Kay 192cc277de8SChris Kay # C-related tools 19314260dbfSChris Kay toolchain-tools-cc := arm-clang llvm-clang gnu-gcc # C compilers 19414260dbfSChris Kay toolchain-tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors 195cc277de8SChris Kay 196cc277de8SChris Kay # Assembly-related tools 19714260dbfSChris Kay toolchain-tools-as := arm-clang llvm-clang gnu-gcc # Assemblers 198cc277de8SChris Kay 199cc277de8SChris Kay # Linking and object-handling tools 20014260dbfSChris Kay toolchain-tools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers 20114260dbfSChris Kay toolchain-tools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers 20214260dbfSChris Kay toolchain-tools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers 20314260dbfSChris Kay toolchain-tools-ar := arm-ar llvm-ar gnu-ar # Archivers 204cc277de8SChris Kay 205cc277de8SChris Kay # Other tools 20614260dbfSChris Kay toolchain-tools-dtc := generic-dtc # Device tree compilers 207d2867397SChris Kay toolchain-tools-poetry := generic-poetry # Python Poetry package manager 208cc277de8SChris Kay 209cc277de8SChris Kay # 210cc277de8SChris Kay # Helper functions to identify toolchain tools. 211cc277de8SChris Kay # 212291e7182SChris Kay # The functions defined in this section return a tool identifier when 213291e7182SChris Kay # given a path to a binary. We generally check a help or version string 214291e7182SChris Kay # to more reliably identify tools than by looking at the path alone 215291e7182SChris Kay # (e.g. `gcc` on macOS is actually Apple Clang). 216cc277de8SChris Kay # 21714260dbfSChris Kay # Each tool-guessing function (`toolchain-guess-tool-$(tool)`) takes a 21814260dbfSChris Kay # single argument giving the path to the tool to guess, and returns a 21914260dbfSChris Kay # non-empty value if the tool corresponds to the tool identifier 22014260dbfSChris Kay # `$(tool)`: 221cc277de8SChris Kay # 22214260dbfSChris Kay # $(call toolchain-guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty> 22314260dbfSChris Kay # $(call toolchain-guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty> 224cc277de8SChris Kay # 22514260dbfSChris Kay # The `toolchain-guess-tool` function tries to find the corresponding tool 226291e7182SChris Kay # identifier for a tool given its path. It takes two arguments: 227cc277de8SChris Kay # 228cc277de8SChris Kay # - $(1): a list of candidate tool identifiers to check 229cc277de8SChris Kay # - $(2): the path to the tool to identify 230cc277de8SChris Kay # 231291e7182SChris Kay # If any of the guess functions corresponding to candidate tool 232291e7182SChris Kay # identifiers return a non-empty value then the tool identifier of the 233291e7182SChris Kay # first function to do so is returned: 234cc277de8SChris Kay # 23514260dbfSChris Kay # $(call toolchain-guess-tool,gnu-gcc llvm-clang,armclang) # <empty> 23614260dbfSChris Kay # $(call toolchain-guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang 23714260dbfSChris Kay # $(call toolchain-guess-tool,gnu-gcc llvm-clang,aarch64-none-elf-gcc-12) # gnu-gcc 238cc277de8SChris Kay # 23914260dbfSChris Kay # Tools are checked in the order that they are provided, and the first 24014260dbfSChris Kay # match is returned. 241cc277de8SChris Kay # 242cc277de8SChris Kay 243cc277de8SChris Kay # Arm Compiler for Embedded 244c3273703SChris Kay toolchain-guess-tool-arm-clang = $(shell $(1) --version 2>&1 </dev/null | grep -o "Tool: armclang") 245c3273703SChris Kay toolchain-guess-tool-arm-link = $(shell $(1) --help 2>&1 </dev/null | grep -o "Tool: armlink") 246c3273703SChris Kay toolchain-guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 </dev/null | grep -o "Tool: fromelf") 247c3273703SChris Kay toolchain-guess-tool-arm-ar = $(shell $(1) --version 2>&1 </dev/null | grep -o "Tool: armar") 248cc277de8SChris Kay 249cc277de8SChris Kay # LLVM Project 250c3273703SChris Kay toolchain-guess-tool-llvm-clang = $(shell $(1) -v 2>&1 </dev/null | grep -o "clang version") 251c3273703SChris Kay toolchain-guess-tool-llvm-lld = $(shell $(1) --help 2>&1 </dev/null | grep -o "OVERVIEW: lld") 252c3273703SChris Kay toolchain-guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 </dev/null | grep -o "llvm-objcopy tool") 253c3273703SChris Kay toolchain-guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 </dev/null | grep -o "llvm object file dumper") 254c3273703SChris Kay toolchain-guess-tool-llvm-ar = $(shell $(1) --help 2>&1 </dev/null | grep -o "LLVM Archiver") 255cc277de8SChris Kay 256cc277de8SChris Kay # GNU Compiler Collection & GNU Binary Utilities 257c3273703SChris Kay toolchain-guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 </dev/null | grep -o "gcc version") 258c3273703SChris Kay toolchain-guess-tool-gnu-ld = $(shell $(1) -v 2>&1 </dev/null | grep -o "GNU ld") 259c3273703SChris Kay toolchain-guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 </dev/null | grep -o "GNU objcopy") 260c3273703SChris Kay toolchain-guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 </dev/null | grep -o "GNU objdump") 261c3273703SChris Kay toolchain-guess-tool-gnu-ar = $(shell $(1) --version 2>&1 </dev/null | grep -o "GNU ar") 262cc277de8SChris Kay 263cc277de8SChris Kay # Other tools 264c3273703SChris Kay toolchain-guess-tool-generic-dtc = $(shell $(1) --version 2>&1 </dev/null | grep -o "Version: DTC") 265c3273703SChris Kay toolchain-guess-tool-generic-poetry = $(shell $(1) --version 2>&1 </dev/null) 266cc277de8SChris Kay 267d2867397SChris Kay toolchain-guess-tool = $(if $(2),$(firstword $(foreach candidate,$(1),$\ 268d2867397SChris Kay $(if $(call toolchain-guess-tool-$(candidate),$(2)),$(candidate))))) 269cc277de8SChris Kay 270cc277de8SChris Kay # 271*5c24052aSChris Kay # Get the index of the first valid tool path in a shell command. 272*5c24052aSChris Kay # 273*5c24052aSChris Kay # To support compiler wrappers like `ccache`, we need to be able to 274*5c24052aSChris Kay # robustly identify which part of a shell command is the wrapper and 275*5c24052aSChris Kay # which part is the wrapped. 276*5c24052aSChris Kay # 277*5c24052aSChris Kay # To do this, we iterate through each shell word in the string, query it 278*5c24052aSChris Kay # to see if it is one the tools we would expect to see, and return its 279*5c24052aSChris Kay # index. 280*5c24052aSChris Kay # 281*5c24052aSChris Kay # - $(1): A list of candidate tool identifiers to check. 282*5c24052aSChris Kay # - $(2): The shell command to parse. 283*5c24052aSChris Kay # 284*5c24052aSChris Kay 285*5c24052aSChris Kay toolchain-tool-program-index = $(or $(firstword $\ 286*5c24052aSChris Kay $(foreach i,$(call irange,$(call shell-words,$(2))),$\ 287*5c24052aSChris Kay $(and $(call which,$(call shell-word,$(i),$(2))),$\ 288*5c24052aSChris Kay $(call toolchain-guess-tool,$(1),$\ 289*5c24052aSChris Kay $(call shell-word,$(i),$(2))),$\ 290*5c24052aSChris Kay $(i)))),1) 291*5c24052aSChris Kay 292*5c24052aSChris Kay # 293*5c24052aSChris Kay # Strip any program wrappers from a tool's shell command. 294*5c24052aSChris Kay # 295*5c24052aSChris Kay # This function removes any program wrappers, like `ccache`, from the 296*5c24052aSChris Kay # shell command of a tool. 297*5c24052aSChris Kay # 298*5c24052aSChris Kay # - $(1): A list of candidate tool identifiers to check. 299*5c24052aSChris Kay # - $(2): The shell command to parse. 300*5c24052aSChris Kay # 301*5c24052aSChris Kay 302*5c24052aSChris Kay toolchain-tool-program = $(call shell-slice,$(2),$\ 303*5c24052aSChris Kay $(call toolchain-tool-program-index,$(1),$(2))) 304*5c24052aSChris Kay 305*5c24052aSChris Kay # 306*5c24052aSChris Kay # Extract the program wrapper from a tool's shell command. 307*5c24052aSChris Kay # 308*5c24052aSChris Kay # This function returns any program wrappers, like `ccache`, from the 309*5c24052aSChris Kay # shell command of a tool. 310*5c24052aSChris Kay # 311*5c24052aSChris Kay # - $(1): A list of candidate tool identifiers to check. 312*5c24052aSChris Kay # - $(2): The shell command to parse. 313*5c24052aSChris Kay # 314*5c24052aSChris Kay 315*5c24052aSChris Kay toolchain-tool-wrapper = $(call shell-slice,$(2),1,$\ 316*5c24052aSChris Kay $(call toolchain-tool-program-index,$(1),$(2))) 317*5c24052aSChris Kay 318*5c24052aSChris Kay # 3193789c3c0SChris Kay # Warn the user that a tool could not be identified. 3203789c3c0SChris Kay # 3213789c3c0SChris Kay # Parameters: 3223789c3c0SChris Kay # 3233789c3c0SChris Kay # - $1: The toolchain that the tool belongs to. 3243789c3c0SChris Kay # - $2: The tool class that the tool belongs to. 3253789c3c0SChris Kay # 3263789c3c0SChris Kay 3273789c3c0SChris Kay define toolchain-warn-unrecognized 3283789c3c0SChris Kay $(warning ) 3299cea2c36SChris Kay $(warning The configured $($(1)-name) $(toolchain-tool-class-name-$(2)) could not be identified:) 3303789c3c0SChris Kay $(warning ) 33193f45539SChris Kay $(warning $(space) $($(1)-$(2)) ($($(1)-$(2)-origin))) 3329cea2c36SChris Kay 3333789c3c0SChris Kay $(warning ) 3343789c3c0SChris Kay $(warning The following tools are supported:) 3353789c3c0SChris Kay $(warning ) 3363789c3c0SChris Kay 3373789c3c0SChris Kay $(foreach tool,$(toolchain-tools-$(2)), \ 3383789c3c0SChris Kay $(warning $(space) - $(toolchain-tool-name-$(tool)))) 3393789c3c0SChris Kay 3403789c3c0SChris Kay $(warning ) 3419cea2c36SChris Kay $(warning The build system will treat this $(toolchain-tool-class-name-$(2)) as $(toolchain-tool-name-$($(1)-$(2)-default-id)).) 3423789c3c0SChris Kay $(warning ) 3433789c3c0SChris Kay endef 3443789c3c0SChris Kay 3453789c3c0SChris Kay # 346cc277de8SChris Kay # Locate and identify tools belonging to each toolchain. 347cc277de8SChris Kay # 348cc277de8SChris Kay # Each tool class in each toolchain receives a variable of the form 349291e7182SChris Kay # `$(toolchain)-$(tool)` giving the associated path to the program. For 350291e7182SChris Kay # example: 351cc277de8SChris Kay # 352cc277de8SChris Kay # - `aarch64-ld` gives the linker for the AArch64 toolchain, 353cc277de8SChris Kay # - `aarch32-oc` gives the object copier for the AArch32 toolchain, and 354cc277de8SChris Kay # - `host-cc` gives the C compiler for the host toolchain. 355cc277de8SChris Kay # 356291e7182SChris Kay # For each of these variables, if no program path is explicitly provided 357291e7182SChris Kay # by the parent Makefile then the C compiler is queried (if supported) 35814260dbfSChris Kay # for its location. 359cc277de8SChris Kay # 36014260dbfSChris Kay # If the C compiler cannot provide the location (or the tool class *is* 36114260dbfSChris Kay # the C compiler), then it is assigned a default value specific for that 36214260dbfSChris Kay # toolchain. 363cc277de8SChris Kay # 364cc277de8SChris Kay 3653cc5e789SChris Kay toolchain-from-parameter = $($($(1)-$(2)-parameter)) 366cc277de8SChris Kay 3673cc5e789SChris Kay toolchain-from-cc-arm-clang-cpp = $(1) 3683cc5e789SChris Kay toolchain-from-cc-arm-clang-as = $(1) 3693cc5e789SChris Kay toolchain-from-cc-arm-clang-ld = # Fall back to `$(toolchain)-ld-default` 3703cc5e789SChris Kay toolchain-from-cc-arm-clang-oc = # Fall back to `$(toolchain)-oc-default` 3713cc5e789SChris Kay toolchain-from-cc-arm-clang-od = # Fall back to `$(toolchain)-od-default` 3723cc5e789SChris Kay toolchain-from-cc-arm-clang-ar = # Fall back to `$(toolchain)-ar-default` 373cc277de8SChris Kay 3743cc5e789SChris Kay toolchain-from-cc-llvm-clang-cpp = $(1) 3753cc5e789SChris Kay toolchain-from-cc-llvm-clang-as = $(1) 3763cc5e789SChris Kay toolchain-from-cc-llvm-clang-ld = $(1) 3773cc5e789SChris Kay toolchain-from-cc-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>/dev/null) 3783cc5e789SChris Kay toolchain-from-cc-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>/dev/null) 3793cc5e789SChris Kay toolchain-from-cc-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>/dev/null) 380d2867397SChris Kay 3813cc5e789SChris Kay toolchain-from-cc-gnu-gcc-cpp = $(1) 3823cc5e789SChris Kay toolchain-from-cc-gnu-gcc-as = $(1) 3833cc5e789SChris Kay toolchain-from-cc-gnu-gcc-ld = $(1) 3843cc5e789SChris Kay toolchain-from-cc-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>/dev/null) 3853cc5e789SChris Kay toolchain-from-cc-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>/dev/null) 3863cc5e789SChris Kay toolchain-from-cc-gnu-gcc-ar = $(shell $(1) --print-prog-name ar 2>/dev/null) 3873cc5e789SChris Kay 3883cc5e789SChris Kay toolchain-from-cc = $(and $(filter-out cc,$(2)),$($(1)-cc),$\ 3893cc5e789SChris Kay $(call toolchain-from-cc-$($(1)-cc-id)-$(2),$($(1)-cc))) 3903cc5e789SChris Kay 3913cc5e789SChris Kay toolchain-from-default = $(firstword $\ 3923cc5e789SChris Kay $(foreach candidate,$($(1)-$(2)-default),$\ 3933cc5e789SChris Kay $(if $(call which,$(candidate)),$(candidate))) $\ 3943cc5e789SChris Kay $($(1)-$(2)-default)) 395cc277de8SChris Kay 3963789c3c0SChris Kay # 397aa6edba3SBoyan Karatotev # Compiler configuration for the correct ARCH 398aa6edba3SBoyan Karatotev # 399aa6edba3SBoyan Karatotev 400aa6edba3SBoyan Karatotev target-arch-aarch32-arm-clang := arm-arm-none-eabi 401aa6edba3SBoyan Karatotev target-arch-aarch64-arm-clang := aarch64-arm-none-eabi 402aa6edba3SBoyan Karatotev target-arch-aarch32-llvm-clang := arm-arm-none-eabi 403aa6edba3SBoyan Karatotev target-arch-aarch64-llvm-clang := aarch64-arm-none-elf 404aa6edba3SBoyan Karatotev 405aa6edba3SBoyan Karatotev target-flag-aarch32-arm-clang := -target $(target-arch-aarch32-arm-clang) 406aa6edba3SBoyan Karatotev target-flag-aarch64-arm-clang := -target $(target-arch-aarch64-arm-clang) 407aa6edba3SBoyan Karatotev target-flag-aarch32-llvm-clang := -target $(target-arch-aarch32-llvm-clang) 408aa6edba3SBoyan Karatotev target-flag-aarch64-llvm-clang := -target $(target-arch-aarch64-llvm-clang) 409aa6edba3SBoyan Karatotev 410b45fc164SBoyan Karatotev # Prefixes a linker flag appropriately for the linker in use. 411b45fc164SBoyan Karatotev # 412b45fc164SBoyan Karatotev # Parameters: 413b45fc164SBoyan Karatotev # - $1: A linker flag 414b45fc164SBoyan Karatotev # 415b45fc164SBoyan Karatotev 416b45fc164SBoyan Karatotev toolchain-ld-prefix-gnu-gcc = $(addprefix -Xlinker ,$(1)) 417b45fc164SBoyan Karatotev toolchain-ld-prefix-gnu-ld = $(1) 418b45fc164SBoyan Karatotev toolchain-ld-prefix-llvm-clang = $(addprefix -Xlinker ,$(1)) 419b45fc164SBoyan Karatotev toolchain-ld-prefix-llvm-lld = $(1) 420b45fc164SBoyan Karatotev toolchain-ld-prefix-arm-clang = $(addprefix -Xlinker ,$(1)) 421b45fc164SBoyan Karatotev toolchain-ld-prefix-arm-link = $(1) 422b45fc164SBoyan Karatotev 423b45fc164SBoyan Karatotev # 424b45fc164SBoyan Karatotev # Discover whether a linker supports any given option (passed in $(2)) 425b45fc164SBoyan Karatotev # Depending on which linker is in use and how exactly it is used (via a 426b45fc164SBoyan Karatotev # wrapper or not) the discovery process is different for each one 427b45fc164SBoyan Karatotev # 428b45fc164SBoyan Karatotev # Parameters: 429b45fc164SBoyan Karatotev # - $1: The ARCH prefix of the toolchain (eg TF-A's or the native one) 430b45fc164SBoyan Karatotev # - $2: The flag to test 431b45fc164SBoyan Karatotev # Returns the option with the wrapper's prefix (-Xlinker) if necessary 432b45fc164SBoyan Karatotev # 433b45fc164SBoyan Karatotev # Optionally works with lists of options, although granularity will be 434b45fc164SBoyan Karatotev # lost 435b45fc164SBoyan Karatotev # 436b45fc164SBoyan Karatotev 437b45fc164SBoyan Karatotev # shorthand for the below helpers, assuming we're building TF-A 438b45fc164SBoyan Karatotev toolchain-ld-option = $(call toolchain-ld-option-$($(1)-ld-id),$(1),$(2)) 439b45fc164SBoyan Karatotev toolchain-ld-option-gnu-gcc = $(if $\ 440b45fc164SBoyan Karatotev $(shell $($(1)-ld) $(call toolchain-ld-prefix-gnu-gcc,$(2)) -Xlinker --help >/dev/null 2>&1 && echo 1),$\ 441b45fc164SBoyan Karatotev $(call toolchain-ld-prefix-gnu-gcc,$(2))) 442b45fc164SBoyan Karatotev toolchain-ld-option-gnu-ld = $(shell $($(1)-ld) $(2) --help >/dev/null 2>&1 && $\ 443b45fc164SBoyan Karatotev echo $(call escape-shell,$(2))) 444b45fc164SBoyan Karatotev 445aa6edba3SBoyan Karatotev toolchain-ld-option-llvm-clang = $(shell $($(1)-ld) $(target-flag-$(1)-llvm-clang) $\ 446b45fc164SBoyan Karatotev $(call toolchain-ld-prefix-llvm-clang,$(2)) -Xlinker --help >/dev/null 2>&1 && $\ 447b45fc164SBoyan Karatotev echo $(call escape-shell,$(call toolchain-ld-prefix-llvm-clang,$(2)))) 448b45fc164SBoyan Karatotev toolchain-ld-option-llvm-lld = $(shell $($(1)-ld) $(2) --help >/dev/null 2>&1 && $\ 449b45fc164SBoyan Karatotev echo $(call escape-shell,$(2))) 450b45fc164SBoyan Karatotev 451aa6edba3SBoyan Karatotev toolchain-ld-option-arm-clang = $(shell $($(1)-ld) $(target-flag-$(1)-arm-clang) $\ 452b45fc164SBoyan Karatotev $(call toolchain-ld-prefix-arm-clang,$(2)) -Xlinker --help >/dev/null 2>&1 && $\ 453b45fc164SBoyan Karatotev echo $(call escape-shell,$(call toolchain-ld-prefix-arm-clang,$(2)))) 454b45fc164SBoyan Karatotev toolchain-ld-option-arm-link = $(shell $($(1)-ld) $(2) --help >/dev/null 2>&1 && $\ 455b45fc164SBoyan Karatotev echo $(call escape-shell,$(2))) 456b45fc164SBoyan Karatotev 457b45fc164SBoyan Karatotev # 4583789c3c0SChris Kay # Configure a toolchain. 4593789c3c0SChris Kay # 4603789c3c0SChris Kay # Parameters: 4613789c3c0SChris Kay # 4623789c3c0SChris Kay # - $1: The toolchain to configure. 4633789c3c0SChris Kay # 4643789c3c0SChris Kay # This function iterates over all tool classes and configures them for 4653789c3c0SChris Kay # the provided toolchain. Toolchain tools are initialized lazily and 4663789c3c0SChris Kay # on-demand based on the first read of the tool path or identifier 4673789c3c0SChris Kay # variables. 4683789c3c0SChris Kay # 4693d6c7e59SChris Kay 4703789c3c0SChris Kay define toolchain-configure 4713789c3c0SChris Kay $$(foreach tool-class,$$(toolchain-tool-classes), \ 4723789c3c0SChris Kay $$(eval $$(call toolchain-configure-tool,$1,$$(tool-class)))) 4733d6c7e59SChris Kay endef 4743d6c7e59SChris Kay 4753789c3c0SChris Kay # 4763789c3c0SChris Kay # Configure a specific tool within a toolchain. 4773789c3c0SChris Kay # 4783789c3c0SChris Kay # Parameters: 4793789c3c0SChris Kay # 4803789c3c0SChris Kay # - $1: The toolchain to configure. 4813789c3c0SChris Kay # - $2: The tool class to configure. 4823789c3c0SChris Kay # 4833789c3c0SChris Kay 4843789c3c0SChris Kay define toolchain-configure-tool 4853789c3c0SChris Kay $1-$2-configure = $\ 4863789c3c0SChris Kay $$(eval $$(call toolchain-determine-tool,$1,$2)) 4873789c3c0SChris Kay 4883789c3c0SChris Kay # 4893789c3c0SChris Kay # When either of the following variables are read for the first 4903789c3c0SChris Kay # time, the appropriate tool is determined and *both* variables 4913789c3c0SChris Kay # are overwritten with their final values. 4923789c3c0SChris Kay # 4933789c3c0SChris Kay 4943789c3c0SChris Kay $1-$2 = $$($1-$2-configure)$$($1-$2) 4953789c3c0SChris Kay $1-$2-id = $$($1-$2-configure)$$($1-$2-id) 4963789c3c0SChris Kay endef 4973789c3c0SChris Kay 4983789c3c0SChris Kay # 4993789c3c0SChris Kay # Determines and identifies a tool. 5003789c3c0SChris Kay # 5013789c3c0SChris Kay # Parameters: 5023789c3c0SChris Kay # 5033789c3c0SChris Kay # - $1: The toolchain identifier. 5043789c3c0SChris Kay # - $2: The tool class. 5053789c3c0SChris Kay # 5063789c3c0SChris Kay # Tool identification happens by reading the designated tool parameter 5073789c3c0SChris Kay # to get the user-specified command for the tool (e.g. `CC` or `LD`). If 5083789c3c0SChris Kay # no tool parameter is defined then try to derive the tool from the C 5093789c3c0SChris Kay # compiler. 5103789c3c0SChris Kay # 5113789c3c0SChris Kay # If all else fails, fall back to the default command defined by the 5123789c3c0SChris Kay # toolchain makefile. 5133789c3c0SChris Kay # 5143789c3c0SChris Kay 515e01c7126SChris Kay define toolchain-determine-tool 5163cc5e789SChris Kay # 5173cc5e789SChris Kay # Try to determine the tool command by: 5183cc5e789SChris Kay # 5193cc5e789SChris Kay # 1. Using the user-specified value (if one is provided). 5203cc5e789SChris Kay # 2. Otherwise, inferring a reasonable default by: 5213cc5e789SChris Kay # a. Querying the C compiler, if available. 5223cc5e789SChris Kay # b. Falling back to a hard-coded default, if specified. 5233cc5e789SChris Kay # c. Giving up, and erroring out if the tool is mandatory. 5243cc5e789SChris Kay # 525cc277de8SChris Kay 5263cc5e789SChris Kay $1-$2-from-parameter = $$(call toolchain-from-parameter,$1,$2) 5273cc5e789SChris Kay $1-$2-from-cc = $$(call toolchain-from-cc,$1,$2) 5283cc5e789SChris Kay $1-$2-from-default = $$(call toolchain-from-default,$1,$2) 5299cea2c36SChris Kay 53093f45539SChris Kay ifneq ($$($1-$2-from-parameter),) 53193f45539SChris Kay $1-$2-from := $$($1-$2-from-parameter) 53293f45539SChris Kay $1-$2-origin := via `$$($1-$2-parameter)` parameter 53393f45539SChris Kay else ifneq ($$($1-$2-from-cc),) 53493f45539SChris Kay $1-$2-from := $$($1-$2-from-cc) 53593f45539SChris Kay $1-$2-origin := inferred from C compiler 53693f45539SChris Kay else ifneq ($$($1-$2-from-default),) 53793f45539SChris Kay $1-$2-from := $$($1-$2-from-default) 53893f45539SChris Kay $1-$2-origin := default 53993f45539SChris Kay endif 5403d6c7e59SChris Kay 5413cc5e789SChris Kay # 5423cc5e789SChris Kay # Sanitize the command for the shell by either escaping the 5433cc5e789SChris Kay # entire string if it's a program name/path, or by expanding and 5443cc5e789SChris Kay # escaping each shell word. 5453cc5e789SChris Kay # 5463cc5e789SChris Kay 5473cc5e789SChris Kay $1-$2 := $$(call shell-program,$$($1-$2-from)) 5483cc5e789SChris Kay 5493cc5e789SChris Kay $$(if $$(or $$($1-$2),$$($1-$2-optional)),,$\ 5503cc5e789SChris Kay $$(error no $$($1-name) $$(toolchain-tool-class-name-$2) configured)) 5513d6c7e59SChris Kay 552d2867397SChris Kay $1-$2-id := $$(if $$($1-$2),$$(or $\ 553d2867397SChris Kay $$(call toolchain-guess-tool,$$\ 554d2867397SChris Kay $$(toolchain-tools-$2),$$($1-$2)),$\ 5553cc5e789SChris Kay $$(call toolchain-warn-unrecognized,$1,$2)$\ 556d2867397SChris Kay $$($1-$2-default-id))) 557*5c24052aSChris Kay 558*5c24052aSChris Kay $1-$2-program := $$(call toolchain-tool-program,$\ 559*5c24052aSChris Kay $$($1-$2-id),$$($1-$2)) 560*5c24052aSChris Kay $1-$2-wrapper := $$(call toolchain-tool-wrapper,$\ 561*5c24052aSChris Kay $$($1-$2-id),$$($1-$2)) 562cc277de8SChris Kay endef 563cc277de8SChris Kay 564cc277de8SChris Kay $(foreach toolchain,$(toolchains), \ 5653789c3c0SChris Kay $(eval $(call toolchain-configure,$(toolchain)))) 566291e7182SChris Kayendif 567