xref: /aosp_15_r20/external/coreboot/payloads/libpayload/Makefile (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1##
2##
3## Copyright (C) 2008 Advanced Micro Devices, Inc.
4## Copyright (C) 2008 Uwe Hermann <[email protected]>
5## Copyright (C) 2009-2010 coresystems GmbH
6## Copyright (C) 2011 secunet Security Networks AG
7##
8## Redistribution and use in source and binary forms, with or without
9## modification, are permitted provided that the following conditions
10## are met:
11## 1. Redistributions of source code must retain the above copyright
12##    notice, this list of conditions and the following disclaimer.
13## 2. Redistributions in binary form must reproduce the above copyright
14##    notice, this list of conditions and the following disclaimer in the
15##    documentation and/or other materials provided with the distribution.
16## 3. The name of the author may not be used to endorse or promote products
17##    derived from this software without specific prior written permission.
18##
19## THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22## ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29## SUCH DAMAGE.
30##
31
32ifneq ($(words $(CURDIR)),1)
33	$(error ERROR: Path to the main directory cannot contain spaces)
34endif
35
36ifeq ($(INNER_SCANBUILD),y)
37CC_real:=$(CC)
38endif
39
40export top := $(CURDIR)
41export coreboottop ?= $(abspath $(top)/../../)
42export src := src
43export srck := $(abspath $(top)/../../util/kconfig)
44export obj ?= build
45export objutil ?= $(obj)/util
46export objk := $(objutil)/lp_kconfig
47export absobj := $(abspath $(obj))
48VBOOT_SOURCE ?= $(coreboottop)/3rdparty/vboot
49
50export KCONFIG_AUTOHEADER := $(obj)/config.h
51export KCONFIG_AUTOCONFIG := $(obj)/auto.conf
52export KCONFIG_DEPENDENCIES := $(obj)/auto.conf.cmd
53export KCONFIG_SPLITCONFIG := $(obj)/config/
54export KCONFIG_TRISTATE := $(obj)/tristate.conf
55export KCONFIG_NEGATIVES := 1
56export KBUILD_KCONFIG := Kconfig
57export CONFIG_ := CONFIG_LP_
58
59# directory containing the toplevel Makefile.mk
60TOPLEVEL := .
61
62CONFIG_LP_SHELL := sh
63KBUILD_DEFCONFIG ?= configs/defconfig
64UNAME_RELEASE := $(shell uname -r)
65DOTCONFIG ?= .config
66KCONFIG_CONFIG = $(DOTCONFIG)
67export KCONFIG_CONFIG
68HAVE_DOTCONFIG := $(wildcard $(DOTCONFIG))
69MAKEFLAGS += -rR --no-print-directory
70
71# Make is silent per default, but 'make V=1' will show all compiler calls.
72Q:=@
73ifneq ($(V),1)
74ifneq ($(Q),)
75.SILENT:
76endif
77endif
78
79CPP:= $(CC) -x assembler-with-cpp -DASSEMBLY -E
80HOSTCC = gcc
81HOSTCXX = g++
82HOSTCFLAGS := -I$(srck) -I$(objk) -g
83HOSTCXXFLAGS := -I$(srck) -I$(objk)
84HOSTAS ?= as
85HOSTLD ?= ld
86HOSTNM ?= nm
87HOSTOBJCOPY ?= objcopy
88HOSTOBJDUMP ?= objdump
89HOSTREADELF ?= readelf
90HOSTSTRIP ?= strip
91HOSTAR ?= ar
92
93DOXYGEN := doxygen
94DOXYGEN_OUTPUT_DIR := doxygen
95
96all: real-all
97
98ifeq ($(INNER_SCANBUILD),y)
99CC:=$(CC_real)
100HOSTCC:=$(CC_real) --hostcc
101HOSTCXX:=$(CC_real) --hostcxx
102endif
103
104# This include must come _before_ the pattern rules below!
105# Order _does_ matter for pattern rules.
106include $(srck)/Makefile.mk
107
108include $(HAVE_DOTCONFIG)
109
110ARCHDIR-$(CONFIG_LP_ARCH_ARM)     := arm
111ARCHDIR-$(CONFIG_LP_ARCH_ARM64)   := arm64
112ARCHDIR-$(CONFIG_LP_ARCH_X86)     := x86
113ARCHDIR-$(CONFIG_LP_ARCH_MOCK)    := mock
114
115ARCH-y := $(ARCHDIR-y)
116
117# If architecture folder name is different from xcompile architecture name,
118# override here.
119ARCH-$(CONFIG_LP_ARCH_ARM)     := arm
120ARCH-$(CONFIG_LP_ARCH_ARM64)   := arm64
121ARCH-$(CONFIG_LP_ARCH_X86_32)  := x86_32
122ARCH-$(CONFIG_LP_ARCH_X86_64)  := x86_64
123ARCH-$(CONFIG_LP_ARCH_MOCK)    := mock
124
125# Five cases where we don't need fully populated $(obj) lists:
126# 1. when no .config exists
127# 2. when make config (in any flavour) is run
128# 3. when make distclean is run
129# 4. when make help% or make clean% is run
130# 5. when make %-test or make %-tests or make %coverage-report is run
131# Don't waste time on reading all Makefiles in these cases
132ifeq ($(strip $(HAVE_DOTCONFIG)),)
133NOCOMPILE := 1
134endif
135ifneq ($(MAKECMDGOALS),)
136ifneq ($(filter %config %clean clean-% help%,$(MAKECMDGOALS)),)
137NOCOMPILE := 1
138endif
139ifneq ($(filter %clean help% clean%, $(MAKECMDGOALS)),)
140UNIT_TEST := 1
141endif
142endif
143
144ifneq ($(filter help%, $(MAKECMDGOALS)),)
145NOCOMPILE := 1
146UNIT_TEST := 1
147else
148ifneq ($(filter %-test %-tests %coverage-report, $(MAKECMDGOALS)),)
149ifneq ($(filter-out %-test %-tests %coverage-report, $(MAKECMDGOALS)),)
150$(error Cannot mix unit-tests targets with other targets)
151endif
152NOCOMPILE :=
153UNIT_TEST := 1
154endif
155endif
156
157xcompile ?= $(obj)/xcompile
158$(xcompile): $(top)/../../util/xcompile/xcompile
159	$< $(XGCCPATH) > $@.tmp
160	\mv -f $@.tmp $@ 2> /dev/null
161
162ifeq ($(NOCOMPILE),1)
163include $(TOPLEVEL)/Makefile.mk
164include $(TOPLEVEL)/tests/Makefile.mk
165real-all: config
166
167else
168
169ifeq ($(CONFIG_LP_ARCH_MOCK),y)
170
171# Create empty xcompile to satisfy install script
172$(shell echo '' > $(xcompile))
173
174CC := $(HOSTCC)
175CC-mock := $(HOSTCC)
176AS := $(HOSTAS)
177AS-mock := $(HOSTAS)
178LD := $(HOSTLD)
179LD-mock := $(HOSTLD)
180NM := $(HOSTNM)
181NM-mock := $(HOSTNM)
182OBJCOPY := $(HOSTOBJCOPY)
183OBJCOPY-mock := $(HOSTOBJCOPY)
184OBJDUMP := $(HOSTOBJDUMP)
185OBJDUMP-mock := $(HOSTOBJDUMP)
186READELF := $(HOSTREADELF)
187READELF-mock := $(HOSTEADELF)
188STRIP := $(HOSTSTRIP)
189STRIP-mock := $(HOSTSTRIP)
190AR := $(HOSTAR)
191AR-mock := $(HOSTAR)
192else
193
194# in addition to the dependency below, create the file if it doesn't exist
195# to silence stupid warnings about a file that would be generated anyway.
196$(if $(wildcard $(xcompile)),,$(shell	\
197	mkdir -p $(dir $(xcompile)) &&	\
198	$(top)/../../util/xcompile/xcompile $(XGCCPATH) > $(xcompile) || rm -f $(xcompile)))
199
200include $(xcompile)
201
202ifneq ($(XCOMPILE_COMPLETE),1)
203$(shell rm -f $(xcompile))
204$(error $(xcompile) deleted because it's invalid. \
205	Restarting the build should fix that, or explain the problem)
206endif
207
208CC := $(CC_$(ARCH-y))
209AS := $(AS_$(ARCH-y))
210LD := $(LD_$(ARCH-y))
211NM := $(NM_$(ARCH-y))
212OBJCOPY := $(OBJCOPY_$(ARCH-y))
213OBJDUMP := $(OBJDUMP_$(ARCH-y))
214READELF := $(READELF_$(ARCH-y))
215STRIP := $(STRIP_$(ARCH-y))
216AR := $(AR_$(ARCH-y))
217endif
218
219CFLAGS += -std=gnu11 $(CFLAGS_$(ARCH-y))
220
221ifneq ($(INNER_SCANBUILD),y)
222ifeq ($(CONFIG_LP_COMPILER_LLVM_CLANG),y)
223CC:=clang
224ifneq ($(CONFIG_LP_ARCH_MOCK),y)
225CC += -m32
226endif
227HOSTCC:=clang
228endif
229endif
230
231ifeq ($(CONFIG_LP_CCACHE),y)
232CCACHE:=$(word 1,$(wildcard $(addsuffix /ccache,$(subst :, ,$(PATH)))))
233ifeq ($(CCACHE),)
234$(error ccache selected, but not found in PATH)
235endif
236CCACHE:=CCACHE_COMPILERCHECK=content CCACHE_BASEDIR=$(top) $(CCACHE)
237CC := $(CCACHE) $(CC)
238HOSTCC := $(CCACHE) $(HOSTCC)
239HOSTCXX := $(CCACHE) $(HOSTCXX)
240endif
241
242strip_quotes = $(subst ",,$(subst \",,$(1)))
243
244# The primary target needs to be here before we include the
245# other files
246
247ifeq ($(INNER_SCANBUILD),y)
248CONFIG_LP_SCANBUILD_ENABLE:=
249endif
250
251ifeq ($(CONFIG_LP_SCANBUILD_ENABLE),y)
252ifneq ($(CONFIG_LP_SCANBUILD_REPORT_LOCATION),)
253CONFIG_LP_SCANBUILD_REPORT_LOCATION:=-o $(CONFIG_LP_SCANBUILD_REPORT_LOCATION)
254endif
255real-all:
256	echo '#!/bin/sh' > .ccwrap
257	echo 'CC="$(CC)"' >> .ccwrap
258	echo 'if [ "$$1" = "--hostcc" ]; then shift; CC="$(HOSTCC)"; fi' >> .ccwrap
259	echo 'if [ "$$1" = "--hostcxx" ]; then shift; CC="$(HOSTCXX)"; fi' >> .ccwrap
260	echo 'eval $$CC $$*' >> .ccwrap
261	chmod +x .ccwrap
262	scan-build $(CONFIG_LP_SCANBUILD_REPORT_LOCATION) -analyze-headers --use-cc=$(top)/.ccwrap --use-c++=$(top)/.ccwrap $(MAKE) INNER_SCANBUILD=y
263else
264real-all: real-target
265endif
266
267# must come rather early
268.SECONDEXPANSION:
269
270$(KCONFIG_AUTOHEADER): $(KCONFIG_CONFIG)
271	$(MAKE) CONFIG_=CONFIG_LP_ olddefconfig
272	$(MAKE) CONFIG_=CONFIG_LP_ syncconfig
273
274# Add a new class of source/object files to the build system
275add-class= \
276	$(eval $(1)-srcs:=) \
277	$(eval $(1)-objs:=) \
278	$(eval classes+=$(1))
279
280# Special classes are managed types with special behaviour
281# On parse time, for each entry in variable $(1)-y
282# a handler $(1)-handler is executed with the arguments:
283# * $(1): directory the parser is in
284# * $(2): current entry
285add-special-class= \
286	$(eval $(1):=) \
287	$(eval special-classes+=$(1))
288
289# Clean -y variables, include Makefile.mk
290# Add paths to files in X-y to X-srcs
291# Add subdirs-y to subdirs
292includemakefiles= \
293	$(foreach class,classes subdirs $(classes) $(special-classes), $(eval $(class)-y:=)) \
294	$(eval -include $(1)) \
295	$(foreach class,$(classes-y), $(call add-class,$(class))) \
296	$(foreach special,$(special-classes), \
297		$(foreach item,$($(special)-y), $(call $(special)-handler,$(dir $(1)),$(item)))) \
298	$(foreach class,$(classes), \
299		$(eval $(class)-srcs+= \
300			$$(subst $(absobj)/,$(obj)/, \
301			$$(subst $(top)/,, \
302			$$(abspath $$(subst $(dir $(1))/,/,$$(addprefix $(dir $(1)),$$($(class)-y)))))))) \
303	$(eval subdirs+=$$(subst $(CURDIR)/,,$$(wildcard $$(abspath $$(addprefix $(dir $(1)),$$(subdirs-y))))))
304
305
306# For each path in $(subdirs) call includemakefiles
307# Repeat until subdirs is empty
308evaluate_subdirs= \
309	$(eval cursubdirs:=$(subdirs)) \
310	$(eval subdirs:=) \
311	$(foreach dir,$(cursubdirs), \
312		$(eval $(call includemakefiles,$(dir)/Makefile.mk))) \
313	$(if $(subdirs),$(eval $(call evaluate_subdirs)))
314
315# collect all object files eligible for building or run unit-tests
316ifneq ($(UNIT_TEST),1)
317subdirs:=$(TOPLEVEL)
318$(eval $(call evaluate_subdirs))
319else
320include $(TOPLEVEL)/tests/Makefile.mk
321endif
322
323# Converts one or more source file paths to the corresponding build/ paths.
324# $1 lib name
325# $2 file path (list)
326src-to-obj=\
327	$(addsuffix .$(1).o,\
328	$(basename \
329	$(addprefix $(obj)/,\
330	$(subst $(coreboottop)/,coreboot/,$(2)))))
331$(foreach class,$(classes),$(eval $(class)-objs+=$(call src-to-obj,$(class),$($(class)-srcs))))
332
333allsrcs:=$(foreach var, $(addsuffix -srcs,$(classes)), $($(var)))
334allobjs:=$(foreach var, $(addsuffix -objs,$(classes)), $($(var)))
335alldirs:=$(sort $(abspath $(dir $(allobjs))))
336
337# macro to define template macros that are used by use_template macro
338define create_cc_template
339# $1 obj class
340# $2 source suffix (c, S)
341# $3 additional compiler flags
342# $4 additional dependencies
343ifn$(EMPTY)def $(1)-objs_$(2)_template
344de$(EMPTY)fine $(1)-objs_$(2)_template
345$$(call src-to-obj,$(1), $$(1).$(2)): $$(1).$(2) $(obj)/libpayload-config.h $(4)
346	@printf "    CC         $$$$(subst $$$$(obj)/,,$$$$(@))\n"
347	$(CC) $(3) -MMD $$$$(CFLAGS) $(EXTRA_CFLAGS) -c -o $$$$@ $$$$<
348en$(EMPTY)def
349end$(EMPTY)if
350endef
351
352filetypes-of-class=$(subst .,,$(sort $(suffix $($(1)-srcs))))
353$(foreach class,$(classes), \
354	$(foreach type,$(call filetypes-of-class,$(class)), \
355		$(eval $(call create_cc_template,$(class),$(type),$($(class)-$(type)-ccopts),$($(class)-$(type)-deps)))))
356
357foreach-src=$(foreach file,$($(1)-srcs),$(eval $(call $(1)-objs_$(subst .,,$(suffix $(file)))_template,$(basename $(file)))))
358$(eval $(foreach class,$(classes),$(call foreach-src,$(class))))
359
360DEPENDENCIES = $($(filter %.o,%(allobjs)):.o=.d)
361-include $(DEPENDENCIES)
362
363printall:
364	@$(foreach class,$(classes),echo $(class)-objs:=$($(class)-objs); )
365	@echo alldirs:=$(alldirs)
366	@echo allsrcs=$(allsrcs)
367	@echo DEPENDENCIES=$(DEPENDENCIES)
368	@$(foreach class,$(special-classes),echo $(class):='$($(class))'; )
369
370endif
371
372$(shell mkdir -p $(KCONFIG_SPLITCONFIG) $(obj) $(objk)/lxdialog $(additional-dirs) $(alldirs))
373
374cscope:
375	cscope -bR
376
377doxy: doxygen
378doxygen:
379	$(DOXYGEN) Doxyfile
380
381doxyclean: doxygen-clean
382doxygen-clean:
383	rm -rf $(DOXYGEN_OUTPUT_DIR)
384
385clean-for-update: doxygen-clean clean-for-update-target
386	rm -f $(allobjs) $(xcompile)
387	rm -f $(DEPENDENCIES)
388	rmdir -p $(alldirs) 2>/dev/null >/dev/null || true
389
390clean: clean-for-update clean-target
391	rm -f .ccwrap junit_config junit_config.old
392	rm -rf $(obj)
393
394clean-cscope:
395	rm -f cscope.out
396
397distclean: clean-cscope clean
398	rm -f .config .config.old ..config.tmp .kconfig.d .tmpconfig* .ccwrap .xcompile junit.xml
399
400.PHONY: $(PHONY) clean clean-cscope cscope distclean doxygen doxy
401