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