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