1#------------------------------------------------------------------------------- 2# Copyright (c) 2001-2019, Arm Limited. All rights reserved. 3# 4# SPDX-License-Identifier: BSD-3-Clause 5# 6#------------------------------------------------------------------------------- 7 8# Make rules common to all Host components build 9# This file should be included at the end of a Makefile 10# (that included Makefile.defs at its beginning) 11 12# Including Makefile should provide (define before including this file): 13# TARGET_LIBS = Target library names (without extention) 14# TARGET_EXES = Target executables (without extention) 15# SOURCES_<target name> = The list of source files to create the binary target (currently assumes C) 16# OBJECTS_EXTRA_<target name> = Additional objects that should be linked but their build is defined outside of Makefile.rules 17# DEPLIBS = Dependency libraries for executable linking 18# PUBLIC_INCLUDES = The list of public include files to export from this module (if a library) 19# TEST_INCLUDES = The list of test include files to export from this module (if a library) 20# PUBLIC_SCRIPTS = List of scripts to be released to /bin 21# PUBLIC_DATA = List of data (binary?) files that should be released (primarily for tests) 22# CFLAGS_EXTRA = Additional compiler flags to append to default flags 23# INCDIRS_EXTRA = Additional include directories in addition to the default (current dir., Host/include, Shared/include) 24# LIBDIRS_EXTRA = Additional library directories in addition to the default 25# HOST_PROJ_ROOT = Relative or absolute path of project's root (trunks' root) 26# DEBUG = Set to '1 to enable debug compilation 27 28# Note: Avoid choosing the same name for a library and an executable 29#Test directories for freertos 30ifeq ($(TEE_OS),freertos) 31KERNEL_LIB_DIR = $(KERNEL_DIR)/lib 32KERNEL_TEST_DIR = $(KERNEL_DIR)/lib/tests 33endif 34 35### Compilation flags setup ### 36CFLAGS += -c -D$(ARCH_ENDIAN)__ENDIAN -DHASLONGLONG 37CFLAGS += $(foreach incdir,$(INCDIRS),-I$(incdir)) 38ARFLAGS = rcs 39MM = -MM 40ifeq ($(CROSS_COMPILE),arm-dsm-) 41CFLAGS += -I/cadtools/arm/arm_realview/RVCT/Data/2.2/349/include/unix -D__ARM_DSM__ 42else ifeq ($(CROSS_COMPILE),armcc) 43MM = --mm 44CFLAGS += -D__ARM_DS5__ --diag_error=warning #--strict --strict_warnings 45ARFLAGS = -rcs 46else ifeq ($(CROSS_COMPILE),arm) 47CFLAGS += -D__ARM_DS__ --c99 --strict --strict_warnings 48ARFLAGS = -rcs 49MM = --mm 50else ifeq ($(CROSS_COMPILE),armclang) 51CFLAGS += -Wall 52CFLAGS += -Wsign-compare 53CFLAGS += -Wextra 54CFLAGS += -Wpointer-arith 55CFLAGS += -Wcast-align 56CFLAGS += -Wstrict-prototypes 57CFLAGS += -Wwrite-strings 58CFLAGS += -Wswitch-default 59CFLAGS += -Wunreachable-code 60CFLAGS += -Winit-self 61CFLAGS += -Wmissing-field-initializers 62CFLAGS += -Werror=undef 63CFLAGS += -Werror -Wfatal-errors 64ARFLAGS = -rcs 65else 66CFLAGS += -Wall 67CFLAGS += -Wsign-compare 68CFLAGS += -Wextra 69CFLAGS += -Wpointer-arith 70CFLAGS += -Wcast-align 71CFLAGS += -Wstrict-prototypes 72CFLAGS += -Wwrite-strings 73CFLAGS += -Wswitch-default 74CFLAGS += -Wunreachable-code 75CFLAGS += -Winit-self 76CFLAGS += -Wjump-misses-init 77CFLAGS += -Wlogical-op 78CFLAGS += -Wmissing-field-initializers 79CFLAGS += -Werror=undef 80CFLAGS += -Werror -Wfatal-errors 81#CFLAGS += -finstrument-functions 82endif 83#CFLAGS += -D__STDC_VERSION__=19900L 84 85#ARFLAGS = rcs 86LDFLAGS = $(foreach libdir,$(LIBDIRS),-L$(libdir)) 87 88LDFLAGS += -Wl,--start-group 89LDFLAGS += $(foreach lib,$(DEPLIBS),-l$(lib)) 90LDFLAGS += -Wl,--end-group 91 92ifeq ($(CROSS_COMPILE),arm-none-eabi-) 93LDFLAGS += -lc -lm -lrdimon 94else 95ifneq ($(filter $(TEE_OS),no_os freertos),$(TEE_OS)) 96LDFLAGS += -lpthread 97endif 98endif 99 100ifneq ($(filter $(CROSS_COMPILE),arm-dsm- armcc),$(CROSS_COMPILE)) 101LDFLAGS += -Wl,-rpath=. 102endif 103 104# C++ compilation 105CXXFLAGS = $(CFLAGS) 106 107CFLAGS += -D__$(ARCH)__ 108 109# Library suffix 110LIB_TYPE ?= static 111ifeq ($(LIB_TYPE),dynamic) 112 ifeq ($(ARCH),x86win) 113 LIBEXT = .dll 114 # -fPIC not needed for x86win. 115 else 116 LIBEXT = .so 117 CFLAGS += -fPIC 118 endif 119else 120 LIBEXT = .a 121endif 122 123DEPLIBS_FILES = $(foreach lib, $(strip $(DEPLIBS)), $(shell find $(LIBDIRS) -name $(LIBPRE)$(lib)$(LIBEXT) 2>/dev/null)) 124 125#Optimization defs 126ifeq ($(DEBUG),1) 127 CFLAGS += -O0 -DDEBUG 128 ifeq ($(CROSS_COMPILE),armcc) 129 CFLAGS += -g 130 else 131 ifneq ($(CROSS_COMPILE),$(filter $(CROSS_COMPILE),arm-dsm- arm)) 132 CFLAGS += -g3 133 endif 134 endif 135else 136 CFLAGS += -O2 137endif 138 139# Support module specific extra Cflags 140CFLAGS += $(CFLAGS_EXTRA) 141 142### Top level targets ### 143 144default: release test 145 146# Clean only build intermediate files (incl. log file) but leave released target 147clean_intermediate: 148 -$(RMDIR) $(BUILDDIR) 149 -$(RM) $(LOGFILE) 150 151clean: clean_intermediate 152 -$(if $(TARGET_EXES), $(RM) $(foreach exe, $(TARGET_EXES), $(RELEASE_EXEDIR)/$(exe)$(EXEEXT))) 153 -$(if $(TARGET_LIBS),$(RM) $(foreach lib, $(TARGET_LIBS), $(RELEASE_LIBDIR)/$(LIBPRE)$(lib)$(LIBEXT))) 154 -$(if $(PUBLIC_INCLUDES),$(RM) $(foreach inc, $(PUBLIC_INCLUDES), $(RELEASE_INCDIR)/$(notdir $(inc)))) 155 -$(if $(subst freertos,,$(TEE_OS)),,$(if $(TEST_INCLUDES),$(RM) $(foreach inc, $(TEST_INCLUDES), $(KERNEL_TEST_DIR)/$(notdir $(inc))))) 156 -$(if $(PUBLIC_SCRIPTS),$(RM) $(foreach scr, $(PUBLIC_SCRIPTS), $(RELEASE_SCRDIR)/$(notdir $(scr)))) 157 -$(if $(PUBLIC_DATA),$(RM) $(foreach scr, $(PUBLIC_DATA), $(RELEASE_DATDIR)/$(notdir $(scr)))) 158 159.PHONY: default release test clean 160 161# Directory creation rule 162$(BUILDDIR) $(RELEASE_INCDIR) $(RELEASE_LIBDIR) $(RELEASE_EXEDIR) $(RELEASE_DATDIR): 163 @if [ ! -d $@ ] ; then $(ECHO) [MKDIR] $@ ; fi 164 @if [ ! -d $@ ] ; then $(call exec_logged,$(MKDIR) $@ ) ; fi 165 166# Makefile variable print (for debug) 167PRINT_VAR_%: 168 @$(ECHO) $* = \'$($*)\' 169 170### Generate rules for releasing (non-built resources) files 171define release_file_rule 172$(RELEASE_$(2)DIR)/$(notdir $(1)): $(1) $(call DEPENDENCY_ON_EXISTENCE_OF,$(RELEASE_$(2)DIR)) 173 @$(ECHO) [CP] $$< --\> $(RELEASE_$(2)DIR) 174 @$(call exec_logged_evaled,$(CP) $$< $(RELEASE_$(2)DIR) ) 175 176release: $(RELEASE_$(2)DIR)/$(notdir $(1)) 177 178endef 179 180define test_file_rule 181$(KERNEL_TEST_DIR)/$(notdir $(1)): $(1) 182 @$(ECHO) [CP] $$< --\> $(KERNEL_TEST_DIR) 183 @$(call exec_logged_evaled,$(CP) $$< $(KERNEL_TEST_DIR) ) 184 185test: $(KERNEL_TEST_DIR)/$(notdir $(1)) 186 187endef 188 189$(foreach hfile, $(PUBLIC_INCLUDES), $(eval $(call release_file_rule,$(hfile),INC))) 190$(if $(subst freertos,,$(TEE_OS)),,$(foreach hfile, $(TEST_INCLUDES), $(eval $(call test_file_rule,$(hfile),INC)))) 191$(foreach scrfile, $(PUBLIC_SCRIPTS), $(eval $(call release_file_rule,$(scrfile),SCR))) 192$(foreach datfile, $(PUBLIC_DATA), $(eval $(call release_file_rule,$(datfile),DAT))) 193 194### LIB+EXE targets rules ### 195release: $(TARGET_LIBS) $(TARGET_EXES) 196 197# Generic rule for LIB+EXE targets 198# Usage: $(eval $(call RELEASE_RULE, <target_name>, [LIB|EXE])) 199define RELEASE_RULE 200# Map named target to target with extension at release dir 201$(1): $(RELEASE_$(2)DIR)/$($(2)PRE)$(1)$($(2)EXT) 202 203.PHONY: $(1) 204 205# Objects list for dependency generation 206C_SOURCES_$(1) = $$(filter %.c,$$(SOURCES_$(1))) 207CPP_SOURCES_$(1) = $$(filter %.cpp,$$(SOURCES_$(1))) 208OBJECTS_FROM_C_$(1) = $$(addprefix $(BUILDDIR)/,$$(patsubst %.c,%$(OBJEXT),$$(filter-out $(BUILDDIR)/%,$$(C_SOURCES_$(1))))) 209OBJECTS_FROM_GENERATED_C_$(1) = $$(patsubst %.c,%$(OBJEXT),$$(filter $(BUILDDIR)/%,$$(C_SOURCES_$(1)))) 210OBJECTS_FROM_CPP_$(1) = $$(addprefix $(BUILDDIR)/,$$(patsubst %.cpp,%$(OBJEXT),$$(CPP_SOURCES_$(1)))) 211OBJECTS_INTERNAL_$(1) = $$(OBJECTS_FROM_C_$(1)) $$(OBJECTS_FROM_GENERATED_C_$(1)) $$(OBJECTS_FROM_CPP_$(1)) 212OBJECTS_$(1) = $$(OBJECTS_INTERNAL_$(1)) $$(OBJECTS_EXTRA_$(1)) 213OBJECTS_FROM_C += $$(OBJECTS_FROM_C_$(1)) 214OBJECTS_FROM_GENERATED_C += $$(OBJECTS_FROM_GENERATED_C_$(1)) 215OBJECTS_FROM_CPP += $$(OBJECTS_FROM_CPP_$(1)) 216 217# Retain generated dependency files after a build 218.SECONDARY: $$(OBJECTS_$(1):%.o=%.dep) 219 220endef 221 222# Generate library targets rules 223$(foreach lib,$(TARGET_LIBS), $(eval $(call RELEASE_RULE,$(lib),LIB))) 224#include generated depedencies 225$(foreach lib,$(TARGET_LIBS), $(eval -include $(OBJECTS_INTERNAL_$(lib):%.o=%.dep))) 226 227 228TEST_COPY_RULE = $(if $(PROJ_TESTS),$(call exec_logged,$(CP) $(RELEASE_LIBDIR)/$(1) $(KERNEL_TEST_DIR)/$(1)),) 229LIB_COPY_RULE = $(if $(PROJ_TESTS),$(call exec_logged,$(CP) $(RELEASE_LIBDIR)/$(1) $(KERNEL_LIB_DIR)/$(1)),) 230TEST_ECHO_RULE = $(ECHO) [CP] $(RELEASE_LIBDIR)/$(1) $< --\> $(KERNEL_TEST_DIR)/$(1) 231LIB_ECHO_RULE = $(ECHO) [CP] $(RELEASE_LIBDIR)/$(1) $< --\> $(KERNEL_LIB_DIR)/$(1) 232IS_TEST = $(findstring test, $(1)) 233 234# Implicit rule for libraries releasing 235$(RELEASE_LIBDIR)/$(LIBPRE)%$(LIBEXT): $(BUILDDIR)/$(LIBPRE)%$(LIBEXT) $(call DEPENDENCY_ON_EXISTENCE_OF,$(RELEASE_LIBDIR)) 236 @$(ECHO) [CP] $< --\> $(RELEASE_LIBDIR) 237 @$(call exec_logged,$(CP) $< $(RELEASE_LIBDIR) ) 238 @$(if $(subst freertos,,$(TEE_OS)),, $(if $(call IS_TEST,$(notdir $<)), $(call TEST_ECHO_RULE,$(notdir $<)), $(call LIB_ECHO_RULE,$(notdir $<)) )) 239 @$(if $(subst freertos,,$(TEE_OS)),, $(if $(call IS_TEST,$(notdir $<)), $(call TEST_COPY_RULE,$(notdir $<)), $(call LIB_COPY_RULE,$(notdir $<)) )) 240 @$(if $(subst freertos,,$(TEE_OS)),, $(foreach lib, $(DEPLIBS), $(ECHO) [CP] $(RELEASE_LIBDIR)/lib$(lib).a --\> $(KERNEL_LIB_DIR)/ ;)) 241 @$(if $(subst freertos,,$(TEE_OS)),, $(foreach lib, $(DEPLIBS), $(CP) $(RELEASE_LIBDIR)/lib$(lib).a $(KERNEL_LIB_DIR)/ ;)) 242 243ifeq ($(LIB_TYPE),dynamic) 244define LIB_LINK_RULE 245$(BUILDDIR)/$(LIBPRE)$(1)$(LIBEXT): $(OBJECTS_$(1)) 246 @$(if $(SOURCES_$(1)), , echo Makefile is missing SOURCES_$(1) definition && exit 1) 247 @$(ECHO) [LD] $$^ --\> $$@ # Dynamic library linkage 248 @$(call exec_logged_evaled,$(CC) -shared -o $$@ $$^ ) 249endef 250 251else # Static library 252define LIB_LINK_RULE 253$(BUILDDIR)/$(LIBPRE)$(1)$(LIBEXT): $(OBJECTS_$(1)) 254 @$(if $(SOURCES_$(1)), , echo Makefile is missing SOURCES_$(1) definition && exit 1) 255 @$(ECHO) [AR] $$^ --\> $$@ # Library archive linkage 256 @$(call exec_logged_evaled,$(AR) $(ARFLAGS) $$@ $$^ ) 257endef 258endif 259 260$(foreach lib,$(TARGET_LIBS), $(eval $(call LIB_LINK_RULE,$(lib)))) 261 262 263# Generate executable targets rules 264$(foreach exe,$(TARGET_EXES), $(eval $(call RELEASE_RULE,$(exe),EXE))) 265#include generated depedencies 266$(foreach exe,$(TARGET_EXES), $(eval -include $(OBJECTS_INTERNAL_$(exe):%.o=%.dep))) 267# Implicit rule for executables releasing 268$(RELEASE_EXEDIR)/%$(EXEEXT): $(BUILDDIR)/%$(EXEEXT) $(call DEPENDENCY_ON_EXISTENCE_OF,$(RELEASE_EXEDIR)) 269 @$(ECHO) [CP] $< --\> $(RELEASE_EXEDIR) 270 @$(call exec_logged,$(CP) $< $(RELEASE_EXEDIR) ) 271 272define EXE_LINK_RULE 273$(BUILDDIR)/$(1)$(EXEEXT): $(OBJECTS_$(1)) $(DEPLIBS_FILES) 274 @$(if $(SOURCES_$(1)), , echo Makefile is missing SOURCES_$(1) definition && exit 1) 275 @$(ECHO) [LD] $$^ --\> $$@ # Executable linkage 276 @$(call exec_logged_evaled,$(LD) $$(filter-out %$(LIBEXT),$$^) $(LDFLAGS) -o $$@ ) 277endef 278$(foreach exe,$(TARGET_EXES), $(eval $(call EXE_LINK_RULE,$(exe)))) 279 280ifneq ($(OBJECTS_FROM_C),) 281# Default implicit compile rule assuming C source code (+dependency generation) 282$(OBJECTS_FROM_C): $(BUILDDIR)/%$(OBJEXT): %.c $(call DEPENDENCY_ON_EXISTENCE_OF,$(BUILDDIR)) $(addprefix $(RELEASE_INCDIR)/,$(notdir ${PUBLIC_INCLUDES})) 283 @$(ECHO) [CC] $< --\> $@ # Compilation 284 @$(call exec_logged,$(CC) $(CFLAGS) $< -o $@ ) 285 @#$(ECHO) [MM] $(@:.o=.dep) \<-- $@ # Generate dependency of object when generated 286 @$(call exec_logged,$(CC) $(MM) $(CFLAGS) $< | sed 's~.*\.o:~$(BUILDDIR)/&~' > $(BUILDDIR)/$*.dep ) 287 288# $(call exec_logged,$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; [ -s $@ ] || rm -f $@' ) 289endif 290 291ifneq ($(OBJECTS_FROM_CPP),) 292# Default implicit compile rule assuming C++ source code (+dependency generation) 293$(OBJECTS_FROM_CPP): $(BUILDDIR)/%$(OBJEXT): %.cpp $(call DEPENDENCY_ON_EXISTENCE_OF,$(BUILDDIR)) $(addprefix $(RELEASE_INCDIR)/,$(notdir ${PUBLIC_INCLUDES})) 294 @$(ECHO) [CPP] $< --\> $@ # Compilation 295 @$(call exec_logged,$(CPP) $(CPPFLAGS) $< -o $@ ) 296 @#$(ECHO) [MM] $(@:.o=.dep) \<-- $@ # Generate dependency of object when generated 297 @$(call exec_logged,$(CP) -MM $(CPPFLAGS) $< | sed 's~.*\.o:~$(BUILDDIR)/&~' > $(BUILDDIR)/$*.dep ) 298endif 299 300ifneq ($(OBJECTS_FROM_GENERATED_C),) 301# Default implicit compile rule assuming generated C stub source code (+dependency generation) 302$(OBJECTS_FROM_GENERATED_C): $(BUILDDIR)/%$(OBJEXT): $(PWD)/$(BUILDDIR)/%.c $(addprefix $(RELEASE_INCDIR)/,$(notdir ${PUBLIC_INCLUDES})) 303 @$(ECHO) [CC4GEN] $< --\> $@ # Compilation 304 @$(call exec_logged,$(CC) $(CFLAGS) $< -o $@ ) 305 @#$(ECHO) [MM] $(@:.o=.dep) \<-- $@ # Generate dependency of object when generated 306 @$(call exec_logged,$(CC) -MM $(CFLAGS) $< | sed 's~.*\.o:~$(BUILDDIR)/&~' > $(BUILDDIR)/$*.dep ) 307endif 308 309 310