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 # 2715c24052aSChris Kay # Get the index of the first valid tool path in a shell command. 2725c24052aSChris Kay # 2735c24052aSChris Kay # To support compiler wrappers like `ccache`, we need to be able to 2745c24052aSChris Kay # robustly identify which part of a shell command is the wrapper and 2755c24052aSChris Kay # which part is the wrapped. 2765c24052aSChris Kay # 2775c24052aSChris Kay # To do this, we iterate through each shell word in the string, query it 2785c24052aSChris Kay # to see if it is one the tools we would expect to see, and return its 2795c24052aSChris Kay # index. 2805c24052aSChris Kay # 2815c24052aSChris Kay # - $(1): A list of candidate tool identifiers to check. 2825c24052aSChris Kay # - $(2): The shell command to parse. 2835c24052aSChris Kay # 2845c24052aSChris Kay 285*3dc69bcbSChris Kay toolchain-tool-program-index = $\ 286*3dc69bcbSChris Kay $(call with,p:candidates p:command,$(1),$(2),$\ 287*3dc69bcbSChris Kay $$(firstword $$(call shell-map,$\ 288*3dc69bcbSChris Kay toolchain-tool-program-index.map,$\ 289*3dc69bcbSChris Kay $$(command)))) 290*3dc69bcbSChris Kay 291*3dc69bcbSChris Kay toolchain-tool-program-index.map = $(and $\ 292*3dc69bcbSChris Kay $(call which,$(1)),$\ 293*3dc69bcbSChris Kay $(call toolchain-guess-tool,$(candidates),$(1)),$\ 294*3dc69bcbSChris Kay $(2)) 2955c24052aSChris Kay 2965c24052aSChris Kay # 2975c24052aSChris Kay # Strip any program wrappers from a tool's shell command. 2985c24052aSChris Kay # 2995c24052aSChris Kay # This function removes any program wrappers, like `ccache`, from the 3005c24052aSChris Kay # shell command of a tool. 3015c24052aSChris Kay # 3025c24052aSChris Kay # - $(1): A list of candidate tool identifiers to check. 3035c24052aSChris Kay # - $(2): The shell command to parse. 3045c24052aSChris Kay # 3055c24052aSChris Kay 3065c24052aSChris Kay toolchain-tool-program = $(call shell-slice,$(2),$\ 3075c24052aSChris Kay $(call toolchain-tool-program-index,$(1),$(2))) 3085c24052aSChris Kay 3095c24052aSChris Kay # 3105c24052aSChris Kay # Extract the program wrapper from a tool's shell command. 3115c24052aSChris Kay # 3125c24052aSChris Kay # This function returns any program wrappers, like `ccache`, from the 3135c24052aSChris Kay # shell command of a tool. 3145c24052aSChris Kay # 3155c24052aSChris Kay # - $(1): A list of candidate tool identifiers to check. 3165c24052aSChris Kay # - $(2): The shell command to parse. 3175c24052aSChris Kay # 3185c24052aSChris Kay 3195c24052aSChris Kay toolchain-tool-wrapper = $(call shell-slice,$(2),1,$\ 3205c24052aSChris Kay $(call toolchain-tool-program-index,$(1),$(2))) 3215c24052aSChris Kay 3225c24052aSChris Kay # 3233789c3c0SChris Kay # Warn the user that a tool could not be identified. 3243789c3c0SChris Kay # 3253789c3c0SChris Kay # Parameters: 3263789c3c0SChris Kay # 3273789c3c0SChris Kay # - $1: The toolchain that the tool belongs to. 3283789c3c0SChris Kay # - $2: The tool class that the tool belongs to. 3293789c3c0SChris Kay # 3303789c3c0SChris Kay 3313789c3c0SChris Kay define toolchain-warn-unrecognized 3323789c3c0SChris Kay $(warning ) 3339cea2c36SChris Kay $(warning The configured $($(1)-name) $(toolchain-tool-class-name-$(2)) could not be identified:) 3343789c3c0SChris Kay $(warning ) 33593f45539SChris Kay $(warning $(space) $($(1)-$(2)) ($($(1)-$(2)-origin))) 3369cea2c36SChris Kay 3373789c3c0SChris Kay $(warning ) 3383789c3c0SChris Kay $(warning The following tools are supported:) 3393789c3c0SChris Kay $(warning ) 3403789c3c0SChris Kay 3413789c3c0SChris Kay $(foreach tool,$(toolchain-tools-$(2)), \ 3423789c3c0SChris Kay $(warning $(space) - $(toolchain-tool-name-$(tool)))) 3433789c3c0SChris Kay 3443789c3c0SChris Kay $(warning ) 3459cea2c36SChris Kay $(warning The build system will treat this $(toolchain-tool-class-name-$(2)) as $(toolchain-tool-name-$($(1)-$(2)-default-id)).) 3463789c3c0SChris Kay $(warning ) 3473789c3c0SChris Kay endef 3483789c3c0SChris Kay 3493789c3c0SChris Kay # 350cc277de8SChris Kay # Locate and identify tools belonging to each toolchain. 351cc277de8SChris Kay # 352cc277de8SChris Kay # Each tool class in each toolchain receives a variable of the form 353291e7182SChris Kay # `$(toolchain)-$(tool)` giving the associated path to the program. For 354291e7182SChris Kay # example: 355cc277de8SChris Kay # 356cc277de8SChris Kay # - `aarch64-ld` gives the linker for the AArch64 toolchain, 357cc277de8SChris Kay # - `aarch32-oc` gives the object copier for the AArch32 toolchain, and 358cc277de8SChris Kay # - `host-cc` gives the C compiler for the host toolchain. 359cc277de8SChris Kay # 360291e7182SChris Kay # For each of these variables, if no program path is explicitly provided 361291e7182SChris Kay # by the parent Makefile then the C compiler is queried (if supported) 36214260dbfSChris Kay # for its location. 363cc277de8SChris Kay # 36414260dbfSChris Kay # If the C compiler cannot provide the location (or the tool class *is* 36514260dbfSChris Kay # the C compiler), then it is assigned a default value specific for that 36614260dbfSChris Kay # toolchain. 367cc277de8SChris Kay # 368cc277de8SChris Kay 3693cc5e789SChris Kay toolchain-from-parameter = $($($(1)-$(2)-parameter)) 370cc277de8SChris Kay 3713cc5e789SChris Kay toolchain-from-cc-arm-clang-cpp = $(1) 3723cc5e789SChris Kay toolchain-from-cc-arm-clang-as = $(1) 3733cc5e789SChris Kay toolchain-from-cc-arm-clang-ld = # Fall back to `$(toolchain)-ld-default` 3743cc5e789SChris Kay toolchain-from-cc-arm-clang-oc = # Fall back to `$(toolchain)-oc-default` 3753cc5e789SChris Kay toolchain-from-cc-arm-clang-od = # Fall back to `$(toolchain)-od-default` 3763cc5e789SChris Kay toolchain-from-cc-arm-clang-ar = # Fall back to `$(toolchain)-ar-default` 377cc277de8SChris Kay 3783cc5e789SChris Kay toolchain-from-cc-llvm-clang-cpp = $(1) 3793cc5e789SChris Kay toolchain-from-cc-llvm-clang-as = $(1) 3803cc5e789SChris Kay toolchain-from-cc-llvm-clang-ld = $(1) 3813cc5e789SChris Kay toolchain-from-cc-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>/dev/null) 3823cc5e789SChris Kay toolchain-from-cc-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>/dev/null) 3833cc5e789SChris Kay toolchain-from-cc-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>/dev/null) 384d2867397SChris Kay 3853cc5e789SChris Kay toolchain-from-cc-gnu-gcc-cpp = $(1) 3863cc5e789SChris Kay toolchain-from-cc-gnu-gcc-as = $(1) 3873cc5e789SChris Kay toolchain-from-cc-gnu-gcc-ld = $(1) 3883cc5e789SChris Kay toolchain-from-cc-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>/dev/null) 3893cc5e789SChris Kay toolchain-from-cc-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>/dev/null) 3903cc5e789SChris Kay toolchain-from-cc-gnu-gcc-ar = $(shell $(1) --print-prog-name ar 2>/dev/null) 3913cc5e789SChris Kay 3923cc5e789SChris Kay toolchain-from-cc = $(and $(filter-out cc,$(2)),$($(1)-cc),$\ 3933cc5e789SChris Kay $(call toolchain-from-cc-$($(1)-cc-id)-$(2),$($(1)-cc))) 3943cc5e789SChris Kay 3953cc5e789SChris Kay toolchain-from-default = $(firstword $\ 3963cc5e789SChris Kay $(foreach candidate,$($(1)-$(2)-default),$\ 3973cc5e789SChris Kay $(if $(call which,$(candidate)),$(candidate))) $\ 3983cc5e789SChris Kay $($(1)-$(2)-default)) 399cc277de8SChris Kay 4003789c3c0SChris Kay # 401aa6edba3SBoyan Karatotev # Compiler configuration for the correct ARCH 402aa6edba3SBoyan Karatotev # 403aa6edba3SBoyan Karatotev 404aa6edba3SBoyan Karatotev target-arch-aarch32-arm-clang := arm-arm-none-eabi 405aa6edba3SBoyan Karatotev target-arch-aarch64-arm-clang := aarch64-arm-none-eabi 406aa6edba3SBoyan Karatotev target-arch-aarch32-llvm-clang := arm-arm-none-eabi 407aa6edba3SBoyan Karatotev target-arch-aarch64-llvm-clang := aarch64-arm-none-elf 408aa6edba3SBoyan Karatotev 409aa6edba3SBoyan Karatotev target-flag-aarch32-arm-clang := -target $(target-arch-aarch32-arm-clang) 410aa6edba3SBoyan Karatotev target-flag-aarch64-arm-clang := -target $(target-arch-aarch64-arm-clang) 411aa6edba3SBoyan Karatotev target-flag-aarch32-llvm-clang := -target $(target-arch-aarch32-llvm-clang) 412aa6edba3SBoyan Karatotev target-flag-aarch64-llvm-clang := -target $(target-arch-aarch64-llvm-clang) 413aa6edba3SBoyan Karatotev 414b45fc164SBoyan Karatotev # Prefixes a linker flag appropriately for the linker in use. 415b45fc164SBoyan Karatotev # 416b45fc164SBoyan Karatotev # Parameters: 417b45fc164SBoyan Karatotev # - $1: A linker flag 418b45fc164SBoyan Karatotev # 419b45fc164SBoyan Karatotev 420b45fc164SBoyan Karatotev toolchain-ld-prefix-gnu-gcc = $(addprefix -Xlinker ,$(1)) 421b45fc164SBoyan Karatotev toolchain-ld-prefix-gnu-ld = $(1) 422b45fc164SBoyan Karatotev toolchain-ld-prefix-llvm-clang = $(addprefix -Xlinker ,$(1)) 423b45fc164SBoyan Karatotev toolchain-ld-prefix-llvm-lld = $(1) 424b45fc164SBoyan Karatotev toolchain-ld-prefix-arm-clang = $(addprefix -Xlinker ,$(1)) 425b45fc164SBoyan Karatotev toolchain-ld-prefix-arm-link = $(1) 426b45fc164SBoyan Karatotev 427b45fc164SBoyan Karatotev # 428b45fc164SBoyan Karatotev # Discover whether a linker supports any given option (passed in $(2)) 429b45fc164SBoyan Karatotev # Depending on which linker is in use and how exactly it is used (via a 430b45fc164SBoyan Karatotev # wrapper or not) the discovery process is different for each one 431b45fc164SBoyan Karatotev # 432b45fc164SBoyan Karatotev # Parameters: 433b45fc164SBoyan Karatotev # - $1: The ARCH prefix of the toolchain (eg TF-A's or the native one) 434b45fc164SBoyan Karatotev # - $2: The flag to test 435b45fc164SBoyan Karatotev # Returns the option with the wrapper's prefix (-Xlinker) if necessary 436b45fc164SBoyan Karatotev # 437b45fc164SBoyan Karatotev # Optionally works with lists of options, although granularity will be 438b45fc164SBoyan Karatotev # lost 439b45fc164SBoyan Karatotev # 440b45fc164SBoyan Karatotev 441b45fc164SBoyan Karatotev # shorthand for the below helpers, assuming we're building TF-A 442b45fc164SBoyan Karatotev toolchain-ld-option = $(call toolchain-ld-option-$($(1)-ld-id),$(1),$(2)) 443b45fc164SBoyan Karatotev toolchain-ld-option-gnu-gcc = $(if $\ 444b45fc164SBoyan Karatotev $(shell $($(1)-ld) $(call toolchain-ld-prefix-gnu-gcc,$(2)) -Xlinker --help >/dev/null 2>&1 && echo 1),$\ 445b45fc164SBoyan Karatotev $(call toolchain-ld-prefix-gnu-gcc,$(2))) 446b45fc164SBoyan Karatotev toolchain-ld-option-gnu-ld = $(shell $($(1)-ld) $(2) --help >/dev/null 2>&1 && $\ 447b45fc164SBoyan Karatotev echo $(call escape-shell,$(2))) 448b45fc164SBoyan Karatotev 449aa6edba3SBoyan Karatotev toolchain-ld-option-llvm-clang = $(shell $($(1)-ld) $(target-flag-$(1)-llvm-clang) $\ 450b45fc164SBoyan Karatotev $(call toolchain-ld-prefix-llvm-clang,$(2)) -Xlinker --help >/dev/null 2>&1 && $\ 451b45fc164SBoyan Karatotev echo $(call escape-shell,$(call toolchain-ld-prefix-llvm-clang,$(2)))) 452b45fc164SBoyan Karatotev toolchain-ld-option-llvm-lld = $(shell $($(1)-ld) $(2) --help >/dev/null 2>&1 && $\ 453b45fc164SBoyan Karatotev echo $(call escape-shell,$(2))) 454b45fc164SBoyan Karatotev 455aa6edba3SBoyan Karatotev toolchain-ld-option-arm-clang = $(shell $($(1)-ld) $(target-flag-$(1)-arm-clang) $\ 456b45fc164SBoyan Karatotev $(call toolchain-ld-prefix-arm-clang,$(2)) -Xlinker --help >/dev/null 2>&1 && $\ 457b45fc164SBoyan Karatotev echo $(call escape-shell,$(call toolchain-ld-prefix-arm-clang,$(2)))) 458b45fc164SBoyan Karatotev toolchain-ld-option-arm-link = $(shell $($(1)-ld) $(2) --help >/dev/null 2>&1 && $\ 459b45fc164SBoyan Karatotev echo $(call escape-shell,$(2))) 460b45fc164SBoyan Karatotev 461b45fc164SBoyan Karatotev # 4623789c3c0SChris Kay # Configure a toolchain. 4633789c3c0SChris Kay # 4643789c3c0SChris Kay # Parameters: 4653789c3c0SChris Kay # 4663789c3c0SChris Kay # - $1: The toolchain to configure. 4673789c3c0SChris Kay # 4683789c3c0SChris Kay # This function iterates over all tool classes and configures them for 4693789c3c0SChris Kay # the provided toolchain. Toolchain tools are initialized lazily and 4703789c3c0SChris Kay # on-demand based on the first read of the tool path or identifier 4713789c3c0SChris Kay # variables. 4723789c3c0SChris Kay # 4733d6c7e59SChris Kay 4743789c3c0SChris Kay define toolchain-configure 4753789c3c0SChris Kay $$(foreach tool-class,$$(toolchain-tool-classes), \ 4763789c3c0SChris Kay $$(eval $$(call toolchain-configure-tool,$1,$$(tool-class)))) 4773d6c7e59SChris Kay endef 4783d6c7e59SChris Kay 4793789c3c0SChris Kay # 4803789c3c0SChris Kay # Configure a specific tool within a toolchain. 4813789c3c0SChris Kay # 4823789c3c0SChris Kay # Parameters: 4833789c3c0SChris Kay # 4843789c3c0SChris Kay # - $1: The toolchain to configure. 4853789c3c0SChris Kay # - $2: The tool class to configure. 4863789c3c0SChris Kay # 4873789c3c0SChris Kay 4883789c3c0SChris Kay define toolchain-configure-tool 4893789c3c0SChris Kay $1-$2-configure = $\ 4903789c3c0SChris Kay $$(eval $$(call toolchain-determine-tool,$1,$2)) 4913789c3c0SChris Kay 4923789c3c0SChris Kay # 4933789c3c0SChris Kay # When either of the following variables are read for the first 4943789c3c0SChris Kay # time, the appropriate tool is determined and *both* variables 4953789c3c0SChris Kay # are overwritten with their final values. 4963789c3c0SChris Kay # 4973789c3c0SChris Kay 4983789c3c0SChris Kay $1-$2 = $$($1-$2-configure)$$($1-$2) 4993789c3c0SChris Kay $1-$2-id = $$($1-$2-configure)$$($1-$2-id) 5003789c3c0SChris Kay endef 5013789c3c0SChris Kay 5023789c3c0SChris Kay # 5033789c3c0SChris Kay # Determines and identifies a tool. 5043789c3c0SChris Kay # 5053789c3c0SChris Kay # Parameters: 5063789c3c0SChris Kay # 5073789c3c0SChris Kay # - $1: The toolchain identifier. 5083789c3c0SChris Kay # - $2: The tool class. 5093789c3c0SChris Kay # 5103789c3c0SChris Kay # Tool identification happens by reading the designated tool parameter 5113789c3c0SChris Kay # to get the user-specified command for the tool (e.g. `CC` or `LD`). If 5123789c3c0SChris Kay # no tool parameter is defined then try to derive the tool from the C 5133789c3c0SChris Kay # compiler. 5143789c3c0SChris Kay # 5153789c3c0SChris Kay # If all else fails, fall back to the default command defined by the 5163789c3c0SChris Kay # toolchain makefile. 5173789c3c0SChris Kay # 5183789c3c0SChris Kay 519e01c7126SChris Kay define toolchain-determine-tool 5203cc5e789SChris Kay # 5213cc5e789SChris Kay # Try to determine the tool command by: 5223cc5e789SChris Kay # 5233cc5e789SChris Kay # 1. Using the user-specified value (if one is provided). 5243cc5e789SChris Kay # 2. Otherwise, inferring a reasonable default by: 5253cc5e789SChris Kay # a. Querying the C compiler, if available. 5263cc5e789SChris Kay # b. Falling back to a hard-coded default, if specified. 5273cc5e789SChris Kay # c. Giving up, and erroring out if the tool is mandatory. 5283cc5e789SChris Kay # 529cc277de8SChris Kay 5303cc5e789SChris Kay $1-$2-from-parameter = $$(call toolchain-from-parameter,$1,$2) 5313cc5e789SChris Kay $1-$2-from-cc = $$(call toolchain-from-cc,$1,$2) 5323cc5e789SChris Kay $1-$2-from-default = $$(call toolchain-from-default,$1,$2) 5339cea2c36SChris Kay 53493f45539SChris Kay ifneq ($$($1-$2-from-parameter),) 53593f45539SChris Kay $1-$2-from := $$($1-$2-from-parameter) 53693f45539SChris Kay $1-$2-origin := via `$$($1-$2-parameter)` parameter 53793f45539SChris Kay else ifneq ($$($1-$2-from-cc),) 53893f45539SChris Kay $1-$2-from := $$($1-$2-from-cc) 53993f45539SChris Kay $1-$2-origin := inferred from C compiler 54093f45539SChris Kay else ifneq ($$($1-$2-from-default),) 54193f45539SChris Kay $1-$2-from := $$($1-$2-from-default) 54293f45539SChris Kay $1-$2-origin := default 54393f45539SChris Kay endif 5443d6c7e59SChris Kay 5453cc5e789SChris Kay # 5463cc5e789SChris Kay # Sanitize the command for the shell by either escaping the 5473cc5e789SChris Kay # entire string if it's a program name/path, or by expanding and 5483cc5e789SChris Kay # escaping each shell word. 5493cc5e789SChris Kay # 5503cc5e789SChris Kay 5513cc5e789SChris Kay $1-$2 := $$(call shell-program,$$($1-$2-from)) 5523cc5e789SChris Kay 5533cc5e789SChris Kay $$(if $$(or $$($1-$2),$$($1-$2-optional)),,$\ 5543cc5e789SChris Kay $$(error no $$($1-name) $$(toolchain-tool-class-name-$2) configured)) 5553d6c7e59SChris Kay 556d2867397SChris Kay $1-$2-id := $$(if $$($1-$2),$$(or $\ 557d2867397SChris Kay $$(call toolchain-guess-tool,$$\ 558d2867397SChris Kay $$(toolchain-tools-$2),$$($1-$2)),$\ 5593cc5e789SChris Kay $$(call toolchain-warn-unrecognized,$1,$2)$\ 560d2867397SChris Kay $$($1-$2-default-id))) 5615c24052aSChris Kay 5625c24052aSChris Kay $1-$2-program := $$(call toolchain-tool-program,$\ 5635c24052aSChris Kay $$($1-$2-id),$$($1-$2)) 5645c24052aSChris Kay $1-$2-wrapper := $$(call toolchain-tool-wrapper,$\ 5655c24052aSChris Kay $$($1-$2-id),$$($1-$2)) 566cc277de8SChris Kay endef 567cc277de8SChris Kay 568cc277de8SChris Kay $(foreach toolchain,$(toolchains), \ 5693789c3c0SChris Kay $(eval $(call toolchain-configure,$(toolchain)))) 570291e7182SChris Kayendif 571