1# Copyright 2016 The Fuchsia Authors
2# Copyright (c) 2008-2015 Travis Geiselbrecht
3#
4# Use of this source code is governed by a MIT-style
5# license that can be found in the LICENSE file or at
6# https://opensource.org/licenses/MIT
7
8
9# modules
10#
11# args:
12# MODULE : module name (required)
13# MODULE_SRCS : list of source files, local path (required)
14# MODULE_DEPS : other modules that this one depends on
15# MODULE_HEADER_DEPS : other headers that this one depends on, in addition to MODULE_DEPS
16# MODULE_DEFINES : #defines local to this module
17# MODULE_OPTFLAGS : OPTFLAGS local to this module
18# MODULE_COMPILEFLAGS : COMPILEFLAGS local to this module
19# MODULE_CFLAGS : CFLAGS local to this module
20# MODULE_CPPFLAGS : CPPFLAGS local to this module
21# MODULE_ASMFLAGS : ASMFLAGS local to this module
22# MODULE_SRCDEPS : extra dependencies that all of this module's files depend on
23# MODULE_EXTRA_OBJS : extra .o files that should be linked with the module
24# MODULE_TYPE : "userapp" for userspace executables
25#               "userlib" for userspace library,
26#               "driver" for Zircon driver
27#               "hostapp" for a host tool,
28#               "hosttest" for a host test,
29#               "hostlib" for a host library,
30#               "" for kernel,
31# MODULE_LIBS : shared libraries for a userapp or userlib to depend on
32# MODULE_STATIC_LIBS : static libraries for a userapp or userlib to depend on
33# MODULE_FIDL_LIBS : fidl libraries for a userapp or userlib to depend on the C bindings of
34# MODULE_FIDL_LIBRARY : the name of the FIDL library being built (for fidl modules)
35# MODULE_BANJO_LIBS : banjo libraries for a userapp or userlib to depend on the C bindings of
36# MODULE_BANJO_LIBRARY : the name of the BANJO library being built (for banjo modules)
37# MODULE_FIRMWARE : files under prebuilt/downloads/firmware/ to be installed under /boot/driver/firmware/
38# MODULE_SO_NAME : linkage name for the shared library
39# MODULE_HOST_LIBS: static libraries for a hostapp or hostlib to depend on
40# MODULE_HOST_SYSLIBS: system libraries for a hostapp or hostlib to depend on
41# MODULE_GROUP: tag for manifest file entry
42# MODULE_PACKAGE: package type (src, fidl, banjo, so, a) for module to export to SDK
43# MODULE_PACKAGE_SRCS: override automated package source file selection, or the special
44#                      value "none" for header-only libraries
45# MODULE_PACKAGE_INCS: override automated package include file selection
46
47# the minimum module rules.mk file is as follows:
48#
49# LOCAL_DIR := $(GET_LOCAL_DIR)
50# MODULE := $(LOCAL_DIR)
51#
52# MODULE_SRCS := $(LOCAL_DIR)/at_least_one_source_file.c
53#
54# include make/module.mk
55
56# Remove any .postfix bits for submodules to find our source directory
57MODULE_SRCDIR := $(firstword $(subst .,$(SPACE),$(MODULE)))
58
59# If there's not a rules.mk that corresponds to our srcdir,
60# something fishy is going on
61ifeq ($(wildcard $(MODULE_SRCDIR)/rules.mk),)
62$(error Module '$(MODULE)' missing $(MODULE_SRCDIR)/rules.mk)
63endif
64
65# Catch the "defined a module twice" failure case as soon
66# as possible, so it's easier to understand.
67ifneq ($(filter $(MODULE),$(DUPMODULES)),)
68$(error Module '$(MODULE)' defined in multiple rules.mk files)
69endif
70DUPMODULES += $(MODULE)
71
72# if there's a manifest group, remove whitespace and wrap it in {}s
73ifneq ($(strip $(MODULE_GROUP)),)
74MODULE_GROUP := {$(strip $(MODULE_GROUP))}
75else ifeq ($(MODULE_TYPE),driver)
76MODULE_GROUP := {core}
77else ifeq ($(MODULE_TYPE),userlib)
78MODULE_GROUP := {libs}
79else ifneq (,$(filter usertest drivertest fuzztest,$(MODULE_TYPE)))
80MODULE_GROUP := {test}
81endif
82
83# all library deps go on the deps list
84_MODULE_DEPS := $(MODULE_DEPS) $(MODULE_LIBS) $(MODULE_STATIC_LIBS) \
85                $(MODULE_HOST_LIBS) $(MODULE_FIDL_LIBS) $(MODULE_FIDL_DEPS) \
86                $(MODULE_BANJO_LIBS) $(MODULE_BANJO_DEPS)
87
88# Catch the depends on nonexistant module error case
89# here where we can tell you what module has the bad deps.
90# Strip any .postfixes, as these refer to "sub-modules" defined in the
91# rules.mk file of the base module name.
92$(foreach mod,$(_MODULE_DEPS) $(MODULE_HEADER_DEPS),\
93$(if $(wildcard $(firstword $(subst .,$(SPACE),$(mod)))),,\
94$(error Module '$(MODULE)' depends on '$(mod)' which does not exist)))
95
96# all regular deps contribute to header deps list
97MODULE_HEADER_DEPS += $(_MODULE_DEPS)
98
99# use sort to de-duplicate our deps list
100_MODULE_DEPS := $(sort $(_MODULE_DEPS))
101MODULE_HEADER_DEPS := $(sort $(MODULE_HEADER_DEPS))
102
103# add the module deps to the global list
104MODULES += $(_MODULE_DEPS)
105
106MODULE_BUILDDIR := $(call TOBUILDDIR,$(MODULE))
107MODULE_GENDIR := $(MODULE_BUILDDIR)/gen
108
109# MODULE_NAME is used to generate installed names
110# it defaults to being derived from the MODULE directory
111ifeq ($(MODULE_NAME),)
112MODULE_NAME := $(lastword $(subst /,$(SPACE),$(MODULE)))
113endif
114
115# Introduce local, libc and dependency include paths
116ifneq ($(MODULE_TYPE),)
117ifeq ($(MODULE_TYPE),$(filter $(MODULE_TYPE),hostapp hosttest hostlib))
118# host module
119MODULE_SRCDEPS += $(HOST_CONFIG_HEADER)
120MODULE_COMPILEFLAGS += -I$(LOCAL_DIR)/include
121else
122# user module
123MODULE_SRCDEPS += $(USER_CONFIG_HEADER)
124MODULE_COMPILEFLAGS += -Iglobal/include
125MODULE_COMPILEFLAGS += -I$(LOCAL_DIR)/include
126MODULE_COMPILEFLAGS += -Ithird_party/ulib/musl/include
127MODULE_DEFINES += MODULE_LIBS=\"$(subst $(SPACE),_,$(MODULE_LIBS))\"
128MODULE_DEFINES += MODULE_STATIC_LIBS=\"$(subst $(SPACE),_,$(MODULE_STATIC_LIBS) $(MODULE_FIDL_LIBS))\"
129
130# depend on the generated-headers of the modules we depend on
131# to insure they are generated before we are built
132MODULE_SRCDEPS += $(patsubst %,$(BUILDDIR)/%/gen-hdr.stamp,$(_MODULE_DEPS))
133
134endif
135MODULE_COMPILEFLAGS += $(foreach DEP,$(MODULE_HEADER_DEPS),-I$(DEP)/include)
136MODULE_COMPILEFLAGS += $(foreach DEP,$(MODULE_HEADER_DEPS),-I$(call TOBUILDDIR,$(DEP))/gen/include)
137#TODO: is this right?
138MODULE_SRCDEPS += $(USER_CONFIG_HEADER)
139else
140# kernel module
141# add a local include dir to the global include path for kernel code
142KERNEL_INCLUDES += $(MODULE_SRCDIR)/include
143MODULE_SRCDEPS += $(KERNEL_CONFIG_HEADER)
144endif
145
146#$(info module $(MODULE))
147#$(info MODULE_SRCDIR $(MODULE_SRCDIR))
148#$(info MODULE_BUILDDIR $(MODULE_BUILDDIR))
149#$(info MODULE_DEPS $(MODULE_DEPS))
150#$(info MODULE_SRCS $(MODULE_SRCS))
151
152MODULE_DEFINES += MODULE_COMPILEFLAGS=\"$(subst $(SPACE),_,$(sort $(MODULE_COMPILEFLAGS)))\"
153MODULE_DEFINES += MODULE_CFLAGS=\"$(subst $(SPACE),_,$(sort $(MODULE_CFLAGS)))\"
154MODULE_DEFINES += MODULE_CPPFLAGS=\"$(subst $(SPACE),_,$(sort $(MODULE_CPPFLAGS)))\"
155MODULE_DEFINES += MODULE_ASMFLAGS=\"$(subst $(SPACE),_,$(sort $(MODULE_ASMFLAGS)))\"
156MODULE_DEFINES += MODULE_OPTFLAGS=\"$(subst $(SPACE),_,$(sort $(MODULE_OPTFLAGS)))\"
157MODULE_DEFINES += MODULE_LDFLAGS=\"$(subst $(SPACE),_,$(sort $(MODULE_LDFLAGS)))\"
158MODULE_DEFINES += MODULE_SRCDEPS=\"$(subst $(SPACE),_,$(sort $(MODULE_SRCDEPS)))\"
159MODULE_DEFINES += MODULE_DEPS=\"$(subst $(SPACE),_,$(sort $(MODULE_DEPS)))\"
160MODULE_DEFINES += MODULE_SRCS=\"$(subst $(SPACE),_,$(sort $(MODULE_SRCS)))\"
161MODULE_DEFINES += MODULE_HEADER_DEPS=\"$(subst $(SPACE),_,$(sort $(MODULE_HEADER_DEPS)))\"
162MODULE_DEFINES += MODULE_TYPE=\"$(subst $(SPACE),_,$(MODULE_TYPE))\"
163
164# generate a per-module config.h file
165MODULE_CONFIG := $(MODULE_BUILDDIR)/config-module.h
166
167# base name for the generated binaries, libraries, etc
168MODULE_OUTNAME := $(MODULE_BUILDDIR)/$(notdir $(MODULE))
169
170# base name for libraries
171MODULE_LIBNAME := $(MODULE_BUILDDIR)/lib$(notdir $(MODULE))
172
173$(MODULE_CONFIG): MODULE_DEFINES:=$(MODULE_DEFINES)
174$(MODULE_CONFIG): FORCE
175	@$(call MAKECONFIGHEADER,$@,MODULE_DEFINES)
176
177GENERATED += $(MODULE_CONFIG)
178
179MODULE_COMPILEFLAGS += -include $(MODULE_CONFIG)
180
181MODULE_SRCDEPS += $(MODULE_CONFIG)
182
183ifeq ($(call TOBOOL,$(ENABLE_ULIB_ONLY)),true)
184# Build all userlib modules, and also always build devhost, which is
185# sort of like an inside-out userlib (drivers need their devhost like
186# executables need their shared libraries).  Elide everything else.
187MODULE_ELIDED := \
188	$(call TOBOOL,$(filter-out userlib:% fidl:% banjo:% userapp:system/core/devmgr.host,\
189			       $(MODULE_TYPE):$(MODULE)))
190else
191MODULE_ELIDED := false
192endif
193
194ifeq ($(MODULE_ELIDED),true)
195
196# Ignore additions just made by this module.
197EXTRA_BUILDDEPS := $(SAVED_EXTRA_BUILDDEPS)
198GENERATED := $(SAVED_GENERATED)
199USER_MANIFEST_LINES := $(SAVED_USER_MANIFEST_LINES)
200
201else # MODULE_ELIDED
202
203# list of generated public headers, asssmbled by */*compile.mk
204MODULE_GEN_HDR :=
205
206# include compile rules appropriate to module type
207# typeless modules are kernel modules
208ifeq ($(MODULE_TYPE),)
209include make/compile.mk
210else
211ifeq ($(MODULE_TYPE),$(filter $(MODULE_TYPE),hostapp hosttest hostlib))
212include make/hcompile.mk
213else
214ifeq ($(MODULE_TYPE),efilib)
215include make/ecompile.mk
216else
217ifeq ($(MODULE_TYPE),fidl)
218include make/fcompile.mk
219else
220ifeq ($(MODULE_TYPE),banjo)
221include make/bcompile.mk
222else
223include make/ucompile.mk
224endif
225endif
226endif
227endif
228endif
229
230# MODULE_OBJS is passed back from *compile.mk
231#$(info MODULE_OBJS = $(MODULE_OBJS))
232
233$(MODULE_BUILDDIR)/gen-hdr.stamp: $(MODULE_GEN_HDR)
234	@$(MKDIR)
235	@touch $@
236
237# track all of the source files compiled
238ALLSRCS += $(MODULE_SRCS)
239
240# track all the objects built
241ALLOBJS += $(MODULE_OBJS)
242
243ifeq (,$(filter $(MODULE_TYPE),hostapp hosttest hostlib))
244ALL_TARGET_OBJS += $(MODULE_OBJS)
245endif
246
247USER_MANIFEST_LINES += \
248    $(addprefix $(MODULE_GROUP)$(FIRMWARE_INSTALL_DIR)/,\
249                $(foreach file,$(MODULE_FIRMWARE),\
250                          $(notdir $(file))=$(FIRMWARE_SRC_DIR)/$(file)))
251
252ifeq ($(MODULE_TYPE),)
253# modules with no type are kernel modules
254ifneq ($(MODULE_LIBS)$(MODULE_STATIC_LIBS)$(MODULE_FIDL_LIBS)$(MODULE_BANJO_LIBS),)
255$(error $(MODULE) kernel modules may not use MODULE_LIBS, MODULE_STATIC_LIBS, MODULE_FIDL_LIBS, or MODULE_BANJO_LIBS)
256endif
257# make the rest of the build depend on our output
258ALLMODULE_OBJS += $(MODULE_OBJS) $(MODULE_EXTRA_OBJS)
259else
260# otherwise they are some named module flavor
261include make/module-$(patsubst %-static,%,$(MODULE_TYPE)).mk
262endif
263
264endif # MODULE_ELIDED
265
266
267# empty out any vars set here
268MODULE :=
269MODULE_ELIDED :=
270MODULE_SRCDIR :=
271MODULE_BUILDDIR :=
272MODULE_GENDIR :=
273MODULE_DEPS :=
274MODULE_HEADER_DEPS :=
275MODULE_SRCS :=
276MODULE_OBJS :=
277MODULE_DEFINES :=
278MODULE_OPTFLAGS :=
279MODULE_COMPILEFLAGS :=
280MODULE_CFLAGS :=
281MODULE_CPPFLAGS :=
282MODULE_ASMFLAGS :=
283MODULE_LDFLAGS :=
284MODULE_SRCDEPS :=
285MODULE_EXTRA_OBJS :=
286MODULE_CONFIG :=
287MODULE_TYPE :=
288MODULE_NAME :=
289MODULE_EXPORT :=
290MODULE_LIBS :=
291MODULE_STATIC_LIBS :=
292MODULE_FIDL_DEPS :=
293MODULE_FIDL_LIBS :=
294MODULE_FIDL_LIBRARY :=
295MODULE_BANJO_DEPS :=
296MODULE_BANJO_LIBS :=
297MODULE_BANJO_LIBRARY :=
298MODULE_SO_NAME :=
299MODULE_INSTALL_PATH :=
300MODULE_SO_INSTALL_NAME :=
301MODULE_HOST_LIBS :=
302MODULE_HOST_SYSLIBS :=
303MODULE_GROUP :=
304MODULE_PACKAGE :=
305MODULE_PACKAGE_SRCS :=
306MODULE_PACKAGE_INCS :=
307MODULE_FIRMWARE :=
308
309# Save these before the next module.
310SAVED_EXTRA_BUILDDEPS := $(EXTRA_BUILDDEPS)
311SAVED_GENERATED := $(GENERATED)
312SAVED_USER_MANIFEST_LINES := $(USER_MANIFEST_LINES)
313