mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
5734ea736c
Spotted during our work on issue #5061.
253 lines
7.0 KiB
Makefile
253 lines
7.0 KiB
Makefile
##
|
|
## Rules for building a program target
|
|
##
|
|
## The following variables must be passed when calling this file:
|
|
##
|
|
## BASE_DIR - base directory of the build system
|
|
## REP_DIR - source repository of the program
|
|
## PRG_REL_DIR - directory of the program relative to 'src/'
|
|
## REPOSITORIES - repositories providing libs and headers
|
|
## INSTALL_DIR - installation directory for stripped executables
|
|
## DEBUG_DIR - installation directory for unstripped executables
|
|
## VERBOSE - build verboseness modifier
|
|
## VERBOSE_DIR - verboseness modifier for changing directories
|
|
## VERBOSE_MK - verboseness of make calls
|
|
## SHARED_LIBS - shared-library dependencies of the target
|
|
## ARCHIVES - archive dependencies of the target
|
|
## LIB_CACHE_DIR - library build cache location
|
|
##
|
|
|
|
#
|
|
# Prevent target.mk rules to be executed as default rule
|
|
#
|
|
all:
|
|
|
|
#
|
|
# Include common utility functions
|
|
#
|
|
include $(BASE_DIR)/mk/util.inc
|
|
|
|
#
|
|
# Include target build instructions
|
|
#
|
|
PRG_DIR := $(REP_DIR)/src/$(PRG_REL_DIR)
|
|
include $(PRG_DIR)/target.mk
|
|
|
|
#
|
|
# Include lib-import description files
|
|
#
|
|
include $(foreach LIB,$(LIBS),$(call select_from_repositories,lib/import/import-$(LIB).mk))
|
|
|
|
#
|
|
# Include specifics for platforms, kernel APIs, etc.
|
|
#
|
|
include $(SPEC_FILES)
|
|
|
|
vpath % $(PRG_DIR)
|
|
|
|
include $(BASE_DIR)/mk/global.mk
|
|
|
|
#
|
|
# Assemble linker options for static and dynamic linkage
|
|
#
|
|
LD_TEXT_ADDR ?= 0x01000000
|
|
ifneq ($(LD_TEXT_ADDR),)
|
|
CXX_LINK_OPT += -Wl,-Ttext=$(LD_TEXT_ADDR)
|
|
endif
|
|
|
|
#
|
|
# Supply machine-dependent arguments to the linker
|
|
#
|
|
CXX_LINK_OPT += $(CC_MARCH)
|
|
|
|
#
|
|
# Generic linker script for statically linked binaries
|
|
#
|
|
ifneq ($(filter linux, $(SPECS)),)
|
|
LD_SCRIPT_STATIC ?= $(BASE_DIR)/src/ld/genode.ld \
|
|
$(call select_from_repositories,src/ld/stack_area.ld)
|
|
else
|
|
LD_SCRIPT_STATIC ?= $(BASE_DIR)/src/ld/genode.ld
|
|
endif
|
|
|
|
include $(BASE_DIR)/mk/generic.mk
|
|
include $(BASE_DIR)/mk/base-libs.mk
|
|
|
|
all: $(TARGET)
|
|
|
|
ifneq ($(INSTALL_DIR),)
|
|
ifneq ($(DEBUG_DIR),)
|
|
all: $(INSTALL_DIR)/$(TARGET) $(DEBUG_DIR)/$(TARGET) $(DEBUG_DIR)/$(TARGET).debug
|
|
endif
|
|
endif
|
|
|
|
all:
|
|
@true # prevent nothing-to-be-done message
|
|
|
|
#
|
|
# Enforce unconditional call of gnatmake rule when compiling Ada sources
|
|
#
|
|
# Citation from texinfo manual for make:
|
|
#
|
|
# If a rule has no prerequisites or commands, and the target of the rule
|
|
# is a nonexistent file, then `make' imagines this target to have been
|
|
# updated whenever its rule is run. This implies that all targets
|
|
# depending on this one will always have their commands run.
|
|
#
|
|
FORCE:
|
|
$(SRC_ADA:.adb=.o): FORCE
|
|
|
|
#
|
|
# Run binder if Ada sources are included in the build
|
|
#
|
|
ifneq ($(SRC_ADS)$(SRC_ADB),)
|
|
|
|
CUSTOM_BINDER_FLAGS ?= -n -we -D768k
|
|
|
|
OBJECTS += b~$(TARGET).o
|
|
|
|
ALIS := $(addsuffix .ali, $(basename $(SRC_ADS) $(SRC_ADB)))
|
|
ALI_DIRS := $(foreach LIB,$(LIBS),$(call select_from_repositories,lib/ali/$(LIB)))
|
|
BINDER_SEARCH_DIRS = $(addprefix -I$(BUILD_BASE_DIR)/var/libcache/, $(LIBS)) $(addprefix -aO, $(ALI_DIRS))
|
|
|
|
BINDER_SRC := b~$(TARGET).ads b~$(TARGET).adb
|
|
|
|
$(BINDER_SRC): $(ALIS)
|
|
$(VERBOSE)$(GNATBIND) $(CUSTOM_BINDER_FLAGS) $(BINDER_SEARCH_DIRS) $(INCLUDES) --RTS=$(ADA_RTS) -o $@ $^
|
|
endif
|
|
|
|
#
|
|
# Use CXX for linking
|
|
#
|
|
LD_CMD ?= $(CXX)
|
|
LD_CMD += $(CXX_LINK_OPT)
|
|
|
|
ifeq ($(SHARED_LIBS),)
|
|
LD_SCRIPTS := $(LD_SCRIPT_STATIC)
|
|
else
|
|
|
|
#
|
|
# Add a list of symbols that shall always be added to the dynsym section
|
|
#
|
|
LD_OPT += --dynamic-list=$(BASE_DIR)/src/ld/genode_dyn.dl
|
|
|
|
LD_SCRIPTS := $(LD_SCRIPT_DYN)
|
|
LD_CMD += -Wl,--dynamic-linker=$(DYNAMIC_LINKER).lib.so \
|
|
-Wl,--eh-frame-hdr -Wl,-rpath-link=.
|
|
|
|
#
|
|
# Filter out the base libraries since they will be provided by the LDSO library
|
|
#
|
|
override ARCHIVES := $(filter-out $(BASE_LIBS:=.lib.a),$(ARCHIVES))
|
|
endif
|
|
|
|
#
|
|
# LD_SCRIPT_PREFIX is needed as 'addprefix' chokes on prefixes containing
|
|
# commas othwerwise. For compatibilty with older tool chains, we use two -Wl
|
|
# parameters for both components of the linker command line.
|
|
#
|
|
LD_SCRIPT_PREFIX := -Wl,-T -Wl,
|
|
|
|
#
|
|
# LD_SCRIPTS may be a list of linker scripts (e.g., in base-linux). Further,
|
|
# we use the default linker script if none was specified - 'addprefix' expands
|
|
# to empty string on empty input.
|
|
#
|
|
LD_CMD += $(addprefix $(LD_SCRIPT_PREFIX), $(LD_SCRIPTS))
|
|
|
|
STATIC_LIBS := $(foreach l,$(ARCHIVES:.lib.a=),$(LIB_CACHE_DIR)/$l/$l.lib.a)
|
|
|
|
#
|
|
# We need the linker option '--whole-archive' to make sure that all library
|
|
# constructors marked with '__attribute__((constructor))' end up int the
|
|
# binary. When not using this option, the linker goes through all libraries
|
|
# to resolve a symbol and, if it finds the symbol, stops searching. This way,
|
|
# object files that are never explicitly referenced (such as library
|
|
# constructors) would not be visited at all.
|
|
#
|
|
# Furthermore, the '--whole-archive' option reveals symbol ambiguities, which
|
|
# would go undetected if the search stops after the first match.
|
|
#
|
|
LINK_ITEMS := $(OBJECTS) $(STATIC_LIBS) $(SHARED_LIBS)
|
|
LINK_ITEMS_BRIEF := $(subst $(LIB_CACHE_DIR),$$libs,$(LINK_ITEMS))
|
|
|
|
#
|
|
# Trigger the build of host tools
|
|
#
|
|
$(LINK_ITEMS) $(TARGET): $(HOST_TOOLS)
|
|
|
|
#
|
|
# Trigger build of additional program specific targets
|
|
#
|
|
all: $(CUSTOM_TARGET_DEPS)
|
|
|
|
LD_CMD += -Wl,--whole-archive -Wl,--start-group
|
|
LD_CMD += $(LINK_ITEMS_BRIEF)
|
|
LD_CMD += $(EXT_OBJECTS)
|
|
LD_CMD += -Wl,--no-whole-archive
|
|
LD_CMD += -Wl,--end-group
|
|
|
|
#
|
|
# Link libgcc to each program
|
|
#
|
|
LD_LIBGCC ?= $(shell $(CC) $(CC_MARCH) -print-libgcc-file-name)
|
|
LD_CMD += $(LD_LIBGCC)
|
|
|
|
#
|
|
# If available, link XML schema file for checking configurations
|
|
#
|
|
ifneq ($(CONFIG_XSD),)
|
|
all: $(INSTALL_DIR)/$(TARGET).xsd
|
|
$(INSTALL_DIR)/$(TARGET).xsd: $(PRG_DIR)/$(CONFIG_XSD)
|
|
$(VERBOSE)ln -sf $< $@
|
|
endif
|
|
|
|
#
|
|
# Skip final linking if no objects are involved, i.e. no 'SRC' files are
|
|
# specified in the 'target.mk' file. This applies for pseudo 'target.mk'
|
|
# files that invoke a 3rd-party build system by providing local rule for
|
|
# $(TARGET).
|
|
#
|
|
ifneq ($(OBJECTS),)
|
|
$(TARGET): $(LINK_ITEMS) $(wildcard $(LD_SCRIPTS))
|
|
$(MSG_LINK)$(TARGET)
|
|
$(VERBOSE)libs=$(LIB_CACHE_DIR); $(LD_CMD) -o $@
|
|
|
|
STRIP_TARGET_CMD ?= $(STRIP) -o $@ $<
|
|
|
|
$(TARGET).debug: $(TARGET)
|
|
$(VERBOSE)$(OBJCOPY) --only-keep-debug $< $@
|
|
|
|
$(TARGET).stripped: $(TARGET) $(TARGET).debug
|
|
$(VERBOSE)$(STRIP_TARGET_CMD)
|
|
$(VERBOSE)$(OBJCOPY) --add-gnu-debuglink=$(TARGET).debug $@
|
|
|
|
$(INSTALL_DIR)/$(TARGET): $(TARGET).stripped
|
|
$(VERBOSE)ln -sf $(CURDIR)/$< $@
|
|
ifeq ($(COVERAGE),yes)
|
|
$(VERBOSE)mkdir -p $(INSTALL_DIR)/gcov_data/$(TARGET)
|
|
$(VERBOSE)ln -sf $(CURDIR)/*.gcno $(INSTALL_DIR)/gcov_data/$(TARGET)/
|
|
endif
|
|
|
|
ifneq ($(DEBUG_DIR),)
|
|
$(DEBUG_DIR)/$(TARGET): $(TARGET).stripped
|
|
$(VERBOSE)ln -sf $(CURDIR)/$< $@
|
|
$(DEBUG_DIR)/$(TARGET).debug: $(TARGET).debug
|
|
$(VERBOSE)ln -sf $(CURDIR)/$< $@
|
|
endif
|
|
|
|
else
|
|
$(TARGET):
|
|
$(INSTALL_DIR)/$(TARGET): $(TARGET)
|
|
$(DEBUG_DIR)/$(TARGET): $(TARGET)
|
|
$(DEBUG_DIR)/$(TARGET).debug: $(TARGET)
|
|
endif
|
|
|
|
|
|
clean_prg_objects:
|
|
$(MSG_CLEAN)$(PRG_REL_DIR)
|
|
$(VERBOSE)$(RM) -f $(OBJECTS) $(OBJECTS:.o=.d) $(TARGET) $(TARGET).stripped $(TARGET).debug $(BINDER_SRC)
|
|
$(VERBOSE)$(RM) -f *.d *.i *.ii *.s *.ali *.lib.so
|
|
|
|
clean: clean_prg_objects
|