genode/tool/depot/mk/build_bin_archive
Norman Feske b510394a6d depot/build_bin_archive: keep hash of ingredients
This patch records the content hashes of the src and api ingredients
used for creating a bin archive. This information allows for the
detection of possible inconsistencies between a bin archive and its
corresponding src archive within the depot.

Issue #5379
2024-11-20 08:55:49 +01:00

260 lines
6.8 KiB
Makefile
Executable File

#!/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)) <src-name> SPEC=<spec> USER=<user> CCACHE=<ccache> DBG=<dbg>
<src-name> name of the source archive to build
<spec> build spec, e.g., x86_32, x86_64
<user> identity of the archive creator
<ccache> compiler calls will use the C/C++ compiler cache if this is 1
<dbg> 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))
DEPOT_BIN_HASH_FILE := $(addsuffix .hash,$(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 '<srcdir>/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 $</* $@/ \;
@$(ECHO) "$(DARK_COL)created$(DEFAULT_COL) $(USER)/bin/$(SPEC)/$(VERSIONED_ARCHIVE)"
$(DEPOT_DBG_ARCHIVE_DIR): $(DEPOT_ARCHIVE_BUILD_DIR)/debug
$(VERBOSE)mkdir -p $@
$(VERBOSE)find $< -name *.debug -exec cp {} $@/ \;
@$(ECHO) "$(DARK_COL)created$(DEFAULT_COL) $(USER)/dbg/$(SPEC)/$(VERSIONED_ARCHIVE)"
INGREDIENTS := $(addprefix src/,$(ARCHIVE)) $(addprefix api/,$(USED_APIS))
INGREDIENTS_HASHES := $(foreach I,$(INGREDIENTS),$(call file_content,$(DEPOT_DIR)/$(USER)/$I.hash))
$(DEPOT_BIN_HASH_FILE): $(DEPOT_BIN_ARCHIVE_DIR)
$(VERBOSE)echo "$(INGREDIENTS_HASHES)" > $@
$(TARGET): $(DEPOT_BIN_HASH_FILE)
ifneq ($(DBG),)
$(TARGET): $(DEPOT_DBG_ARCHIVE_DIR)
endif
#
# Remove intermediate build artifacts
#
ifeq ($(KEEP_BUILD_DIR),)
$(TARGET): remove_build_dir_when_done
remove_build_dir_when_done: $(DEPOT_BIN_ARCHIVE_DIR)
$(VERBOSE)$(RM_BUILD_DIR_CMD)
ifneq ($(DBG),)
remove_build_dir_when_done: $(DEPOT_DBG_ARCHIVE_DIR)
endif
endif