blob: d0a5d70398e4c17bb48cc6a177994ff6cc052f33 [file] [log] [blame]
# Copyright 2016 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT
# check for disallowed options
ifneq ($(MODULE_DEPS),)
$(error $(MODULE) $(MODULE_TYPE) modules must use MODULE_{LIBS,STATIC_LIBS}, not MODULE_DEPS)
endif
ifneq ($(MODULE_HOST_LIBS)$(MODULE_HOST_SYSLIBS),)
$(error $(MODULE) $(MODULE_TYPE) modules must use MODULE_{LIBS,STATIC_LIBS}, not MODULE_HOST_{LIBS,SYSLIBS})
endif
# Things that are library-like but not "userlib" do not
# generate static libraries, nor do they cause shared
# libraries to be exported to the sysroot
ifeq ($(MODULE_TYPE),userlib)
# build static library
$(MODULE_LIBNAME).a: $(MODULE_OBJS) $(MODULE_EXTRA_OBJS)
@$(MKDIR)
$(call BUILDECHO,linking $@)
@rm -f -- "$@"
$(call BUILDCMD,$(AR),cr $@ $^)
# always build all libraries
EXTRA_BUILDDEPS += $(MODULE_LIBNAME).a
GENERATED += $(MODULE_LIBNAME).a
# exported modules get packaged
ifeq ($(filter so,$(MODULE_EXPORT)),so)
MODULE_PACKAGE += $(sort $(MODULE_PACKAGE) shared)
endif
ifeq ($(filter a,$(MODULE_EXPORT)),a)
MODULE_PACKAGE += $(sort $(MODULE_PACKAGE) static)
endif
endif
# modules that declare a soname or install name desire to be shared libs as well
ifneq ($(MODULE_SO_NAME)$(MODULE_SO_INSTALL_NAME),)
MODULE_ALIBS := $(foreach lib,$(MODULE_STATIC_LIBS) $(MODULE_FIDL_LIBS),$(call TOBUILDDIR,$(lib))/lib$(notdir $(lib)).a)
# Link profile runtime into everything compiled with profile instrumentation.
# The static profile runtime library must come after all static libraries
# whose instrumented code might call into it. It depends on libzircon, so
# make sure we're linking that in if we're not already.
ifeq ($(strip $(call TOBOOL,$(USE_PROFILE)) \
$(filter $(NO_PROFILE),$(MODULE_COMPILEFLAGS))),true)
MODULE_ALIBS += $(PROFILE_LIB)
MODULE_LIBS := $(filter-out system/ulib/zircon,$(MODULE_LIBS)) \
system/ulib/zircon
endif
MODULE_SOLIBS := $(foreach lib,$(MODULE_LIBS),$(call TOBUILDDIR,$(lib))/lib$(notdir $(lib)).so.abi)
MODULE_EXTRA_OBJS += $(foreach lib,$(MODULE_FIDL_LIBS),$(call TOBUILDDIR,$(lib))/gen/obj/tables.cpp.o)
# Include this in every link.
MODULE_EXTRA_OBJS += scripts/dso_handle.ld
# Link the ASan runtime into everything compiled with ASan.
ifeq (,$(filter -fno-sanitize=all,$(MODULE_COMPILEFLAGS)))
MODULE_EXTRA_OBJS += $(ASAN_SOLIB)
endif
$(MODULE_LIBNAME).so: _OBJS := $(MODULE_OBJS) $(MODULE_EXTRA_OBJS)
$(MODULE_LIBNAME).so: _LIBS := $(MODULE_ALIBS) $(MODULE_SOLIBS)
ifneq (,$(MODULE_SO_NAME))
$(MODULE_LIBNAME).so: _SONAME_FLAGS := -soname lib$(MODULE_SO_NAME).so
endif
$(MODULE_LIBNAME).so: _LDFLAGS := $(GLOBAL_LDFLAGS) $(USERLIB_SO_LDFLAGS) $(MODULE_LDFLAGS)
$(MODULE_LIBNAME).so: $(MODULE_OBJS) $(MODULE_EXTRA_OBJS) $(MODULE_ALIBS) $(MODULE_SOLIBS)
@$(MKDIR)
$(call BUILDECHO,linking userlib $@)
$(call BUILDCMD,$(USER_LD),$(_LDFLAGS) -shared $(_SONAME_FLAGS) $(_OBJS) \
--start-group $(_LIBS) --end-group \
$(LIBGCC) -o $@)
EXTRA_IDFILES += $(MODULE_LIBNAME).so.id
# build list and debugging files if asked to
ifeq ($(ENABLE_BUILD_LISTFILES),true)
EXTRA_BUILDDEPS += $(MODULE_LIBNAME).so.lst
EXTRA_BUILDDEPS += $(MODULE_LIBNAME).so.sym
GENERATED += $(MODULE_LIBNAME).so.lst
GENERATED += $(MODULE_LIBNAME).so.sym
endif
ifeq ($(MODULE_TYPE),userlib)
# Only update the .so.abi file if it's changed, so things don't need
# to be relinked if the ABI didn't change.
$(MODULE_LIBNAME).so.abi: $(MODULE_LIBNAME).abi.stamp ;
# Link the ABI stub against the same DSOs the real library uses, so the
# stub gets DT_NEEDED entries. These are not strictly part of the ABI.
# But at link time, the linker pays attention to them if the DSO has any
# undefined symbols. In some situations, the presence of the undefined
# symbols actually is part of the ABI, so we can't omit them from the
# stub. Since they're there, the linker will want to believe that some
# other DSO supplies them. The old GNU linker actually looks for the
# named DSOs (via -rpath-link) and checks their symbols. Gold simply
# notices if any DSO directly included in the link has a DT_NEEDED for
# another DSO that is not directly included in the link, and in that
# case doesn't complain about undefined symbols in the directly-included
# DSO. LLD never complains about undefined symbols in a DSO included in
# the link, so if it were the only linker we would not add these
# DT_NEEDEDs at all.
$(MODULE_LIBNAME).abi.stamp: _SONAME := lib$(MODULE_SO_NAME).so
$(MODULE_LIBNAME).abi.stamp: _LIBS := $(MODULE_SOLIBS)
$(MODULE_LIBNAME).abi.stamp: $(MODULE_LIBNAME).abi.o $(MODULE_SOLIBS) \
$(MODULE_LIBNAME).abi.h scripts/shlib-symbols
$(call BUILDECHO,generating ABI stub $(@:.abi.stamp=.so.abi))
$(NOECHO)$(USER_LD) $(GLOBAL_LDFLAGS) --no-gc-sections \
-shared -soname $(_SONAME) -s \
$< $(_LIBS) -o $(@:.abi.stamp=.so.abi).new
# Sanity check that the ABI stub really matches the actual DSO.
$(NOECHO)$(SHELLEXEC) scripts/shlib-symbols '$(NM)' $(@:.abi.stamp=.so.abi).new | \
cmp $(<:.o=.h) -
# Move it into place only if it's changed.
$(NOECHO)\
if cmp -s $(@:.abi.stamp=.so.abi).new $(@:.abi.stamp=.so.abi); then \
rm $(@:.abi.stamp=.so.abi).new; \
else \
mv -f $(@:.abi.stamp=.so.abi).new $(@:.abi.stamp=.so.abi); \
fi
$(NOECHO)touch $@
$(MODULE_LIBNAME).abi.h: $(MODULE_LIBNAME).so scripts/shlib-symbols
$(NOECHO)$(SHELLEXEC) scripts/shlib-symbols -z '$(NM)' $< > $@
$(MODULE_LIBNAME).abi.o: $(MODULE_LIBNAME).abi.h scripts/dso-abi.h
$(NOECHO)$(CC) $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) \
$(ARCH_CFLAGS) -c -include scripts/dso-abi.h \
-xassembler-with-cpp $< -o $@
ALLUSER_LIBS += $(MODULE)
EXTRA_BUILDDEPS += $(MODULE_LIBNAME).so.abi
GENERATED += \
$(MODULE_LIBNAME).so $(MODULE_LIBNAME).so.abi $(MODULE_LIBNAME).abi.stamp \
$(MODULE_LIBNAME).abi.h $(MODULE_LIBNAME).abi.o
endif
ifeq ($(MODULE_SO_INSTALL_NAME),)
MODULE_SO_INSTALL_NAME := lib$(MODULE_SO_NAME).so
# At runtime, ASan-supporting libraries are found in lib/asan/ first.
ifeq ($(call TOBOOL,$(USE_ASAN)),true)
MODULE_SO_INSTALL_NAME := asan/$(MODULE_SO_INSTALL_NAME)
endif
MODULE_SO_INSTALL_NAME := lib/$(MODULE_SO_INSTALL_NAME)
endif
ifneq ($(MODULE_SO_INSTALL_NAME),-)
USER_MANIFEST_LINES += $(MODULE_GROUP)$(MODULE_SO_INSTALL_NAME)=$(MODULE_LIBNAME).so.strip
# These debug info files go in the bootfs image.
ifeq ($(and $(filter $(subst $(COMMA),$(SPACE),$(BOOTFS_DEBUG_MODULES)),$(MODULE)),yes),yes)
USER_MANIFEST_DEBUG_INPUTS += $(MODULE_LIBNAME).so
endif
endif
endif
MODULE_RULESMK := $(MODULE_SRCDIR)/rules.mk
# Hack to work around libc/libmusl aliasing
# TODO(swetland): a long-term fix
ifeq ($(MODULE_SRCDIR),system/ulib/c)
MODULE_SRCDIR := third_party/ulib/musl
endif
# process packages exported to sdk as source
ifneq ($(strip $(MODULE_PACKAGE)),)
MODULE_PKG_FILE := $(MODULE_BUILDDIR)/$(MODULE_NAME).pkg
MODULE_EXP_FILE := $(BUILDDIR)/export/$(MODULE_NAME).pkg
# grab all files from source, we'll filter out .h, .c, etc in the next steps
# so as to exclude build files, editor droppings, etc
MODULE_PKG_FILES := $(shell find $(MODULE_SRCDIR) -type f)
# split based on include/... and everything else
ifneq ($(MODULE_PACKAGE_INCS),)
MODULE_PKG_INCS := $(MODULE_PACKAGE_INCS)
else
MODULE_PKG_INCS := $(filter %.h %.modulemap,$(filter $(MODULE_SRCDIR)/include/%,$(MODULE_PKG_FILES)))
endif
MODULE_PKG_INCS := $(foreach inc,$(MODULE_PKG_INCS),$(patsubst $(MODULE_SRCDIR)/include/%,%,$(inc))=SOURCE/$(inc))
# We replace . with - in module dep names to handle async.xyz which are defined
# as sub-libraries of async in the same directory. If we ever introduce more
# libraries this way they will have to maintain the pattern where foo.bar in the
# MODULE is foo-bar in the MODULE_NAME:
MODULE_PKG_DEPS := $(subst .,-,$(foreach dep,$(MODULE_LIBS),$(lastword $(subst /,$(SPACE),$(dep)))))
ifeq ($(filter src,$(MODULE_PACKAGE)),src)
ifneq ($(MODULE_PACKAGE_SRCS),)
MODULE_PKG_SRCS := $(filter-out none,$(MODULE_PACKAGE_SRCS))
else
MODULE_PKG_SRCS := $(filter %.c %.h %.cpp %.S %.modulemap,$(filter-out $(MODULE_SRCDIR)/include/%,$(MODULE_PKG_FILES)))
endif
MODULE_PKG_SRCS := $(foreach src,$(MODULE_PKG_SRCS),$(patsubst $(MODULE_SRCDIR)/%,%,$(src))=SOURCE/$(src))
MODULE_PKG_ARCH := src
MODULE_PKG_TAG := "[src]"
else
MODULE_PKG_SRCS :=
MODULE_PKG_ARCH := $(ARCH)
MODULE_PKG_TAG := "[lib]"
ifneq ($(filter shared,$(MODULE_PACKAGE)),)
ifneq ($(MODULE_SO_NAME),)
MODULE_PKG_SRCS += lib/lib$(MODULE_SO_NAME).so=BUILD/$(patsubst $(BUILDDIR)/%,%,$(MODULE_LIBNAME)).so.abi
MODULE_PKG_SRCS += dist/$(MODULE_SO_INSTALL_NAME)=BUILD/$(patsubst $(BUILDDIR)/%,%,$(MODULE_LIBNAME)).so.strip
MODULE_PKG_SRCS += debug/lib$(MODULE_SO_NAME).so=BUILD/$(patsubst $(BUILDDIR)/%,%,$(MODULE_LIBNAME)).so
endif
endif
ifneq ($(filter static,$(MODULE_PACKAGE)),)
MODULE_PKG_SRCS += lib/lib$(MODULE_NAME).a=BUILD/$(patsubst $(BUILDDIR)/%,%,$(MODULE_LIBNAME)).a
endif
endif
ifeq ($(filter shared,$(MODULE_PACKAGE)),)
# source modules and static libraries need to include their static deps to be buildable
# we apply the same . to - transform as in PKG_DEPS
MODULE_PKG_SDEPS := $(subst .,-,$(foreach dep,$(MODULE_STATIC_LIBS),$(lastword $(subst /,$(SPACE),$(dep)))))
MODULE_PKG_FDEPS := $(subst .,-,$(foreach dep,$(MODULE_FIDL_LIBS),$(lastword $(subst /,$(SPACE),$(dep)))))
MODULE_PKG_BDEPS := $(subst .,-,$(foreach dep,$(MODULE_BANJO_LIBS),$(lastword $(subst /,$(SPACE),$(dep)))))
else
MODULE_PKG_SDEPS :=
MODULE_PKG_FDEPS :=
MODULE_PKG_BDEPS :=
endif
# libc is the "sysroot" package
# We bundle crt1, aux libs (libdl, etc), libzircon, as well
# as the public system headers and libzircon headers into this package
ifeq ($(MODULE),system/ulib/c)
# empty compatibility libraries
MODULE_PKG_SRCS += lib/libm.so=SOURCE/third_party/ulib/musl/lib.ld
MODULE_PKG_SRCS += lib/libdl.so=SOURCE/third_party/ulib/musl/lib.ld
MODULE_PKG_SRCS += lib/libpthread.so=SOURCE/third_party/ulib/musl/lib.ld
MODULE_PKG_SRCS += lib/librt.so=SOURCE/third_party/ulib/musl/lib.ld
# crt1
MODULE_PKG_SRCS += lib/Scrt1.o=$(patsubst $(BUILDDIR)/%,BUILD/%,$(USER_SCRT1_OBJ))
# libzircon
MODULE_PKG_SRCS += lib/libzircon.so=BUILD/system/ulib/zircon/libzircon.so.abi
MODULE_PKG_SRCS += debug/libzircon.so=BUILD/system/ulib/zircon/libzircon.so
# global headers
GLOBAL_HEADERS := $(shell find system/public -name \*\.h -o -name \*\.inc -o -name \*\.modulemap)
MODULE_PKG_INCS += $(foreach inc,$(GLOBAL_HEADERS),$(patsubst system/public/%,%,$(inc))=SOURCE/$(inc))
# generated headers
MODULE_PKG_INCS += $(foreach inc,$(sort $(ABIGEN_PUBLIC_HEADERS)),$(patsubst $(ABIGEN_BUILDDIR)/%,%,$(inc))=$(patsubst $(BUILDDIR)/%,BUILD/%,$(inc)))
# libzircon headers
ZIRCON_HEADERS := $(shell find system/ulib/zircon/include -name \*\.h)
MODULE_PKG_INCS += $(foreach inc,$(ZIRCON_HEADERS),$(patsubst system/ulib/zircon/include/%,%,$(inc))=SOURCE/$(inc))
# libc only depends on libzircon which is now included, so clear the deps list
MODULE_PKG_DEPS :=
MODULE_PKG_SDEPS :=
MODULE_PKG_FDEPS :=
MODULE_PKG_BDEPS :=
endif
$(MODULE_PKG_FILE): _NAME := $(MODULE_NAME)
$(MODULE_PKG_FILE): _ARCH := $(MODULE_PKG_ARCH)
$(MODULE_PKG_FILE): _INCS := $(if $(MODULE_PKG_INCS),"[includes]" $(sort $(MODULE_PKG_INCS)))
$(MODULE_PKG_FILE): _SRCS := $(if $(MODULE_PKG_SRCS),$(MODULE_PKG_TAG) $(sort $(MODULE_PKG_SRCS)))
$(MODULE_PKG_FILE): _DEPS := $(if $(MODULE_PKG_DEPS),"[deps]" $(sort $(MODULE_PKG_DEPS)))
$(MODULE_PKG_FILE): _SDEPS := $(if $(MODULE_PKG_SDEPS),"[static-deps]" $(sort $(MODULE_PKG_SDEPS)))
$(MODULE_PKG_FILE): _FDEPS := $(if $(MODULE_PKG_FDEPS),"[fidl-deps]" $(sort $(MODULE_PKG_FDEPS)))
$(MODULE_PKG_FILE): _BDEPS := $(if $(MODULE_PKG_BDEPS),"[banjo-deps]" $(sort $(MODULE_PKG_BDEPS)))
$(MODULE_PKG_FILE): $(MODULE_RULESMK) make/module-userlib.mk
@$(call BUILDECHO,creating package $@ ;)\
$(MKDIR) ;\
echo "[package]" > $@ ;\
echo "name=$(_NAME)" >> $@ ;\
echo "type=lib" >> $@ ;\
echo "arch=$(_ARCH)" >> $@ ;\
for i in $(_INCS) ; do echo "$$i" >> $@ ; done ;\
for i in $(_SRCS) ; do echo "$$i" >> $@ ; done ;\
for i in $(_SDEPS) ; do echo "$$i" >> $@ ; done ;\
for i in $(_FDEPS) ; do echo "$$i" >> $@ ; done ;\
for i in $(_BDEPS) ; do echo "$$i" >> $@ ; done ;\
for i in $(_DEPS) ; do echo "$$i" >> $@ ; done
$(MODULE_EXP_FILE): $(MODULE_PKG_FILE)
@$(MKDIR) ;\
if [ -f "$@" ]; then \
if ! cmp "$<" "$@" >/dev/null 2>&1; then \
$(if $(BUILDECHO),echo installing $@ ;)\
cp -f $< $@; \
fi \
else \
$(if $(BUILDECHO),echo installing $@ ;)\
cp -f $< $@; \
fi
GENERATED += $(MODULE_EXP_FILE) $(MODULE_PKG_FILE)
ALLPKGS += $(MODULE_EXP_FILE)
endif
# if the SYSROOT build feature is enabled, we will package
# up exported libraries, their headers, etc
#
# MODULE_EXPORT may contain "a" to export the static library
# MODULE_EXPORT may contain "so" to export the shared library
ifeq ($(ENABLE_BUILD_SYSROOT),true)
ifeq ($(MODULE_TYPE),userlib)
ifneq ($(filter so,$(MODULE_EXPORT)),)
ifneq ($(MODULE_SO_NAME),)
# Install the .so.abi, which is needed at link time, into the sysroot's lib directory.
#$(info EXPORT $(MODULE) shared)
MODULE_TEMP_NAME := $(BUILDSYSROOT)/lib/lib$(MODULE_SO_NAME).so.abi
$(call copy-dst-src,$(MODULE_TEMP_NAME),$(MODULE_LIBNAME).so.abi)
SYSROOT_DEPS += $(MODULE_TEMP_NAME)
GENERATED += $(MODULE_TEMP_NAME)
# Install debug info for exported libraries for debuggers to find.
# These files live on the development host, not the target.
# There's no point in saving separate debug info here (at least not yet),
# we just make a copy of the unstripped file.
MODULE_TEMP_NAME := $(BUILDSYSROOT)/debug/lib$(MODULE_SO_NAME).so
$(call copy-dst-src,$(MODULE_TEMP_NAME),$(MODULE_LIBNAME).so)
SYSROOT_DEPS += $(MODULE_TEMP_NAME)
GENERATED += $(MODULE_TEMP_NAME)
endif
endif
ifneq ($(filter a,$(MODULE_EXPORT)),)
#$(info EXPORT $(MODULE) static)
MODULE_TEMP_NAME := $(BUILDSYSROOT)/lib/lib$(MODULE_NAME).a
$(call copy-dst-src,$(MODULE_TEMP_NAME),$(MODULE_LIBNAME).a)
SYSROOT_DEPS += $(MODULE_TEMP_NAME)
GENERATED += $(MODULE_TEMP_NAME)
endif
# only install headers for exported libraries
ifneq ($(MODULE_EXPORT),)
#$(info EXPORT $(MODULE) include)
# for now, unify all headers in one pile
# TODO: ddk, etc should be packaged separately
MODULE_INSTALL_HEADERS := $(BUILDSYSROOT)/include
# locate headers from module source public include dir
MODULE_PUBLIC_HEADERS :=\
$(shell test -d $(MODULE_SRCDIR)/include &&\
find $(MODULE_SRCDIR)/include -name \*\.h -o -name \*\.inc -o -name \*\.modulemap )
# translate them to the destination in sysroot
MODULE_SYSROOT_HEADERS :=\
$(patsubst $(MODULE_SRCDIR)/include/%,$(MODULE_INSTALL_HEADERS)/%,$(MODULE_PUBLIC_HEADERS))
# generate rules to copy them
$(call copy-dst-src,$(MODULE_INSTALL_HEADERS)/%.h,$(MODULE_SRCDIR)/include/%.h)
$(call copy-dst-src,$(MODULE_INSTALL_HEADERS)/%.inc,$(MODULE_SRCDIR)/include/%.inc)
$(call copy-dst-src,$(MODULE_INSTALL_HEADERS)/%.modulemap,$(MODULE_SRCDIR)/include/%.modulemap)
SYSROOT_DEPS += $(MODULE_SYSROOT_HEADERS)
GENERATED += $(MODULE_SYSROOT_HEADERS)
endif
endif # if MODULE_TYPE == userlib
endif # if ENABLE_BUILD_SYSROOT true