1# Copyright 2016 The Fuchsia Authors
2#
3# Use of this source code is governed by a MIT-style
4# license that can be found in the LICENSE file or at
5# https://opensource.org/licenses/MIT
6
7# check for disallowed options
8ifneq ($(MODULE_DEPS),)
9$(error $(MODULE) $(MODULE_TYPE) modules must use MODULE_{LIBS,STATIC_LIBS}, not MODULE_DEPS)
10endif
11ifneq ($(MODULE_HOST_LIBS)$(MODULE_HOST_SYSLIBS),)
12$(error $(MODULE) $(MODULE_TYPE) modules must use MODULE_{LIBS,STATIC_LIBS}, not MODULE_HOST_{LIBS,SYSLIBS})
13endif
14
15# Things that are library-like but not "userlib" do not
16# generate static libraries, nor do they cause shared
17# libraries to be exported to the sysroot
18
19ifeq ($(MODULE_TYPE),userlib)
20# build static library
21$(MODULE_LIBNAME).a: $(MODULE_OBJS) $(MODULE_EXTRA_OBJS)
22	@$(MKDIR)
23	$(call BUILDECHO,linking $@)
24	@rm -f -- "$@"
25	$(call BUILDCMD,$(AR),cr $@ $^)
26
27# always build all libraries
28EXTRA_BUILDDEPS += $(MODULE_LIBNAME).a
29GENERATED += $(MODULE_LIBNAME).a
30
31# exported modules get packaged
32ifeq ($(filter so,$(MODULE_EXPORT)),so)
33MODULE_PACKAGE += $(sort $(MODULE_PACKAGE) shared)
34endif
35ifeq ($(filter a,$(MODULE_EXPORT)),a)
36MODULE_PACKAGE += $(sort $(MODULE_PACKAGE) static)
37endif
38
39endif
40
41# modules that declare a soname or install name desire to be shared libs as well
42ifneq ($(MODULE_SO_NAME)$(MODULE_SO_INSTALL_NAME),)
43MODULE_ALIBS := $(foreach lib,$(MODULE_STATIC_LIBS) $(MODULE_FIDL_LIBS),$(call TOBUILDDIR,$(lib))/lib$(notdir $(lib)).a)
44
45# Link profile runtime into everything compiled with profile instrumentation.
46# The static profile runtime library must come after all static libraries
47# whose instrumented code might call into it.  It depends on libzircon, so
48# make sure we're linking that in if we're not already.
49ifeq ($(strip $(call TOBOOL,$(USE_PROFILE)) \
50	      $(filter $(NO_PROFILE),$(MODULE_COMPILEFLAGS))),true)
51MODULE_ALIBS += $(PROFILE_LIB)
52MODULE_LIBS := $(filter-out system/ulib/zircon,$(MODULE_LIBS)) \
53	       system/ulib/zircon
54endif
55
56MODULE_SOLIBS := $(foreach lib,$(MODULE_LIBS),$(call TOBUILDDIR,$(lib))/lib$(notdir $(lib)).so.abi)
57MODULE_EXTRA_OBJS += $(foreach lib,$(MODULE_FIDL_LIBS),$(call TOBUILDDIR,$(lib))/gen/obj/tables.cpp.o)
58
59# Include this in every link.
60MODULE_EXTRA_OBJS += scripts/dso_handle.ld
61
62# Link the ASan runtime into everything compiled with ASan.
63ifeq (,$(filter -fno-sanitize=all,$(MODULE_COMPILEFLAGS)))
64MODULE_EXTRA_OBJS += $(ASAN_SOLIB)
65endif
66
67$(MODULE_LIBNAME).so: _OBJS := $(MODULE_OBJS) $(MODULE_EXTRA_OBJS)
68$(MODULE_LIBNAME).so: _LIBS := $(MODULE_ALIBS) $(MODULE_SOLIBS)
69ifneq (,$(MODULE_SO_NAME))
70$(MODULE_LIBNAME).so: _SONAME_FLAGS := -soname lib$(MODULE_SO_NAME).so
71endif
72$(MODULE_LIBNAME).so: _LDFLAGS := $(GLOBAL_LDFLAGS) $(USERLIB_SO_LDFLAGS) $(MODULE_LDFLAGS)
73$(MODULE_LIBNAME).so: $(MODULE_OBJS) $(MODULE_EXTRA_OBJS) $(MODULE_ALIBS) $(MODULE_SOLIBS)
74	@$(MKDIR)
75	$(call BUILDECHO,linking userlib $@)
76	$(call BUILDCMD,$(USER_LD),$(_LDFLAGS) -shared $(_SONAME_FLAGS) $(_OBJS) \
77				   --start-group $(_LIBS) --end-group \
78				   $(LIBGCC) -o $@)
79
80EXTRA_IDFILES += $(MODULE_LIBNAME).so.id
81
82# build list and debugging files if asked to
83ifeq ($(ENABLE_BUILD_LISTFILES),true)
84EXTRA_BUILDDEPS += $(MODULE_LIBNAME).so.lst
85EXTRA_BUILDDEPS += $(MODULE_LIBNAME).so.sym
86GENERATED += $(MODULE_LIBNAME).so.lst
87GENERATED += $(MODULE_LIBNAME).so.sym
88endif
89
90ifeq ($(MODULE_TYPE),userlib)
91# Only update the .so.abi file if it's changed, so things don't need
92# to be relinked if the ABI didn't change.
93$(MODULE_LIBNAME).so.abi: $(MODULE_LIBNAME).abi.stamp ;
94
95# Link the ABI stub against the same DSOs the real library uses, so the
96# stub gets DT_NEEDED entries.  These are not strictly part of the ABI.
97# But at link time, the linker pays attention to them if the DSO has any
98# undefined symbols.  In some situations, the presence of the undefined
99# symbols actually is part of the ABI, so we can't omit them from the
100# stub.  Since they're there, the linker will want to believe that some
101# other DSO supplies them.  The old GNU linker actually looks for the
102# named DSOs (via -rpath-link) and checks their symbols.  Gold simply
103# notices if any DSO directly included in the link has a DT_NEEDED for
104# another DSO that is not directly included in the link, and in that
105# case doesn't complain about undefined symbols in the directly-included
106# DSO.  LLD never complains about undefined symbols in a DSO included in
107# the link, so if it were the only linker we would not add these
108# DT_NEEDEDs at all.
109$(MODULE_LIBNAME).abi.stamp: _SONAME := lib$(MODULE_SO_NAME).so
110$(MODULE_LIBNAME).abi.stamp: _LIBS := $(MODULE_SOLIBS)
111$(MODULE_LIBNAME).abi.stamp: $(MODULE_LIBNAME).abi.o $(MODULE_SOLIBS) \
112			     $(MODULE_LIBNAME).abi.h scripts/shlib-symbols
113	$(call BUILDECHO,generating ABI stub $(@:.abi.stamp=.so.abi))
114	$(NOECHO)$(USER_LD) $(GLOBAL_LDFLAGS) --no-gc-sections \
115		       -shared -soname $(_SONAME) -s \
116		       $< $(_LIBS) -o $(@:.abi.stamp=.so.abi).new
117# Sanity check that the ABI stub really matches the actual DSO.
118	$(NOECHO)$(SHELLEXEC) scripts/shlib-symbols '$(NM)' $(@:.abi.stamp=.so.abi).new | \
119	cmp $(<:.o=.h) -
120# Move it into place only if it's changed.
121	$(NOECHO)\
122	if cmp -s $(@:.abi.stamp=.so.abi).new $(@:.abi.stamp=.so.abi); then \
123	  rm $(@:.abi.stamp=.so.abi).new; \
124	else \
125	  mv -f $(@:.abi.stamp=.so.abi).new $(@:.abi.stamp=.so.abi); \
126	fi
127	$(NOECHO)touch $@
128
129$(MODULE_LIBNAME).abi.h: $(MODULE_LIBNAME).so scripts/shlib-symbols
130	$(NOECHO)$(SHELLEXEC) scripts/shlib-symbols -z '$(NM)' $< > $@
131
132$(MODULE_LIBNAME).abi.o: $(MODULE_LIBNAME).abi.h scripts/dso-abi.h
133	$(NOECHO)$(CC) $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) \
134		       $(ARCH_CFLAGS) -c -include scripts/dso-abi.h \
135		       -xassembler-with-cpp $< -o $@
136
137ALLUSER_LIBS += $(MODULE)
138EXTRA_BUILDDEPS += $(MODULE_LIBNAME).so.abi
139GENERATED += \
140    $(MODULE_LIBNAME).so $(MODULE_LIBNAME).so.abi $(MODULE_LIBNAME).abi.stamp \
141    $(MODULE_LIBNAME).abi.h $(MODULE_LIBNAME).abi.o
142endif
143
144ifeq ($(MODULE_SO_INSTALL_NAME),)
145MODULE_SO_INSTALL_NAME := lib$(MODULE_SO_NAME).so
146# At runtime, ASan-supporting libraries are found in lib/asan/ first.
147ifeq ($(call TOBOOL,$(USE_ASAN)),true)
148MODULE_SO_INSTALL_NAME := asan/$(MODULE_SO_INSTALL_NAME)
149endif
150MODULE_SO_INSTALL_NAME := lib/$(MODULE_SO_INSTALL_NAME)
151endif
152ifneq ($(MODULE_SO_INSTALL_NAME),-)
153USER_MANIFEST_LINES += $(MODULE_GROUP)$(MODULE_SO_INSTALL_NAME)=$(MODULE_LIBNAME).so.strip
154# These debug info files go in the bootfs image.
155ifeq ($(and $(filter $(subst $(COMMA),$(SPACE),$(BOOTFS_DEBUG_MODULES)),$(MODULE)),yes),yes)
156USER_MANIFEST_DEBUG_INPUTS += $(MODULE_LIBNAME).so
157endif
158endif
159endif
160
161MODULE_RULESMK := $(MODULE_SRCDIR)/rules.mk
162
163# Hack to work around libc/libmusl aliasing
164# TODO(swetland): a long-term fix
165ifeq ($(MODULE_SRCDIR),system/ulib/c)
166MODULE_SRCDIR := third_party/ulib/musl
167endif
168
169# process packages exported to sdk as source
170ifneq ($(strip $(MODULE_PACKAGE)),)
171MODULE_PKG_FILE := $(MODULE_BUILDDIR)/$(MODULE_NAME).pkg
172MODULE_EXP_FILE := $(BUILDDIR)/export/$(MODULE_NAME).pkg
173
174# grab all files from source, we'll filter out .h, .c, etc in the next steps
175# so as to exclude build files, editor droppings, etc
176MODULE_PKG_FILES := $(shell find $(MODULE_SRCDIR) -type f)
177
178# split based on include/... and everything else
179ifneq ($(MODULE_PACKAGE_INCS),)
180MODULE_PKG_INCS := $(MODULE_PACKAGE_INCS)
181else
182MODULE_PKG_INCS := $(filter %.h %.modulemap,$(filter $(MODULE_SRCDIR)/include/%,$(MODULE_PKG_FILES)))
183endif
184MODULE_PKG_INCS := $(foreach inc,$(MODULE_PKG_INCS),$(patsubst $(MODULE_SRCDIR)/include/%,%,$(inc))=SOURCE/$(inc))
185
186# We replace . with - in module dep names to handle async.xyz which are defined
187# as sub-libraries of async in the same directory.  If we ever introduce more
188# libraries this way they will have to maintain the pattern where foo.bar in the
189# MODULE is foo-bar in the MODULE_NAME:
190MODULE_PKG_DEPS := $(subst .,-,$(foreach dep,$(MODULE_LIBS),$(lastword $(subst /,$(SPACE),$(dep)))))
191
192ifeq ($(filter src,$(MODULE_PACKAGE)),src)
193ifneq ($(MODULE_PACKAGE_SRCS),)
194MODULE_PKG_SRCS := $(filter-out none,$(MODULE_PACKAGE_SRCS))
195else
196MODULE_PKG_SRCS := $(filter %.c %.h %.cpp %.S %.modulemap,$(filter-out $(MODULE_SRCDIR)/include/%,$(MODULE_PKG_FILES)))
197endif
198MODULE_PKG_SRCS := $(foreach src,$(MODULE_PKG_SRCS),$(patsubst $(MODULE_SRCDIR)/%,%,$(src))=SOURCE/$(src))
199MODULE_PKG_ARCH := src
200MODULE_PKG_TAG := "[src]"
201else
202MODULE_PKG_SRCS :=
203MODULE_PKG_ARCH := $(ARCH)
204MODULE_PKG_TAG := "[lib]"
205
206ifneq ($(filter shared,$(MODULE_PACKAGE)),)
207ifneq ($(MODULE_SO_NAME),)
208MODULE_PKG_SRCS += lib/lib$(MODULE_SO_NAME).so=BUILD/$(patsubst $(BUILDDIR)/%,%,$(MODULE_LIBNAME)).so.abi
209MODULE_PKG_SRCS += dist/$(MODULE_SO_INSTALL_NAME)=BUILD/$(patsubst $(BUILDDIR)/%,%,$(MODULE_LIBNAME)).so.strip
210MODULE_PKG_SRCS += debug/lib$(MODULE_SO_NAME).so=BUILD/$(patsubst $(BUILDDIR)/%,%,$(MODULE_LIBNAME)).so
211endif
212endif
213
214ifneq ($(filter static,$(MODULE_PACKAGE)),)
215MODULE_PKG_SRCS += lib/lib$(MODULE_NAME).a=BUILD/$(patsubst $(BUILDDIR)/%,%,$(MODULE_LIBNAME)).a
216endif
217endif
218
219ifeq ($(filter shared,$(MODULE_PACKAGE)),)
220# source modules and static libraries need to include their static deps to be buildable
221# we apply the same . to - transform as in PKG_DEPS
222MODULE_PKG_SDEPS := $(subst .,-,$(foreach dep,$(MODULE_STATIC_LIBS),$(lastword $(subst /,$(SPACE),$(dep)))))
223MODULE_PKG_FDEPS := $(subst .,-,$(foreach dep,$(MODULE_FIDL_LIBS),$(lastword $(subst /,$(SPACE),$(dep)))))
224MODULE_PKG_BDEPS := $(subst .,-,$(foreach dep,$(MODULE_BANJO_LIBS),$(lastword $(subst /,$(SPACE),$(dep)))))
225else
226MODULE_PKG_SDEPS :=
227MODULE_PKG_FDEPS :=
228MODULE_PKG_BDEPS :=
229endif
230
231# libc is the "sysroot" package
232# We bundle crt1, aux libs (libdl, etc), libzircon, as well
233# as the public system headers and libzircon headers into this package
234ifeq ($(MODULE),system/ulib/c)
235# empty compatibility libraries
236MODULE_PKG_SRCS += lib/libm.so=SOURCE/third_party/ulib/musl/lib.ld
237MODULE_PKG_SRCS += lib/libdl.so=SOURCE/third_party/ulib/musl/lib.ld
238MODULE_PKG_SRCS += lib/libpthread.so=SOURCE/third_party/ulib/musl/lib.ld
239MODULE_PKG_SRCS += lib/librt.so=SOURCE/third_party/ulib/musl/lib.ld
240
241# crt1
242MODULE_PKG_SRCS += lib/Scrt1.o=$(patsubst $(BUILDDIR)/%,BUILD/%,$(USER_SCRT1_OBJ))
243
244# libzircon
245MODULE_PKG_SRCS += lib/libzircon.so=BUILD/system/ulib/zircon/libzircon.so.abi
246MODULE_PKG_SRCS += debug/libzircon.so=BUILD/system/ulib/zircon/libzircon.so
247
248# global headers
249GLOBAL_HEADERS := $(shell find system/public -name \*\.h -o -name \*\.inc -o -name \*\.modulemap)
250MODULE_PKG_INCS += $(foreach inc,$(GLOBAL_HEADERS),$(patsubst system/public/%,%,$(inc))=SOURCE/$(inc))
251
252# generated headers
253MODULE_PKG_INCS += $(foreach inc,$(sort $(ABIGEN_PUBLIC_HEADERS)),$(patsubst $(ABIGEN_BUILDDIR)/%,%,$(inc))=$(patsubst $(BUILDDIR)/%,BUILD/%,$(inc)))
254
255# libzircon headers
256ZIRCON_HEADERS := $(shell find system/ulib/zircon/include -name \*\.h)
257MODULE_PKG_INCS += $(foreach inc,$(ZIRCON_HEADERS),$(patsubst system/ulib/zircon/include/%,%,$(inc))=SOURCE/$(inc))
258
259# libc only depends on libzircon which is now included, so clear the deps list
260MODULE_PKG_DEPS :=
261MODULE_PKG_SDEPS :=
262MODULE_PKG_FDEPS :=
263MODULE_PKG_BDEPS :=
264endif
265
266$(MODULE_PKG_FILE): _NAME := $(MODULE_NAME)
267$(MODULE_PKG_FILE): _ARCH := $(MODULE_PKG_ARCH)
268$(MODULE_PKG_FILE): _INCS := $(if $(MODULE_PKG_INCS),"[includes]" $(sort $(MODULE_PKG_INCS)))
269$(MODULE_PKG_FILE): _SRCS := $(if $(MODULE_PKG_SRCS),$(MODULE_PKG_TAG) $(sort $(MODULE_PKG_SRCS)))
270$(MODULE_PKG_FILE): _DEPS := $(if $(MODULE_PKG_DEPS),"[deps]" $(sort $(MODULE_PKG_DEPS)))
271$(MODULE_PKG_FILE): _SDEPS := $(if $(MODULE_PKG_SDEPS),"[static-deps]" $(sort $(MODULE_PKG_SDEPS)))
272$(MODULE_PKG_FILE): _FDEPS := $(if $(MODULE_PKG_FDEPS),"[fidl-deps]" $(sort $(MODULE_PKG_FDEPS)))
273$(MODULE_PKG_FILE): _BDEPS := $(if $(MODULE_PKG_BDEPS),"[banjo-deps]" $(sort $(MODULE_PKG_BDEPS)))
274$(MODULE_PKG_FILE): $(MODULE_RULESMK) make/module-userlib.mk
275	@$(call BUILDECHO,creating package $@ ;)\
276	$(MKDIR) ;\
277	echo "[package]" > $@ ;\
278	echo "name=$(_NAME)" >> $@ ;\
279	echo "type=lib" >> $@ ;\
280	echo "arch=$(_ARCH)" >> $@ ;\
281	for i in $(_INCS) ; do echo "$$i" >> $@ ; done ;\
282	for i in $(_SRCS) ; do echo "$$i" >> $@ ; done ;\
283	for i in $(_SDEPS) ; do echo "$$i" >> $@ ; done ;\
284	for i in $(_FDEPS) ; do echo "$$i" >> $@ ; done ;\
285	for i in $(_BDEPS) ; do echo "$$i" >> $@ ; done ;\
286	for i in $(_DEPS) ; do echo "$$i" >> $@ ; done
287
288$(MODULE_EXP_FILE): $(MODULE_PKG_FILE)
289	@$(MKDIR) ;\
290	if [ -f "$@" ]; then \
291		if ! cmp "$<" "$@" >/dev/null 2>&1; then \
292			$(if $(BUILDECHO),echo installing $@ ;)\
293			cp -f $< $@; \
294		fi \
295	else \
296		$(if $(BUILDECHO),echo installing $@ ;)\
297		cp -f $< $@; \
298	fi
299
300GENERATED += $(MODULE_EXP_FILE) $(MODULE_PKG_FILE)
301ALLPKGS += $(MODULE_EXP_FILE)
302endif
303
304# if the SYSROOT build feature is enabled, we will package
305# up exported libraries, their headers, etc
306#
307# MODULE_EXPORT may contain "a" to export the static library
308# MODULE_EXPORT may contain "so" to export the shared library
309ifeq ($(ENABLE_BUILD_SYSROOT),true)
310ifeq ($(MODULE_TYPE),userlib)
311
312ifneq ($(filter so,$(MODULE_EXPORT)),)
313ifneq ($(MODULE_SO_NAME),)
314# Install the .so.abi, which is needed at link time, into the sysroot's lib directory.
315#$(info EXPORT $(MODULE) shared)
316MODULE_TEMP_NAME := $(BUILDSYSROOT)/lib/lib$(MODULE_SO_NAME).so.abi
317$(call copy-dst-src,$(MODULE_TEMP_NAME),$(MODULE_LIBNAME).so.abi)
318SYSROOT_DEPS += $(MODULE_TEMP_NAME)
319GENERATED += $(MODULE_TEMP_NAME)
320
321# Install debug info for exported libraries for debuggers to find.
322# These files live on the development host, not the target.
323# There's no point in saving separate debug info here (at least not yet),
324# we just make a copy of the unstripped file.
325MODULE_TEMP_NAME := $(BUILDSYSROOT)/debug/lib$(MODULE_SO_NAME).so
326$(call copy-dst-src,$(MODULE_TEMP_NAME),$(MODULE_LIBNAME).so)
327SYSROOT_DEPS += $(MODULE_TEMP_NAME)
328GENERATED += $(MODULE_TEMP_NAME)
329endif
330endif
331
332ifneq ($(filter a,$(MODULE_EXPORT)),)
333#$(info EXPORT $(MODULE) static)
334MODULE_TEMP_NAME := $(BUILDSYSROOT)/lib/lib$(MODULE_NAME).a
335$(call copy-dst-src,$(MODULE_TEMP_NAME),$(MODULE_LIBNAME).a)
336SYSROOT_DEPS += $(MODULE_TEMP_NAME)
337GENERATED += $(MODULE_TEMP_NAME)
338endif
339
340# only install headers for exported libraries
341ifneq ($(MODULE_EXPORT),)
342#$(info EXPORT $(MODULE) include)
343# for now, unify all headers in one pile
344# TODO: ddk, etc should be packaged separately
345MODULE_INSTALL_HEADERS := $(BUILDSYSROOT)/include
346
347# locate headers from module source public include dir
348MODULE_PUBLIC_HEADERS :=\
349$(shell test -d $(MODULE_SRCDIR)/include &&\
350  find $(MODULE_SRCDIR)/include -name \*\.h -o -name \*\.inc -o -name \*\.modulemap )
351
352# translate them to the destination in sysroot
353MODULE_SYSROOT_HEADERS :=\
354$(patsubst $(MODULE_SRCDIR)/include/%,$(MODULE_INSTALL_HEADERS)/%,$(MODULE_PUBLIC_HEADERS))
355
356# generate rules to copy them
357$(call copy-dst-src,$(MODULE_INSTALL_HEADERS)/%.h,$(MODULE_SRCDIR)/include/%.h)
358$(call copy-dst-src,$(MODULE_INSTALL_HEADERS)/%.inc,$(MODULE_SRCDIR)/include/%.inc)
359$(call copy-dst-src,$(MODULE_INSTALL_HEADERS)/%.modulemap,$(MODULE_SRCDIR)/include/%.modulemap)
360
361SYSROOT_DEPS += $(MODULE_SYSROOT_HEADERS)
362GENERATED += $(MODULE_SYSROOT_HEADERS)
363endif
364
365endif # if MODULE_TYPE == userlib
366endif # if ENABLE_BUILD_SYSROOT true
367