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