## ## Rules for building a library target ## ## The following variables must be passed when calling this file: ## ## BASE_DIR - base directory of the build system ## REPOSITORIES - repositories providing libs and headers ## VERBOSE - build verboseness modifier ## VERBOSE_DIR - verboseness modifier for changing directories ## VERBOSE_MK - verboseness of make calls ## BUILD_BASE_DIR - base of build directory tree ## LIB_CACHE_DIR - library build cache location ## INSTALL_DIR - program target build directory ## SHARED_LIBS - shared-library dependencies of the library ## ARCHIVES - archive dependencies of the library ## REP_DIR - repository where the library resides ## CONTRIB_DIR - location of ported 3rd-party source codes ## include $(BASE_DIR)/mk/base-libs.mk # # Prevent .mk rules to be executed as default rule # all: # # Include common utility functions # include $(BASE_DIR)/mk/util.inc # # Include specifics, for example platform, kernel-api etc. # include $(SPEC_FILES) # # Include library build instructions # # We set the 'called_from_lib_mk' variable to allow the library description file # to respond to the build pass. # BACKUP_INC_DIR := $(INC_DIR) called_from_lib_mk = yes include $(LIB_MK) # # Sanity check for INC_DIR overrides # ifneq ($(filter-out $(INC_DIR),$(BACKUP_INC_DIR)),) all: error_inc_dir_override endif error_inc_dir_override: @$(ECHO) "Error: $(LIB_MK) overrides INC_DIR instead of appending" ; false # # Include lib-import descriptions of all used libraries and the target library # include $(foreach LIB,$(LIBS),$(call select_from_repositories,lib/import/import-$(LIB).mk)) # # Include global definitions # include $(BASE_DIR)/mk/global.mk # # Name of .lib.a or .lib.so file to create # ifdef SHARED_LIB LIB_SO := $(addsuffix .lib.so,$(LIB)) INSTALL_SO := $(INSTALL_DIR)/$(LIB_SO) LIB_FILENAME := $(LIB_SO) else LIB_A := $(addsuffix .lib.a,$(LIB)) LIB_FILENAME := $(LIB_A) endif LIB_TAG := $(addsuffix .lib.tag,$(LIB)) # # If a symbol list is provided, we create an ABI stub named '.abi.so' # # The ABI-stub library does not contain any code or data but only the symbol # information of the binary interface (ABI) of the shared library. # # The ABI stub is linked by the users of the library (executables or shared # objects) instead of the real library. This effectively decouples the library # users from the concrete library instance but binds them merely to the # library's binary interface. Note that the ABI stub is not used at runtime at # all. At runtime, the real library that implements the ABI is loaded by the # dynamic linker. # # The symbol information are incorporated into the ABI stub via an assembly # file named '.symbols.s' that is generated from the library's symbol # list. We create a symbolic link from the symbol file to the local directory. # By using '.symbols' as file extension, the pattern rule '%.symbols.s: # %.symbols' defined in 'generic.mk' is automatically applied for creating the # assembly file from the symbols file. # # The '.PRECIOUS' special target prevents make to remove the intermediate # assembler file. Otherwise make would spill the build log with messages # like "rm libc.symbols.s". # ifneq ($(SYMBOLS),) ABI_SO := $(addsuffix .abi.so,$(LIB)) $(LIB).symbols: $(VERBOSE)ln -sf $(SYMBOLS) $@ .PRECIOUS: $(LIB).symbols.s endif # # Link libgcc to shared libraries # # For static libraries, libgcc is not needed because it will be linked # against the final target. # ifdef SHARED_LIB LIBGCC = $(shell $(CC) $(CC_MARCH) -print-libgcc-file-name) endif # # Print message for the currently built library # all: message message: $(MSG_LIB)$(LIB) # # Trigger the creation of the .lib.a or .lib.so file # all: $(LIB_TAG) # # Trigger the build of host tools # # We make '$(LIB_TAG)' depend on the host tools to support building host tools # from pseudo libraries with no actual source code. In this case '$(OBJECTS)' # is empty. # $(LIB_TAG) $(OBJECTS): $(HOST_TOOLS) $(LIB_TAG): $(LIB_A) $(LIB_SO) $(ABI_SO) $(INSTALL_SO) @touch $@ include $(BASE_DIR)/mk/generic.mk # # Rust support # # For a rust library, we create both an actual library (lib.a or lib.so) that # is used for linking the final binary, and an rlib file that is required for # compiling rust source codes that use the library. As the rlib is created from # the file specified at 'SRC_RS' via the pattern rule '%.rlib: %.rs', its name # corresponds to the source file, not the library name. To enable rustc to find # the library when compiling dependent compilation units, we create an # appropriately named symlink that points to the rlib file. # ifneq ($(SRC_RS),) ifneq ($(words $(SRC_RS)),1) $(error 'SRC_RC' of library $(LIB) has more than one element: $(SRC_RC)) endif $(LIB_A): $(LIB).rlib endif .PRECIOUS: $(SRC_RC:.rs=.rlib) $(LIB).rlib: $(SRC_RS:.rs=.rlib) $(VERBOSE)ln -s $< $@ # # Rule to build the .lib.a file # # Use $(OBJECTS) instead of $^ for specifying the list of objects to include # in the archive because $^ may also contain non-object phony targets, e.g., # used by the integration of Qt's meta-object compiler into the Genode # build system. # $(LIB_A): $(OBJECTS) $(MSG_MERGE)$(LIB_A) $(VERBOSE)$(RM) -f $@ $(VERBOSE)$(AR) -rcs $@ $(OBJECTS) # # Link ldso-startup library to each shared library # ifdef SHARED_LIB override ARCHIVES += ldso-startup.lib.a endif # # Don't link base libraries against shared libraries except for ld.lib.so # ifneq ($(LIB_IS_DYNAMIC_LINKER),yes) override ARCHIVES := $(filter-out $(BASE_LIBS:=.lib.a),$(ARCHIVES)) endif # # The 'sort' is needed to ensure the same link order regardless # of the find order, which uses to vary among different systems. # STATIC_LIBS := $(sort $(foreach l,$(ARCHIVES:.lib.a=),$(LIB_CACHE_DIR)/$l/$l.lib.a)) STATIC_LIBS_BRIEF := $(subst $(LIB_CACHE_DIR),$$libs,$(STATIC_LIBS)) # # Rule to build the .lib.so file # # When linking the shared library, we have to link all shared sub libraries # (LIB_SO_DEPS) to the library to store the library-dependency information in # the generated shared object. # # The 'ldso-startup/startup.o' object file, which contains the support code for # constructing static objects must be specified as object file to prevent the # linker from garbage-collecting it. # # # Default entry point of shared libraries # ENTRY_POINT ?= 0x0 $(LIB_SO) $(ABI_SO): $(SHARED_LIBS) $(LIB_SO): $(STATIC_LIBS) $(OBJECTS) $(wildcard $(LD_SCRIPT_SO)) $(LIB_SO_DEPS) $(MSG_MERGE)$(LIB_SO) $(VERBOSE)libs=$(LIB_CACHE_DIR); $(LD) -o $(LIB_SO) -shared --eh-frame-hdr \ $(LD_OPT) -T $(LD_SCRIPT_SO) --entry=$(ENTRY_POINT) \ --whole-archive --start-group \ $(SHARED_LIBS) $(STATIC_LIBS_BRIEF) $(OBJECTS) \ --end-group --no-whole-archive \ $(LIBGCC) $(ABI_SO): $(LIB).symbols.o $(MSG_MERGE)$(ABI_SO) $(VERBOSE)$(LD) -o $(ABI_SO) -shared --eh-frame-hdr $(LD_OPT) \ -T $(LD_SCRIPT_SO) \ --whole-archive --start-group \ $(LIB_SO_DEPS) $< \ --end-group --no-whole-archive $(INSTALL_SO): $(VERBOSE)ln -sf $(CURDIR)/$(LIB_SO) $@