#!/usr/bin/make -f # # \brief Tool for building a binary archive from source # \author Norman Feske # \date 2016-05-17 # define HELP_MESSAGE Build a binary archive from source usage: $(firstword $(MAKEFILE_LIST)) SPEC= USER= CCACHE= DBG= name of the source archive to build build spec, e.g., x86_32, x86_64 identity of the archive creator compiler calls will use the C/C++ compiler cache if this is 1 build 'dbg' archives containing debug info files in addition to the corresponding 'bin' archives if this is 1 endef export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../../..) include $(GENODE_DIR)/tool/depot/mk/front_end.inc # # Provide Genode build system with clean environment # unexport BASE_DIR unexport SPECS unexport SPEC_FILES unexport LIB_CACHE_DIR unexport LIB_DEP_FILE unexport LIB_PROGRESS_LOG unexport CONTRIB_DIR unexport REPOSITORIES # # The target is the name of the archive # ARCHIVE := $(TARGET) # # Define location of source archive # RECIPE_DIR := $(call recipe_dir,src/$(ARCHIVE)) REP_DIR := $(RECIPE_DIR:/recipes/src/$(ARCHIVE)=) DEPOT_API_DIR := $(DEPOT_DIR)/$(USER)/api DEPOT_SRC_DIR := $(DEPOT_DIR)/$(USER)/src DEPOT_BIN_DIR := $(DEPOT_DIR)/$(USER)/bin DEPOT_DBG_DIR := $(DEPOT_DIR)/$(USER)/dbg # # Look up hash of the source archive from the src recipe # EXPECTED_SRC_HASH_FILE := $(RECIPE_DIR)/hash SRC_HASH_FILE := $(wildcard $(EXPECTED_SRC_HASH_FILE)) checked_src_hash_file: ifeq ($(SRC_HASH_FILE),) @$(ECHO) "Error: source-archive hash file missing," @$(ECHO) " expected at '$(EXPECTED_SRC_HASH_FILE)'" @false else SRC_HASH_FILE_CONTENT := $(shell cat $(SRC_HASH_FILE)) SRC_VERSION := $(firstword $(SRC_HASH_FILE_CONTENT)) endif # # Look for source archive # # First try to locate the source archive in the depot, which succeeds only # if the archive is given with a versioned name. The archive version is # unspecified, we look up the version information from the archive recipe. # VERSIONED_ARCHIVE := $(ARCHIVE) SRC_DIR := $(DEPOT_SRC_DIR)/$(VERSIONED_ARCHIVE) SRC_DIR := $(if $(wildcard $(SRC_DIR)),$(SRC_DIR),) checked_src_archive: @true ifeq ($(SRC_DIR),) VERSIONED_ARCHIVE := $(ARCHIVE)/$(SRC_VERSION) SRC_DIR := $(DEPOT_SRC_DIR)/$(VERSIONED_ARCHIVE) checked_src_archive: checked_src_hash_file endif ifeq ($(wildcard $(SRC_DIR)),) checked_src_archive: error_missing_source_archive endif error_missing_source_archive: @$(ECHO) "Error: missing source archive $(SRC_DIR)" @false # # Check for missing SPEC argument # checked_spec_argument: ifeq ($(SPEC),) @$(ECHO) "Error: missing SPEC argument" @false endif # # Define build-directory location # DEPOT_BIN_ARCHIVE_DIR := $(DEPOT_BIN_DIR)/$(SPEC)/$(VERSIONED_ARCHIVE) DEPOT_DBG_ARCHIVE_DIR := $(DEPOT_DBG_DIR)/$(SPEC)/$(VERSIONED_ARCHIVE) DEPOT_ARCHIVE_BUILD_DIR := $(addsuffix .build,$(DEPOT_BIN_ARCHIVE_DIR)) # # Create archive build directory, which corresponds to a Genode build directory # # etc/build.conf: REPOSITORIES point to the source archive and all used api # archive. The list of used api archive comes from the '/used_apis' # file. # # if building a library, always incorporate the API implemented by the library API_FILE := $(wildcard $(addsuffix /api,$(SRC_DIR))) ifneq ($(API_FILE),) USED_APIS += $(call file_content,$(API_FILE)) endif # incorporate all APIs used by the source archive USED_APIS_FILE := $(SRC_DIR)/used_apis ifneq ($(wildcard $(USED_APIS_FILE)),) USED_APIS += $(shell cat $(USED_APIS_FILE)) endif BUILD_CONF := $(DEPOT_ARCHIVE_BUILD_DIR)/etc/build.conf SPECS_CONF := $(DEPOT_ARCHIVE_BUILD_DIR)/etc/specs.conf TOOLS_CONF := $(DEPOT_ARCHIVE_BUILD_DIR)/etc/tools.conf BUILD_MK := $(DEPOT_ARCHIVE_BUILD_DIR)/Makefile # validate that all API archives exist USED_API_DIRS := $(addprefix $(DEPOT_API_DIR)/, $(USED_APIS)) MISSING_API_DIRS := $(filter-out $(wildcard $(USED_API_DIRS)), $(USED_API_DIRS)) checked_api_archives: ifneq ($(MISSING_API_DIRS),) @($(ECHO) "Error: The following API archives are missing:"; \ for api in $(MISSING_API_DIRS); do $(ECHO) " " $$api; done); @false endif ifeq ($(CCACHE),1) BUILD_CONF_CCACHE := yes else BUILD_CONF_CCACHE := endif $(BUILD_CONF): checked_src_archive checked_api_archives $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE) \ ( echo "GENODE_DIR := $(GENODE_DIR)"; \ echo "BASE_DIR := $(GENODE_DIR)/repos/base"; \ echo "override CCACHE := $(BUILD_CONF_CCACHE)"; \ echo "override KERNEL :="; \ echo "REPOSITORIES := $(SRC_DIR)"; \ for api in $(USED_APIS); do \ echo "REPOSITORIES += $(DEPOT_API_DIR)/$$api"; done \ ) > $(BUILD_CONF) $(SPECS_CONF): checked_spec_argument $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)echo "SPECS += genode $(SPEC)" > $@ $(TOOLS_CONF): $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)cp $(GENODE_DIR)/repos/base/etc/tools.conf $@ $(BUILD_MK): $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)ln -sf $(GENODE_DIR)/tool/builddir/build.mk $@ $(BUILD_CONF) $(SPECS_CONF) $(TOOLS_CONF) $(BUILD_MK): wiped_build_dir wiped_build_dir: $(VERBOSE)rm -rf $(DEPOT_ARCHIVE_BUILD_DIR) # # Invoke the Genode build system in the build directory # ifeq ($(KEEP_BUILD_DIR),) RM_BUILD_DIR_CMD := rm -rf $(DEPOT_ARCHIVE_BUILD_DIR) else RM_BUILD_DIR_CMD := true endif $(DEPOT_ARCHIVE_BUILD_DIR)/bin: $(BUILD_CONF) $(SPECS_CONF) $(TOOLS_CONF) $(BUILD_MK) $(VERBOSE)$(MAKE) -C $(DEPOT_ARCHIVE_BUILD_DIR) $(BUILD_ARG) ||\ ( $(RM_BUILD_DIR_CMD); false ) $(DEPOT_ARCHIVE_BUILD_DIR)/debug: $(DEPOT_ARCHIVE_BUILD_DIR)/bin # # Extract build results from build directory into binary-archive and # debug-archive directories # $(DEPOT_BIN_ARCHIVE_DIR): $(DEPOT_ARCHIVE_BUILD_DIR)/bin $(VERBOSE)mkdir -p $@ $(VERBOSE)find $< -maxdepth 0 -not -empty -exec cp -rL $