genode/repos/base/mk/generic.mk
Norman Feske 1866520d6c dde_linux: build initcall_table.c after objects
The added hook 'OBJ_POSTPROC_SRC' gives us a way to post-process object
files for generating supplemental code. By using this hook, the
initcall_table.c generated by import-lx_emul_common.inc gets reliably
executed after all object files are built.

Fixes #5159
2024-04-12 15:00:44 +02:00

169 lines
5.4 KiB
Makefile

#
# Generic rules to build file types from other file types and other
# common functionaly that is needed to build library or program targets.
#
#
# Collect object files and avoid duplicates (by using 'sort')
#
SRC_O += $(addprefix binary_,$(addsuffix .o,$(notdir $(SRC_BIN))))
SRC = $(sort $(SRC_C) $(SRC_CC) $(SRC_ADB) $(SRC_ADS) $(SRC_RS) $(SRC_S) $(SRC_O) $(SRC_GO))
OBJECTS = $(addsuffix .o,$(basename $(SRC)))
#
# Hook for incorporating source code generated by post-processing object
# files. The source code must be generated after building 'OBJECTS'. But
# the object file(s) resulting from the generated code must be linked.
# Hence, 'OBJECTS' is expanded after the dependency definition.
#
ifneq ($(OBJ_POSTPROC_SRC),)
$(OBJ_POSTPROC_SRC) : $(OBJECTS)
OBJECTS += $(addsuffix .o,$(basename $(OBJ_POSTPROC_SRC)))
endif
#
# Create sub directories for objects files corresponding to the sub directories
# of their respective source files
#
SUB_DIRS = $(sort $(dir $(OBJECTS)))
ifneq ($(SUB_DIRS),./)
$(OBJECTS): $(filter-out $(wildcard $(SUB_DIRS)), $(SUB_DIRS))
endif
.PHONY: $(SUB_DIRS)
$(SUB_DIRS):
$(VERBOSE)mkdir -p $@
#
# Make sure that we rebuild object files and host tools after Makefile changes
#
# The 'GLOBAL_DEPS' variable contains a list of files with side effects on the
# build result that not captured by the regular .d-file mechanism. Changes of
# such files - in particular build-description files - trigger a whole rebuild.
#
GLOBAL_DEPS += $(filter-out $(LIB_PROGRESS_LOG),$(MAKEFILE_LIST))
$(wildcard $(OBJECTS)) $(HOST_TOOLS): $(GLOBAL_DEPS)
INCLUDES := $(addprefix -I,$(wildcard $(ALL_INC_DIR)))
#
# If one of the 3rd-party ports used by the target changed, we need to rebuild
# all object files and host tools because they may include sources from the
# 3rd-party port.
#
# The 'PORT_HASH_FILES' variable is populated as side effect of calling the
# 'select_from_ports' function.
#
$(OBJECTS) $(HOST_TOOLS): $(PORT_HASH_FILES)
#
# Include dependency files for the corresponding object files except
# when cleaning
#
ifneq ($(filter-out $(MAKECMDGOALS),clean),)
-include $(OBJECTS:.o=.d)
endif
%.o: %.c
$(MSG_COMP)$@
$(VERBOSE)$(CC) $(CC_DEF) $(CC_C_OPT) $(INCLUDES) -c $< -o $@
%.o: %.cc
$(MSG_COMP)$@
$(VERBOSE)$(CXX) $(CXX_DEF) $(CC_CXX_OPT) $(INCLUDES) -c $< -o $@
%.o: %.cpp
$(MSG_COMP)$@
$(VERBOSE)$(CXX) $(CXX_DEF) $(CC_CXX_OPT) $(INCLUDES) -c $< -o $@
%.o: %.s
$(MSG_ASSEM)$@
$(VERBOSE)$(CC) $(CC_DEF) $(CC_C_OPT) $(INCLUDES) -c $< -o $@
#
# Compiling Go sources
#
%.o: %.go
$(MSG_COMP)$@
$(VERBOSE)$(GOLANG) $(CUSTOM_GO_FLAGS) -c -o $@ $<
#
# Compiling Ada source codes
#
# The mandatory runtime directories 'adainclude' and 'adalib' are expected in
# the program directory.
#
#
# We need to override these to build the ada runtime
#
CUSTOM_ADA_FLAGS ?= --RTS=$(ADA_RTS)
CUSTOM_ADA_OPT ?= $(CC_ADA_OPT) -gnatef -gnatwG
CUSTOM_ADA_INCLUDE ?= -I- $(INCLUDES)
#
# The files generated by the binder would not pass our GNAT style checks
# thus we handle them separately and disable style checks via compiler option
# '-gnatyN'
#
b~%.ali b~%.o: b~%.adb
$(MSG_COMP)$@
$(VERBOSE)$(CUSTOM_ADA_CC) $(CUSTOM_ADA_FLAGS) $(CUSTOM_ADA_OPT) -gnatyN $(CUSTOM_ADA_INCLUDE) -c $<
$(VERBOSE)$(ALI2DEP) $(dir $<) $(ALL_INC_DIR) b~$*.ali
%.ali %.o: %.adb
$(MSG_COMP)$@
$(VERBOSE)$(CUSTOM_ADA_CC) $(CUSTOM_ADA_FLAGS) $(CUSTOM_ADA_OPT) $(CUSTOM_ADA_INCLUDE) -c $<
$(VERBOSE)$(ALI2DEP) $(dir $<) $(ALL_INC_DIR) $*.ali
%.ali %.o: %.ads
$(MSG_COMP)$@
$(VERBOSE)$(CUSTOM_ADA_CC) $(CUSTOM_ADA_FLAGS) $(CUSTOM_ADA_OPT) $(CUSTOM_ADA_INCLUDE) -c $<
$(VERBOSE)$(ALI2DEP) $(dir $<) $(ALL_INC_DIR) $*.ali
#
# Assembler files that must be preprocessed are fed to the C compiler.
#
%.o: %.S
$(MSG_COMP)$@
$(VERBOSE)$(CC) $(CC_DEF) $(CC_OPT) -D__ASSEMBLY__ $(INCLUDES) -c $< -o $@
#
# Link binary data
#
# We transform binary data into an object file by using the 'incbin' directive
# of the GNU assembler. This enables us to choose a any label for the binary
# data (in contrast to 'ld -r -oformat default -b binary', which generates the
# label from the input path name) and to align the binary data as required on
# some architectures (e.g., ARM).
#
symbol_name = _binary_$(subst -,_,$(subst .,_,$(subst binary_,,$(subst .o,,$(notdir $@)))))
binary_%.o: %
$(MSG_CONVERT)$@
$(VERBOSE)echo ".global $(symbol_name)_start, $(symbol_name)_end; .data; .align 4; $(symbol_name)_start:; .incbin \"$<\"; $(symbol_name)_end:" |\
$(AS) $(AS_OPT) -f -o $@ -
#
# Create local symbol links for the used shared libraries
#
# Depending on whether an ABI stub for a given shared library exists, we link
# the target against the ABI stub or the real shared library.
#
# We check if the symbolic links are up-to-date by filtering all links that
# already match the current shared library targets from the list. If the list
# is not empty we flag 'SHARED_LIBS' as phony to make sure that the symbolic
# links are recreated. E.g., if a symbol list is added for library, the next
# time a user of the library is linked, the ABI stub should be used instead of
# the library.
#
select_so = $(firstword $(wildcard $(LIB_CACHE_DIR)/$(1:.lib.so=)/$(1:.lib.so=).abi.so) \
$(LIB_CACHE_DIR)/$(1:.lib.so=)/$(1:.lib.so=).lib.so)
ifneq ($(filter-out $(foreach s,$(SHARED_LIBS),$(realpath $s)), \
$(foreach s,$(SHARED_LIBS),$(call select_so,$s))),)
.PHONY: $(SHARED_LIBS)
endif
$(SHARED_LIBS):
$(VERBOSE)ln -sf $(call select_so,$@) $@