1#------------------------------------------------------------------------------- 2# Copyright (c) 2001-2020, Arm Limited. All rights reserved. 3# 4# SPDX-License-Identifier: BSD-3-Clause 5# 6#------------------------------------------------------------------------------- 7 8# Makefile definitions common to all Host components build 9# This file should be included at the start of a Makefile 10 11# Note: The caller (or environment) should provide the following variables: 12# ARCH = Target architectore, e.g., powerpc 13# OS = Target OS, e.g., linux 14# HOST_PROJ_ROOT = The root of the host domain tree (where this file is located) 15 16# LOGFILE = log file name. Default is makelog.txt in the current dir. 17 18### Determine host environment 19_UNAME_OS=$(shell uname -o) 20 21ifeq (Cygwin,$(_UNAME_OS)) 22 HOST=WINDOWS 23 HOST_OS=CYGWIN 24else ifeq (Msys,$(_UNAME_OS)) 25 HOST=WINDOWS 26 HOST_OS=MSYS 27else ifeq (GNU/Linux,$(_UNAME_OS)) 28 HOST=LINUX 29 HOST_OS=LINUX 30else 31 HOST=UNKNOWN 32 HOST_OS=UNKNOWN 33endif 34 35 36### Build platform commands (Currently assumes Linux/Unix/Cygwin machine) 37SHELL = /bin/bash -o pipefail 38RM = rm -f 39ECHO = echo 40MKDIR = mkdir -p 41RMDIR = rm -rf 42CP = cp -P 43CP_DEREF = cp -L 44SYMLINK = ln -s 45MAKE = make 46 47LOGFILE ?= ./makelog.txt 48 49### Build environment setup ### 50 51#On windows when running from an emulated POSIX environment we have 52#to deal with three different kind of paths. The native windows path 53#i.e. c:\foo\bar, the POSIX path i.e. /c/foo/bar or 54#/cygdrive/c/foo/bar and the mixed path which is the native path but 55#with forward slashes (i.e. c:/foo/bar). 56#Executables compiled in the POSIX environment understand the 57#POSIX and the mixed path. Native windows executables (i.e. compilers 58#understand the native and the mixed path. 59#To avoid path issues the best is to use the mixed path. Use the 60#cygpath tool to do the conversion. 61#Note: the pwd command provided by the shell must not be used in the 62# makefiles! 63 64ifneq (,$(filter ${HOST_OS},CYGWIN MSYS)) 65 PWD := $(shell cygpath -am . | tr -d '\r\n') 66else 67 PWD := $(shell readlink -f .) 68endif 69 70ifndef HOST_PROJ_ROOT 71$(error HOST_PROJ_ROOT is undefined) 72endif 73 74# Host domain root converted to absolut path 75ifneq (,$(filter ${HOST_OS},CYGWIN MSYS)) 76 HOST_PROJ_ROOT := $(shell cygpath -am $(HOST_PROJ_ROOT) | tr -d '\r\n') 77else 78 HOST_PROJ_ROOT := $(shell readlink -f $(HOST_PROJ_ROOT)) 79endif 80HOST_SRCDIR := $(HOST_PROJ_ROOT)/src 81SHARED_DIR := $(HOST_PROJ_ROOT)/../shared 82SHARED_INCDIR := $(SHARED_DIR)/include 83SHARED_SRCDIR := $(SHARED_DIR)/src 84CODESAFE_DIR := $(HOST_PROJ_ROOT)/../codesafe 85CODESAFE_SRCDIR := $(CODESAFE_DIR)/src 86UTILS_DIR := $(HOST_PROJ_ROOT)/../utils 87UTILS_SRCDIR := $(UTILS_DIR)/src 88#Note: on windows GCC seems to ignore ./ as an include path with: 89# ignoring nonexistent directory. Using . seems to work. 90INCDIRS = . $(INCDIRS_EXTRA) 91INCDIRS += $(SHARED_INCDIR) $(SHARED_INCDIR)/proj/$(PROJ_PRD) 92# $(SHARED_INCDIR)/pal $(SHARED_INCDIR)/pal/$(TEE_OS) $(SHARED_INCDIR)/pal/$(TEE_OS)/include 93INCDIRS += $(HOST_PROJ_ROOT)/include 94LIBDIRS = . $(LIBDIRS_EXTRA) $(HOST_PROJ_ROOT)/lib 95 96HOST_LIBDIR = $(HOST_SRCDIR)/$(HOST_LIBNAME) 97 98# Release directories 99RELEASE_INCDIR = $(HOST_PROJ_ROOT)/include 100RELEASE_LIBDIR = $(HOST_PROJ_ROOT)/lib 101RELEASE_EXEDIR = $(HOST_PROJ_ROOT)/bin 102# SCRDIR for scripts 103RELEASE_SCRDIR = $(HOST_PROJ_ROOT)/bin 104# DATDIR for data/binary files 105RELEASE_DATDIR = $(HOST_PROJ_ROOT)/dat 106 107################################################ 108### Handle project configuration definitions ### 109################################################ 110PROJ_CFG_FNAME = proj.cfg 111PROJ_EXT_CFG_FNAME = proj.ext.cfg 112PROJ_CFG_PATH = $(HOST_PROJ_ROOT)/$(PROJ_CFG_FNAME) 113PROJ_EXT_CFG_PATH = $(HOST_PROJ_ROOT)/../$(PROJ_EXT_CFG_FNAME) 114CONFIGS_PATH = src/configs 115PROJ_CONFIGS_DIR = $(HOST_PROJ_ROOT)/$(CONFIGS_PATH) 116 117#Test directories 118ifeq ($(TEE_OS),freertos) 119KERNEL_LIB_DIR := $(KERNEL_DIR)/lib 120KERNEL_TEST_DIR := $(KERNEL_DIR)/lib/tests 121endif 122 123### Toolchain setup ### 124ARCH_SUPPORTED = powerpc arm arm64 i686 x86 x86_64 x86win 125# i686 or x86_64 - compilation for i686(x86)/x86_64 Linux using native toolchain. 126# x86win - compilation for x86 Windows, using MinGW toolchain. 127 128# default ARCH 129ARCH ?= powerpc 130export ARCH 131#$(info ARCH=$(ARCH)) 132 133ifeq ($(filter $(ARCH),$(ARCH_SUPPORTED)),) 134 $(error Unsupported ARCH==$(ARCH)) 135endif 136 137#initiate variable to avoid concatinatation at every target level 138CFLAGS = 139 140ifeq ($(ARCH),arm64) 141 # aarch64-linux-gnu- 142 CROSS_COMPILE := $(if $(filter aarch64-%,$(CROSS_COMPILE)),$(CROSS_COMPILE),aarch64-linux-gnu-) 143 ARCH_ENDIAN = LITTLE 144endif 145 146# The following statements would be executed only if ARCH is one of the supported ones. 147ifeq ($(ARCH),powerpc) 148 CROSS_COMPILE := ppc_4xx- 149 ARCH_ENDIAN = BIG 150 CFLAGS += -isystem /opt/eldk/ppc_4xx/usr/include 151endif 152 153ifeq ($(ARCH),x86win) 154 # Compiling for x86-windows - using MinGW toolchain. 155 CROSS_COMPILE ?= i586-mingw32msvc- 156endif 157 158# subfolder for compilation/generation outcome/objects/binaries 159BUILDDIR = $(PWD)/build-$(CROSS_COMPILE:%-=%) 160 161### proj.cfg exists. Include it to get project configuration definitions ### 162ifeq ($(wildcard $(PROJ_CFG_PATH)),$(PROJ_CFG_PATH)) 163include $(PROJ_EXT_CFG_PATH) 164include $(PROJ_CFG_PATH) 165endif 166 167ifeq ($(ARCH),arm) 168 # For android NDK must define -ffreestanding to be able to build with Bionic library, etc. 169 CFLAGS += $(if $(filter arm-linux-androideabi-,$(CROSS_COMPILE)),-ffreestanding) 170 # Same requirement for arm-eabi (bare metal) due to use of RTOS (private) libc implementation 171 CFLAGS += $(if $(filter arm-eabi-,$(CROSS_COMPILE)),-ffreestanding) 172 ARCH_ENDIAN = LITTLE 173 ifeq ($(CROSS_COMPILE),arm-bcm2708hardfp-linux-gnueabi-) 174 # RaspberryPi (ARM11/ARMv6) support 175 $(info Assuming build for RaspberryPi) 176 CFLAGS += -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s 177 else ifeq ($(CROSS_COMPILE),arm-none-eabi-) 178 ifeq ($(ARM_CPU), cortex-m33) 179 CFLAGS += -march=armv8-m.main 180 CFLAGS += -mcmse 181 CFLAGS += -DARCH_V8M 182 else ifeq ($(ARM_CPU), cortex-m3) 183 # For arm-none-eabi assume cortex-m3 184 ARM_CPU ?= cortex-m3 185 CFLAGS += -mcpu=$(ARM_CPU) 186 else ifeq ($(ARM_CPU), cortex-m0plus) 187 ARM_CPU ?= cortex-m0plus 188 CFLAGS += -mcpu=$(ARM_CPU) 189 else 190 $(error unrecognized ARM_CPU "$(ARM_CPU)") 191 endif 192 CFLAGS += -mthumb 193 TEE_OS = no_os 194 else ifeq ($(CROSS_COMPILE),armcc) 195 ARM_CPU ?= cortex-m3 196 CFLAGS += --cpu $(ARM_CPU) --littleend 197 CFLAGS += --thumb 198 else ifeq ($(CROSS_COMPILE),armclang) 199 ifeq ($(ARM_CPU), cortex-m33) 200 CFLAGS += -march=armv8-m.main 201 CFLAGS += -mcmse 202 CFLAGS += -mfpu=none 203 CFLAGS += -DARCH_V8M 204 else ifeq ($(ARM_CPU), cortex-m3) 205 ARM_CPU ?= cortex-m3 206 CFLAGS += -mcpu=$(ARM_CPU) 207 else ifeq ($(ARM_CPU), cortex-m0plus) 208 ARM_CPU ?= cortex-m0plus 209 CFLAGS += -mcpu=$(ARM_CPU) 210 else 211 $(error unrecognized ARM_CPU "$(ARM_CPU)") 212 endif 213 CFLAGS += --target=arm-arm-none-eabi -mlittle-endian 214 CFLAGS += -mthumb 215 CFLAGS += -DCC_TEE -DDX_PLAT_MPS2_PLUS 216 endif 217 # For arm-eabi- assume a15, otherwise assume a9 (zynq7000) 218 ARM_CPU ?= $(if $(filter arm-eabi-,$(CROSS_COMPILE)),cortex-a15,cortex-a9) 219 ifeq ($(filter arm ,$(CROSS_COMPILE)),$(CROSS_COMPILE)) 220 CFLAGS += --cpu $(ARM_CPU) --littleend 221 endif 222 CFLAGS += $(if $(filter arm-eabi-,$(CROSS_COMPILE)),-DARCH_ARM -DARM_CPU_CORTEX_A15=1) 223 # for optee_os 224 ifeq ($(CROSS_COMPILE),arm-linux-gnueabihf-) 225 CFLAGS += -mfloat-abi=soft 226 endif #arm-linux-gnueabihf- 227 228 export CORTEX 229 export ARM_CPU 230endif #arm 231 232ifneq ($(filter i686 x86 x86win x86_64,$(ARCH)),) # x86* Arch. 233 ARCH_ENDIAN = LITTLE 234endif 235 236ifeq ($(filter arm arm-dsm- armcc ,$(CROSS_COMPILE)),$(CROSS_COMPILE)) 237CC_DEF = 1 238CC = armcc 239LD = armcc 240AR = armar 241ifneq ($(CROSS_COMPILE),armcc) 242override TEE_OS = no_os 243endif 244endif 245 246ifeq ($(filter armclang ,$(CROSS_COMPILE)),$(CROSS_COMPILE)) 247CC_DEF = 1 248CC = armclang 249LD = armlink 250AR = armar 251endif 252 253# Object file suffix 254OBJEXT = .o 255 256# Library prefix 257LIBPRE = lib 258 259# In Unix/Linux there is no extension to executables. Set to ".exe" for Windows. 260EXEEXT = 261 262 263ifeq ($(CC_DEF),) 264CC = $(CROSS_COMPILE)gcc 265CPP = $(CROSS_COMPILE)g++ 266LD = $(CROSS_COMPILE)gcc 267AR = $(CROSS_COMPILE)ar 268RANLIB = $(CROSS_COMPILE)ranlib 269endif 270 271# Helper variables for complex string definitions 272comma := , 273 274############ 275# Logged execution "function". To be used with make's $(call...). 276# Its "parameter is the command to execute 277# The "function" puts all stdout into LOGFILE. The stderr is output to both terminal and a tmp file, than appends 278# the error to the LOGFILE. 279# This complexity is required because of pipe's nature which prevents appending while piping into the log file. 280ifeq ($(LOGFILE),-) 281 exec_logged = $(1) 282 exec_logged_evaled = $(1) 283else 284 exec_logged = ( $(ECHO) $(shell date): "$(1)" >> $(LOGFILE) ; ( $(1) ) >>$(LOGFILE) 2>logerr.tmp ; err=$$? ; cat logerr.tmp ; cat logerr.tmp >> $(LOGFILE) ; rm logerr.tmp ; exit $$err) 285 # nested version is to be $(call)ed from within another $(eval) 286 exec_logged_evaled = ( $(ECHO) $$(shell date): "$(1)" >> $(LOGFILE) ; ( $(1) ) >>$(LOGFILE) 2>logerr.tmp ; err=$$$$? ; cat logerr.tmp ; cat logerr.tmp >> $(LOGFILE) ; rm logerr.tmp ; exit $$$$err) 287endif 288 289exec_logged_and_echo = $(ECHO) $(1) ; $(exec_logged) 290############ 291 292 293# Generate dependency on existence only (i.e., don't care if newer). 294# To be used primarily for directories creation 295DEPENDENCY_ON_EXISTENCE_OF = $(filter-out $(wildcard $(1)),$(1)) 296 297 298############ Special rules for project configuration selection ############## 299ifneq ($(wildcard $(PROJ_CFG_PATH)),$(PROJ_CFG_PATH)) # No proj.cfg linked 300 301all: # default in case there is no proj.cfg and setconfig_ was not used 302 $(info Invoke 'make setconfig_<config. name>' to select project configuration ) 303 $(error 'proj.cfg' not found) 304 305setconfig_%: $(PROJ_CONFIGS_DIR)/proj-%.cfg 306 @$(info [CFG] $(CONFIGS_PATH)/proj-$*.cfg --> proj.cfg) 307 @cd $(HOST_PROJ_ROOT) && ln -s $(CONFIGS_PATH)/proj-$*.cfg $(PROJ_CFG_FNAME) 308 @$(if $(findstring cc312,$<), $(if $(findstring integration_tests,$<),,$(if $(or $(findstring devel,$<), $(findstring llhw,$<)), make -C tests copy_infra_suite,)),) 309 310$(PROJ_CONFIGS_DIR)/proj-%.cfg: 311 @$(error Unknown project configuration. $@ does not exist.) 312 313clrconfig: 314 $(info [CFG-CLN] No active configuration ) 315 316.PHONY: all setconfig_% clrconfig 317 318else 319# default TEE_OS 320REE_OS ?= linux 321TEE_OS ?= cc_linux 322export REE_OS 323export TEE_OS 324#$(info REE_OS=$(REE_OS)) 325#$(info TEE_OS=$(TEE_OS)) 326 327#TestAL defs 328TESTAL_PATH_PAL = $(HOST_SRCDIR)/tests/infrastructure_suite/pal/lib 329TESTAL_PATH_HAL = $(HOST_SRCDIR)/tests/infrastructure_suite/hal/lib 330ifeq ($(ARM_CPU),cortex-a9) 331TESTAL_PAL_ARCH = ca9 332endif 333ifeq ($(ARM_CPU),cortex-m3) 334TESTAL_PAL_ARCH = cm3 335endif 336ifeq ($(ARM_CPU),cortex-m0plus) 337TESTAL_PAL_ARCH = cm0plus 338endif 339ifeq ($(ARM_CPU),cortex-m33) 340TESTAL_PAL_ARCH = cm33 341endif 342ifeq ($(ARCH),arm64) 343TESTAL_PAL_ARCH = ca72.ca53 344endif 345TESTAL_PAL_OS = $(subst cc_,,$(TEE_OS)) 346 347TESTAL_PAL_LIB = *PAL*$(TESTAL_PAL_OS)*$(CROSS_COMPILE)*$(TESTAL_PAL_ARCH)*.a 348TESTAL_HAL_LIB = *HAL*$(TESTAL_PAL_OS)*$(CROSS_COMPILE)*$(TESTAL_PAL_ARCH)*.a 349 350#Tests PAL HAL defs 351TESTS_PAL_LIB_NAME = libtests_pal.a 352TESTS_HAL_LIB_NAME = libtests_hal.a 353 354 355all: default 356 357# setconfig_/clrconfig are available only if $(PROJ_CONFIGS_DIR) exists 358# (i.e., eliminated on release trees) 359ifeq ($(wildcard $(PROJ_CONFIGS_DIR)),$(PROJ_CONFIGS_DIR)) 360# Configuration rules 361setconfig_%: 362 $(if $(filter $(CONFIGS_PATH)/proj-$*.cfg,$(shell readlink $(PROJ_CFG_PATH))),$(info $* configuration is already set.),$(error Before changing configuration invoke 'make clrconfig')) 363 364clrconfig: 365 @$(ECHO) [CFG-CLN] X $(shell readlink $(PROJ_CFG_PATH)) 366 @rm -f $(PROJ_CFG_PATH) 367 @$(ECHO) PROJ_NAME is $(PROJ_NAME) 368 @$(if $(findstring devel,$(PROJ_NAME)), echo calling clean_infra_suite && make -C tests clean_infra_suite, echo ff$(PROJ_NAME)ff clrconfig ) 369endif 370 371endif 372 373# Provide lsconfig to list available configurations 374configs_list = $(foreach cfg_file,$(wildcard $(PROJ_CONFIGS_DIR)/proj-*.cfg),$(patsubst $(PROJ_CONFIGS_DIR)/proj-%.cfg,%,$(cfg_file))) 375lsconfig: 376 @$(info Available project configurations:) 377 @$(foreach cfg_file,$(configs_list),$(info $(cfg_file))) 378 379.PHONY: all setconfig_% clrconfig lsconfig 380