mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
parent
1ed5110d55
commit
39eff7f249
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,5 +5,7 @@
|
||||
|
||||
/build
|
||||
/contrib
|
||||
/depot
|
||||
/public
|
||||
/repos/world
|
||||
|
||||
|
146
tool/depot/build
Executable file
146
tool/depot/build
Executable file
@ -0,0 +1,146 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Build binary archives from source
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-16
|
||||
#
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Build binary archives from source archives stored in the depot
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <archive-path>...
|
||||
|
||||
The <archive-path> argument denotes the archive to create in the
|
||||
form of a path. The first path element correponds to the identity
|
||||
of the archive creator, the second element corresponds to the type
|
||||
of the archive (bin or pkg), the third element specifies the target
|
||||
architectures (e.g., x86_64), and the fourth element is the name
|
||||
of the corresponding source archive including the version.
|
||||
|
||||
E.g., the user 'alan' may build the following archives:
|
||||
|
||||
alan/bin/x86_64/zlib-<version> - a binary archive of the zlib
|
||||
library with the specified
|
||||
version, built for the 64-bit
|
||||
x86 architecture
|
||||
|
||||
alan/pkg/x86_32/wm-<version> - all binary archives needed by
|
||||
the 'wm' package archive, built
|
||||
for the 32-bit x86 architecture
|
||||
|
||||
The following arguments tweak the operation of the tool:
|
||||
|
||||
FORCE=1 Replace existing archives with freshly created
|
||||
ones.
|
||||
|
||||
VERBOSE= Show individual operations.
|
||||
|
||||
-j<N> Enable the parallel creation of packages where
|
||||
<N> denotes the level of parallelism.
|
||||
|
||||
KEEP_BUILD_DIR=1 Do not remove build directories of built binary
|
||||
packages. This is useful for debugging build
|
||||
problems.
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../..)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
include $(GENODE_DIR)/tool/depot/mk/categorize_args.inc
|
||||
|
||||
|
||||
#
|
||||
# Collect dependencies for all specified arguments
|
||||
#
|
||||
# The following accessor functions used by 'mk/dependencies.inc'.
|
||||
#
|
||||
|
||||
_file_within_archive = $(wildcard $(DEPOT_DIR)/$1/$2)
|
||||
|
||||
api_file = $(call _file_within_archive,$1,api)
|
||||
used_apis_file = $(call _file_within_archive,$1,used_apis)
|
||||
|
||||
_pkg_archives_content = $(call file_content,$(call _file_within_archive,$1,archives))
|
||||
|
||||
pkg_src_archives = $(call grep_archive_type,src,$(call _pkg_archives_content,$1))
|
||||
pkg_raw_archives = $(call grep_archive_type,raw,$(call _pkg_archives_content,$1))
|
||||
pkg_pkg_archives = $(call grep_archive_type,pkg,$(call _pkg_archives_content,$1))
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/dependencies.inc
|
||||
|
||||
|
||||
#
|
||||
# Detect missing source archives
|
||||
#
|
||||
|
||||
archive_exists_in_depot = $(wildcard $(DEPOT_DIR)/$1)
|
||||
|
||||
MISSING_ARCHIVES := $(sort \
|
||||
$(foreach A,${ARCHIVES(bin)},\
|
||||
$(if $(call archive_exists_in_depot,$(call src_of_bin,$A)),,$A)))
|
||||
|
||||
checked_source_archives_exist:
|
||||
ifneq ($(MISSING_ARCHIVES),)
|
||||
@echo "Error: archives missing in the depot ($(MISSING_ARCHIVES))"; false
|
||||
endif
|
||||
|
||||
|
||||
#
|
||||
# Generate makefile for archive-build stage
|
||||
#
|
||||
|
||||
bin_archive_spec = $(word 3,$(subst /, ,$1))
|
||||
bin_archive_recipe = $(word 4,$(subst /, ,$1))
|
||||
|
||||
# determine binary-archive path within the depot
|
||||
_api_subdir = $(addsuffix /,$(call file_content,$(call api_file,$(call src_of_bin,$1))))
|
||||
_dst_bin_spec_path = $(call archive_user,$1)/bin/$(call bin_archive_spec,$1)/
|
||||
dst_archive_path = $(call _dst_bin_spec_path,$1)$(call _api_subdir,$1)$(call bin_archive_recipe,$1)
|
||||
|
||||
BUILD_MK_FILE := $(DEPOT_DIR)/var/build.mk
|
||||
|
||||
.PHONY: $(BUILD_MK_FILE)
|
||||
|
||||
wipe_existing_archives:
|
||||
$(VERBOSE)rm -rf $(addprefix $(DEPOT_DIR)/,\
|
||||
$(foreach A,${ARCHIVES(bin)},$(call dst_archive_path,$A)))
|
||||
|
||||
$(BUILD_MK_FILE): checked_source_archives_exist checked_no_uncategorized
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)( echo -e "all:\n"; \
|
||||
echo "TOOL_DIR := $(GENODE_DIR)/tool"; \
|
||||
$(foreach A,${ARCHIVES(bin)},\
|
||||
target=$(call dst_archive_path,$A); \
|
||||
user=$(call archive_user,$A); \
|
||||
recipe=$(call bin_archive_recipe,$A); \
|
||||
spec=$(call bin_archive_spec,$A); \
|
||||
echo ""; \
|
||||
echo "TARGETS += $$target"; \
|
||||
echo "TOOL($$target) := build_bin_archive"; \
|
||||
echo "ARGS($$target) := $$recipe USER=$$user SPEC=$$spec"; \
|
||||
) \
|
||||
echo -e "\nall: \$$(TARGETS)"; \
|
||||
echo -e "\n\$$(TARGETS):"; \
|
||||
echo -e "\t\$$(MAKE) -f \$$(TOOL_DIR)/depot/mk/\$${TOOL(\$$@)}" \
|
||||
"\$${ARGS(\$$@)} VERBOSE=\$$(VERBOSE)\n"; \
|
||||
) > $@
|
||||
|
||||
|
||||
#
|
||||
# Invoke sub make to process generated makefile
|
||||
#
|
||||
execute_generated_build_mk_file: $(BUILD_MK_FILE)
|
||||
$(VERBOSE)$(MAKE) $(if $(VERBOSE),--quiet) -f $(BUILD_MK_FILE) \
|
||||
-C $(DEPOT_DIR) VERBOSE=$(VERBOSE)
|
||||
|
||||
ifneq ($(FORCE),)
|
||||
execute_generated_build_mk_file: wipe_existing_archives
|
||||
endif
|
||||
|
||||
$(MAKECMDGOALS): execute_generated_build_mk_file
|
||||
@true
|
||||
|
61
tool/depot/create
Executable file
61
tool/depot/create
Executable file
@ -0,0 +1,61 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Tool for assembling API/source/binary archives
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-16
|
||||
#
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Populate depot with source and binary archives based of the current
|
||||
version of the Genode source tree
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <archive-path>...
|
||||
|
||||
This tool is a front end to the 'extract' and 'build' tools.
|
||||
It accepts an arbitrary number of archives without their version
|
||||
suffix as arguments. Furthermore, it supports the supplemental
|
||||
arguments of those tools (like VERBOSE, FORCE, -j<N>).
|
||||
|
||||
The 'create' tool first invokes the 'extract' tool to create the
|
||||
API/source/package/raw archives needed for the specified archives.
|
||||
This step is followed by the invokation of the 'build' tool with
|
||||
archive arguments that match their current versions. Combined
|
||||
with the 'UPDATE_VERSIONS=1' argument, it thereby allows for the
|
||||
source-archive creation, version updating, and building of binary
|
||||
archives via a single command.
|
||||
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../..)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
|
||||
|
||||
.PHONY: extract build
|
||||
|
||||
extract:
|
||||
$(VERBOSE)$(MAKE) -f $(GENODE_DIR)/tool/depot/extract $(MAKECMDGOALS) \
|
||||
VERBOSE=$(VERBOSE) FORCE=$(FORCE) \
|
||||
UPDATE_VERSIONS=$(UPDATE_VERSIONS) \
|
||||
|
||||
|
||||
_versioned_src_of_bin = $1-$(call recipe_version,src/$(call bin_archive_recipe,$1))
|
||||
_versioned_pkg = $1-$(call recipe_version,pkg/$(call bin_archive_recipe,$1))
|
||||
|
||||
versioned_archive = $(if $(call archive_has_type,$1,bin),$(call _versioned_src_of_bin,$1),\
|
||||
$(if $(call archive_has_type,$1,pkg),$(call _versioned_pkg,$1)))
|
||||
|
||||
build: extract
|
||||
$(VERBOSE)$(MAKE) -f $(GENODE_DIR)/tool/depot/build \
|
||||
$(foreach A,$(MAKECMDGOALS),$(call versioned_archive,$A))\
|
||||
VERBOSE=$(VERBOSE) FORCE=$(FORCE) \
|
||||
KEEP_BUILD_DIR=$(KEEP_BUILD_DIR)
|
||||
|
||||
|
||||
$(MAKECMDGOALS): build
|
||||
@true
|
||||
|
63
tool/depot/dependencies
Executable file
63
tool/depot/dependencies
Executable file
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Tool for determining the dependencies of depot content
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-17
|
||||
#
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Show the dependencies of depot content
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <archive-path>...
|
||||
|
||||
This tool operates solely on the depot content. It prints the
|
||||
result only if all dependencies are present within the depot.
|
||||
Otherwise, the missing archives are given as an error message.
|
||||
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../..)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
include $(GENODE_DIR)/tool/depot/mk/categorize_args.inc
|
||||
|
||||
|
||||
#
|
||||
# Collect dependencies for all specified arguments
|
||||
#
|
||||
|
||||
api_file = $(addsuffix /api,$(addprefix $(DEPOT_DIR)/,$1))
|
||||
|
||||
used_apis_file = $(addsuffix /used_apis,$(addprefix $(DEPOT_DIR)/,$1))
|
||||
|
||||
_pkg_archives_of_type = $(call grep_archive_type,$1,\
|
||||
$(call file_content,\
|
||||
$(addsuffix /archives,$(addprefix $(DEPOT_DIR)/,$2))))
|
||||
|
||||
pkg_src_archives = $(call _pkg_archives_of_type,src,$1)
|
||||
pkg_raw_archives = $(call _pkg_archives_of_type,raw,$1)
|
||||
pkg_pkg_archives = $(call _pkg_archives_of_type,pkg,$1)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/dependencies.inc
|
||||
|
||||
|
||||
#
|
||||
# Print gathered information
|
||||
#
|
||||
|
||||
NEEDED_ARCHIVES := $(foreach TYPE,pkg src raw api bin,${ARCHIVES(${TYPE})})
|
||||
MISSING_ARCHIVES := $(sort $(foreach A,$(NEEDED_ARCHIVES),\
|
||||
$(if $(wildcard $(addprefix $(DEPOT_DIR)/,$A)),,$A)))
|
||||
checked_completeness:
|
||||
ifneq ($(MISSING_ARCHIVES),)
|
||||
@echo "Error: incomplete or missing archives:"; \
|
||||
for i in $(MISSING_ARCHIVES); do echo " $$i"; done; false
|
||||
endif
|
||||
|
||||
$(MAKECMDGOALS): checked_completeness
|
||||
@for i in $(NEEDED_ARCHIVES); do echo $$i; done
|
||||
|
42
tool/depot/download
Executable file
42
tool/depot/download
Executable file
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Download packages
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-23
|
||||
#
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Download, verify, and uncompress depot content
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <archive-path> {PUBLIC=<public>}
|
||||
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../..)
|
||||
|
||||
PUBLIC_DIR ?= $(GENODE_DIR)/public
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
|
||||
# sanitize arguments
|
||||
ARGS := $(subst ..,__,$(MAKECMDGOALS))
|
||||
|
||||
DEPENDENCIES_CMD = $(GENODE_DIR)/tool/depot/dependencies $(ARGS)
|
||||
DOWNLOAD_CMD = $(GENODE_DIR)/tool/depot/mk/cp_downloader VERBOSE=$(VERBOSE)
|
||||
|
||||
.PHONY: download
|
||||
download:
|
||||
$(VERBOSE)\
|
||||
while true; do \
|
||||
if $(DEPENDENCIES_CMD) > /dev/null 2> /dev/null; then break; fi; \
|
||||
missing_deps=`$(DEPENDENCIES_CMD) 2> /dev/null | sed -n "/^ /s/ *//p"`; \
|
||||
$(DOWNLOAD_CMD) $$missing_deps || break; \
|
||||
done;
|
||||
|
||||
$(MAKECMDGOALS): download
|
||||
@true
|
||||
|
182
tool/depot/extract
Executable file
182
tool/depot/extract
Executable file
@ -0,0 +1,182 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Extract API/source/binary archives from Genode source tree
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-16
|
||||
#
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Extract API/source/raw archives from the Genode source tree
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <archive-path>...
|
||||
|
||||
The <archive-path> argument denotes the archive to extract in the
|
||||
form of a path. The first path element correponds to the identity
|
||||
of the archive creator, the second element corresponds to the type
|
||||
of the archive, and the third element refers to the recipe of
|
||||
the archive description.
|
||||
|
||||
E.g., the user 'alan' may create the following archives:
|
||||
|
||||
alan/api/libc - an API archive for the libc
|
||||
alan/src/zlib - a source archive for the zlib library
|
||||
|
||||
The following arguments tweak the operation of the tool:
|
||||
|
||||
FORCE=1 Replace existing archives with freshly created
|
||||
ones. This is useful during the development of
|
||||
recipes.
|
||||
|
||||
VERBOSE= Show individual operations.
|
||||
|
||||
-j<N> Enable the parallel creation of packages where
|
||||
<N> denotes the level of parallelism.
|
||||
|
||||
UPDATE_VERSIONS=1 Automatically increase the version of recipe
|
||||
hash files whenever their respective archive
|
||||
content has changed. The versions are named
|
||||
after the current date, suffixed with a single
|
||||
letter to differentiate multiple versions
|
||||
created on the same day.
|
||||
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../..)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
include $(GENODE_DIR)/tool/depot/mk/categorize_args.inc
|
||||
|
||||
|
||||
#
|
||||
# Collect dependencies for all specified arguments
|
||||
#
|
||||
# The following accessor functions used by 'mk/dependencies.inc'. The
|
||||
# information found in the 'archives' file of a package recipe has the
|
||||
# placeholder '_' for the user. Only archives with this placeholder are
|
||||
# considered. The '_user_pkg_archives' function transforms those archive paths
|
||||
# into user-specific archive paths.
|
||||
#
|
||||
|
||||
_file_in_depot = $(wildcard $(DEPOT_DIR)/$(call archive_user,$1)/src/$(call archive_recipe,$1)/$2)
|
||||
_file_in_recipe = $(addsuffix /$2,$(call recipe_dir,src/$(call archive_recipe,$1)))
|
||||
|
||||
_file_in_depot_or_recipe = $(if $(call _file_in_depot,$1,$2),\
|
||||
$(call _file_in_depot,$1,$2),\
|
||||
$(call _file_in_recipe,$1,$2))
|
||||
|
||||
api_file = $(call _file_in_depot_or_recipe,$1,api)
|
||||
used_apis_file = $(call _file_in_depot_or_recipe,$1,used_apis)
|
||||
|
||||
_pkg_archives_file = $(call recipe_dir,pkg/$(call archive_recipe,$1))/archives
|
||||
_user_pkg_archives = $(patsubst _/%,$(call archive_user,$1)/%,\
|
||||
$(call grep_archive_user,_,\
|
||||
$(call file_content,$(call _pkg_archives_file,$1))))
|
||||
|
||||
pkg_src_archives = $(call grep_archive_type,src,$(call _user_pkg_archives,$1))
|
||||
pkg_raw_archives = $(call grep_archive_type,raw,$(call _user_pkg_archives,$1))
|
||||
pkg_pkg_archives = $(call grep_archive_type,pkg,$(call _user_pkg_archives,$1))
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/dependencies.inc
|
||||
|
||||
|
||||
#
|
||||
# Obtain version information from recipes
|
||||
#
|
||||
# The 'archive_version' function takes the archive type and name as arguments
|
||||
# and returns the version identifier as present in the corresponding recipe.
|
||||
# The nested foreach loop populates 'ARCHIVE_VERSION' with the version
|
||||
# identifier for each archive.
|
||||
#
|
||||
# If an archive is given with a complete (versioned) name, we don't need to
|
||||
# consult any recipe but only check if the corresponding archive exists within
|
||||
# the depot. For binary archives, it suffices that the corresponding source
|
||||
# archive is present.
|
||||
#
|
||||
|
||||
$(foreach TYPE,api src raw pkg,\
|
||||
$(foreach PATH,${ARCHIVES(${TYPE})},\
|
||||
$(eval ARCHIVE_VERSION(${PATH}) := $(call archive_version,$(PATH)))))
|
||||
|
||||
archive_exists_in_depot = $(wildcard $(DEPOT_DIR)/$1)
|
||||
|
||||
ARCHIVES_WITH_NO_VERSION := $(sort \
|
||||
$(foreach TYPE,api src raw pkg,\
|
||||
$(foreach A,${ARCHIVES(${TYPE})},\
|
||||
$(if $(call archive_exists_in_depot,$A),,\
|
||||
$(if ${ARCHIVE_VERSION($A)},,$A)))))
|
||||
|
||||
checked_versions_defined:
|
||||
ifneq ($(ARCHIVES_WITH_NO_VERSION),)
|
||||
@echo "Error: incomplete or missing recipe ($(sort $(ARCHIVES_WITH_NO_VERSION)))"; false
|
||||
endif
|
||||
|
||||
|
||||
#
|
||||
# Generate makefile for archive-extraction stage
|
||||
#
|
||||
|
||||
# return versioned archive path, if 'ARCHIVE_VERSION' is undefined, assume
|
||||
# that the argument is already a versiond path
|
||||
versioned_archive = $(if $(ARCHIVE_VERSION($1)),$(addsuffix -${ARCHIVE_VERSION($1)},$1),$1)
|
||||
|
||||
EXTRACT_MK_FILE := $(DEPOT_DIR)/var/extract.mk
|
||||
|
||||
.PHONY: $(EXTRACT_MK_FILE)
|
||||
|
||||
wipe_existing_archives:
|
||||
$(VERBOSE)rm -rf $(addprefix $(DEPOT_DIR)/, $(foreach TYPE,api src raw pkg,\
|
||||
$(foreach A,${ARCHIVES(${TYPE})},\
|
||||
$(call versioned_archive,$A))))
|
||||
|
||||
$(EXTRACT_MK_FILE): checked_versions_defined checked_no_uncategorized
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)( echo -e "all:\n"; \
|
||||
echo "TOOL_DIR := $(GENODE_DIR)/tool"; \
|
||||
$(foreach TYPE,api src raw pkg,\
|
||||
$(foreach A,${ARCHIVES(${TYPE})},\
|
||||
target=$(call versioned_archive,$A); \
|
||||
user=$(call archive_user,$A); \
|
||||
recipe=$(call archive_recipe,$A); \
|
||||
echo ""; \
|
||||
echo "ARCHIVES(${TYPE}) += $$target"; \
|
||||
echo "TOOL($$target) := extract_$(TYPE)_archive"; \
|
||||
echo "ARGS($$target) := $$recipe USER=$$user"; \
|
||||
) ) \
|
||||
echo -e ""; \
|
||||
$(foreach A,${ARCHIVES(pkg)},\
|
||||
$(foreach DEP,$(call pkg_pkg_archives,$A),\
|
||||
echo -e "$(call versioned_archive,$A) :" \
|
||||
"$(call versioned_archive,$(DEP))";)) \
|
||||
echo -e ""; \
|
||||
echo -e "\$${ARCHIVES(src)} : \$${ARCHIVES(api)}"; \
|
||||
echo -e "\$${ARCHIVES(pkg)} : \$${ARCHIVES(api)}"; \
|
||||
echo -e "\$${ARCHIVES(pkg)} : \$${ARCHIVES(src)}"; \
|
||||
echo -e "\$${ARCHIVES(pkg)} : \$${ARCHIVES(raw)}"; \
|
||||
echo -e "\nTARGETS := \$$(foreach T,api src raw pkg,\$${ARCHIVES(\$$T)})"; \
|
||||
echo -e "\nall: \$$(TARGETS)"; \
|
||||
echo -e "\n\$$(TARGETS):"; \
|
||||
echo -e "\t\$$(MAKE) -f \$$(TOOL_DIR)/depot/mk/\$${TOOL(\$$@)}" \
|
||||
"\$${ARGS(\$$@)}" \
|
||||
"VERBOSE=\$$(VERBOSE)" \
|
||||
"UPDATE_VERSIONS=\$$(UPDATE_VERSIONS)\n"; \
|
||||
) > $@
|
||||
|
||||
#
|
||||
# Invoke sub make to process generated makefile
|
||||
#
|
||||
execute_generated_extract_mk_file: $(EXTRACT_MK_FILE)
|
||||
$(VERBOSE)$(MAKE) $(if $(VERBOSE),--quiet) -f $(EXTRACT_MK_FILE) \
|
||||
-C $(DEPOT_DIR) VERBOSE=$(VERBOSE) \
|
||||
UPDATE_VERSIONS=$(UPDATE_VERSIONS)
|
||||
|
||||
ifneq ($(FORCE),)
|
||||
execute_generated_extract_mk_file: wipe_existing_archives
|
||||
endif
|
||||
|
||||
$(MAKECMDGOALS): execute_generated_extract_mk_file
|
||||
@true
|
||||
|
219
tool/depot/mk/build_bin_archive
Executable file
219
tool/depot/mk/build_bin_archive
Executable file
@ -0,0 +1,219 @@
|
||||
#!/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>
|
||||
|
||||
<src-name> name of the source archive to build
|
||||
<spec> build spec, e.g., x86_32, x86_64
|
||||
<user> identity of the archive creator
|
||||
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../../..)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
|
||||
|
||||
#
|
||||
# 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
|
||||
|
||||
|
||||
#
|
||||
# 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
|
||||
|
||||
|
||||
#
|
||||
# Look for src/api to determine whether to build a library or a target.
|
||||
# If building a library, concatenate archive dir as <apihash>/<srchash>.
|
||||
# Otherwise use <srchash> has archive dir.
|
||||
#
|
||||
|
||||
API_FILE := $(wildcard $(addsuffix /api,$(SRC_DIR)))
|
||||
|
||||
ifneq ($(API_FILE),)
|
||||
API := $(call file_content,$(API_FILE))
|
||||
DEPOT_ARCHIVE_DIR := $(DEPOT_BIN_DIR)/$(SPEC)/$(API)/$(VERSIONED_ARCHIVE)
|
||||
else
|
||||
DEPOT_ARCHIVE_DIR := $(DEPOT_BIN_DIR)/$(SPEC)/$(VERSIONED_ARCHIVE)
|
||||
endif
|
||||
|
||||
DEPOT_ARCHIVE_BUILD_DIR := $(addsuffix .build,$(DEPOT_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
|
||||
USED_APIS += $(API)
|
||||
|
||||
# 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
|
||||
|
||||
$(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 "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)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 )
|
||||
|
||||
|
||||
#
|
||||
# Extract build results from build directory into binary-archive directory
|
||||
#
|
||||
|
||||
$(DEPOT_ARCHIVE_DIR): $(DEPOT_ARCHIVE_BUILD_DIR)/bin
|
||||
$(VERBOSE)mkdir -p $@
|
||||
$(VERBOSE)find $< -maxdepth 0 -not -empty -exec cp -rL $</* $@/ \;
|
||||
|
||||
$(TARGET): $(DEPOT_ARCHIVE_DIR)
|
||||
@$(ECHO) "$(DARK_COL)created$(DEFAULT_COL) $(USER)/bin/$(SPEC)/$(VERSIONED_ARCHIVE)"
|
||||
|
||||
|
||||
#
|
||||
# Remove intermediate build artifacts
|
||||
#
|
||||
|
||||
ifeq ($(KEEP_BUILD_DIR),)
|
||||
$(TARGET): remove_build_dir_when_done
|
||||
remove_build_dir_when_done: $(DEPOT_ARCHIVE_DIR)
|
||||
$(VERBOSE)$(RM_BUILD_DIR_CMD)
|
||||
endif
|
||||
|
||||
|
51
tool/depot/mk/categorize_args.inc
Normal file
51
tool/depot/mk/categorize_args.inc
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# \brief Initial processing of archive-path arguments
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-21
|
||||
#
|
||||
# This include transforms an arbitrary number of user-specified arguments
|
||||
# into a digestable representation in the form of the 'ARCHIVES' variables
|
||||
# indexed by the archive type.
|
||||
#
|
||||
|
||||
ARCHIVE_PATHS := $(sort $(MAKECMDGOALS))
|
||||
ARCHIVE_TYPES := api src raw bin pkg
|
||||
|
||||
|
||||
#
|
||||
# Categorize argument paths into the different types of archives.
|
||||
#
|
||||
# The 'categorize_archives' function populates the 'ARCHIVES(<type>)' variables
|
||||
# with the matching paths.
|
||||
#
|
||||
#
|
||||
|
||||
categorize_archives = $(foreach PATH,$(ARCHIVE_PATHS),\
|
||||
$(if $(call archive_has_type,$(PATH),$1),\
|
||||
$(eval ARCHIVES($1) += $(PATH))))
|
||||
|
||||
$(foreach TYPE,$(ARCHIVE_TYPES),$(call categorize_archives,$(TYPE)))
|
||||
|
||||
CATEGORIZED := $(foreach TYPE,$(ARCHIVE_TYPES),${ARCHIVES(${TYPE})})
|
||||
UNCATEGORIZED := $(filter-out $(CATEGORIZED),$(ARCHIVE_PATHS))
|
||||
|
||||
checked_no_uncategorized:
|
||||
ifneq ($(UNCATEGORIZED),)
|
||||
@echo "Error: unknown archive type ($(UNCATEGORIZED))"; false
|
||||
endif
|
||||
|
||||
|
||||
#
|
||||
# Sub-categorize source-pkg archives (<user>/pkg/<name>) from binary-pkg
|
||||
# archives (<user>/pkg/<spec>/<name>) so that 'ARCHIVES(pkg)' contains source
|
||||
# pkgs only, and 'ARCHIVES(binpkg)' contains binary pkgs.
|
||||
#
|
||||
# If the path contains 4 elements, it refers to a binary pkg where the third
|
||||
# element is the build spec. Otherwise, the path refers to a source pkg.
|
||||
#
|
||||
|
||||
_src_pkg = $(if $(word 4,$(subst /, ,$1)),,$1)
|
||||
_bin_pkg = $(if $(word 4,$(subst /, ,$1)),$1,)
|
||||
|
||||
ARCHIVES(binpkg) := $(strip $(foreach PKG,${ARCHIVES(pkg)},$(call _bin_pkg,$(PKG))))
|
||||
ARCHIVES(pkg) := $(strip $(foreach PKG,${ARCHIVES(pkg)},$(call _src_pkg,$(PKG))))
|
32
tool/depot/mk/common.inc
Normal file
32
tool/depot/mk/common.inc
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# \brief Common environment
|
||||
# \author Norman Feske
|
||||
# \date 2014-05-27
|
||||
#
|
||||
|
||||
SHELL := bash
|
||||
VERBOSE ?= @
|
||||
ECHO := echo -e
|
||||
HASHSUM := sha1sum
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
|
||||
BRIGHT_COL ?= \x1b[01;33m
|
||||
DARK_COL ?= \x1b[00;33m
|
||||
DEFAULT_COL ?= \x1b[0m
|
||||
|
||||
MSG_PREFIX_TXT := $(DARK_COL)$(TARGET) $(DEFAULT_COL)
|
||||
MSG_PREFIX := $(ECHO) "$(MSG_PREFIX_TXT)"
|
||||
|
||||
define NEWLINE
|
||||
|
||||
|
||||
endef
|
||||
|
||||
EMPTY :=
|
||||
|
||||
#
|
||||
# Utility to read content from a file if it exists and the given file name
|
||||
# is not empty.
|
||||
#
|
||||
file_content = $(if $(wildcard $1),$(shell cat $1),)
|
46
tool/depot/mk/content_env.mk
Normal file
46
tool/depot/mk/content_env.mk
Normal file
@ -0,0 +1,46 @@
|
||||
#
|
||||
# \brief Environment for executing content.mk files
|
||||
# \author Norman Feske
|
||||
# \date 2006-05-13
|
||||
#
|
||||
# The file is executed from within the archive directory.
|
||||
# The following variables must be defined by the caller:
|
||||
#
|
||||
# GENODE_DIR - root directory of the Genode source tree
|
||||
# CONTRIB_DIR - collection of 3rd-party ports, usually $(GENODE_DIR)/contrib
|
||||
# CONTENT_MK - content.mk file to execute
|
||||
# VERBOSE - verbosity
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Check presence of argument $1. Back out with error message $2 if not defined.
|
||||
#
|
||||
_assert = $(if $1,$1,$(error Error: $2))
|
||||
|
||||
|
||||
#
|
||||
# Utility to query the port directory for a given path to a port description.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# $(call port_dir,$(GENODE_DIR)/repos/libports/ports/libpng)
|
||||
#
|
||||
_hash_of_port = $(shell cat $(call _assert,$(wildcard $1.hash),$(notdir $1) port does not exist))
|
||||
_port_dir = $(wildcard $(CONTRIB_DIR)/$(notdir $1)-$(call _hash_of_port,$1))
|
||||
_checked_port_dir = $(call _assert,$(call _port_dir,$1),$(notdir $1) port is not prepared or outdated)
|
||||
|
||||
port_dir = $(call _checked_port_dir,$1)
|
||||
|
||||
|
||||
#
|
||||
# Handy shortcuts to be used in content.mk files
|
||||
#
|
||||
mirror_from_rep_dir = mkdir -p $(dir $@); cp -r $(REP_DIR)/$@ $(dir $@)
|
||||
|
||||
|
||||
#
|
||||
# Execute recipe's content.mk rules for populating the archive directory
|
||||
#
|
||||
include $(CONTENT_MK)
|
||||
|
71
tool/depot/mk/cp_downloader
Executable file
71
tool/depot/mk/cp_downloader
Executable file
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Simulate the download of files by copying content from a directory
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-23
|
||||
#
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../../..)
|
||||
|
||||
REMOTE_DIR ?= $(GENODE_DIR)/remote
|
||||
PUBLIC_DIR ?= $(GENODE_DIR)/public
|
||||
DEPOT_DIR ?= $(GENODE_DIR)/depot
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Simulate the download of files by copying content from a directory
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <archive-path>...
|
||||
|
||||
endef
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
|
||||
TARGETS := $(addprefix $(DEPOT_DIR)/,$(MAKECMDGOALS))
|
||||
|
||||
|
||||
#
|
||||
# Unpack after checking signature against public key as stored in the depot
|
||||
#
|
||||
# Unfortunately, gpg does not allow us to specify the armored public-key
|
||||
# file directly as keyring for the verify operation. So we need to create a
|
||||
# temporary dearmored version.
|
||||
#
|
||||
|
||||
ARCHIVES := $(MAKECMDGOALS)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/gpg.inc
|
||||
|
||||
$(DEPOT_DIR)/% : $(PUBLIC_DIR)/%.tgz $(PUBLIC_DIR)/%.tgz.gpg
|
||||
$(VERBOSE)pubkey_file=$(DEPOT_DIR)/$(call archive_user,$*)/pubkey; \
|
||||
gpg --yes -o $$pubkey_file.dearmored --dearmor $$pubkey_file; \
|
||||
( gpg --no-tty --no-default-keyring \
|
||||
--keyring $$pubkey_file.dearmored \
|
||||
--verify $(PUBLIC_DIR)/$*.tgz.gpg 2> /dev/null; retval=$$?; \
|
||||
rm -f $$pubkey_file.dearmored; \
|
||||
exit $$retval \
|
||||
) || ( echo -e "Error: could not verify '$*', signature does not match\n" \
|
||||
" public key '$$pubkey_file'"; \
|
||||
false )
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)tar xfz $(PUBLIC_DIR)/$*.tgz -C $(dir $@)
|
||||
|
||||
DOWNLOADED_FILES := $(addprefix $(PUBLIC_DIR)/,$(MAKECMDGOALS:=.tgz)) \
|
||||
$(addprefix $(PUBLIC_DIR)/,$(MAKECMDGOALS:=.tgz.gpg))
|
||||
|
||||
.PRECIOUS: $(DOWNLOADED_FILES)
|
||||
|
||||
ifneq ($(MISSING_PUBKEY_FILES),)
|
||||
$(DOWNLOADED_FILES): missing_pubkey_files
|
||||
endif
|
||||
|
||||
$(PUBLIC_DIR)/%:
|
||||
@$(ECHO) "$(DARK_COL)download$(DEFAULT_COL) $*"
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)cp $(REMOTE_DIR)/$* $@
|
||||
|
||||
$(MAKECMDGOALS): $(TARGETS)
|
||||
@true
|
112
tool/depot/mk/dependencies.inc
Normal file
112
tool/depot/mk/dependencies.inc
Normal file
@ -0,0 +1,112 @@
|
||||
#
|
||||
# \brief Dependency-resolution functions
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-22
|
||||
#
|
||||
# The following accessor functions must be defined when including this file:
|
||||
#
|
||||
# api_file return path to 'api' file of a library source archive
|
||||
# used_apis_file return path to 'used_apis' file for a source archive
|
||||
# pkg_src_archives return source archives of a package
|
||||
# pkg_raw_archives return raw-data archives of a package
|
||||
# pkg_pkg_archives return package-archive dependencies of a package
|
||||
#
|
||||
|
||||
#
|
||||
# Extend ARCHIVES(pkg) with package dependencies
|
||||
#
|
||||
|
||||
_pkg_archives = $(call pkg_pkg_archives,$1)
|
||||
|
||||
_check_unvisited = $(if $(filter $(VISITED_PKGS),$1),\
|
||||
$(error recursive package dependency: $(VISITED_PKGS)),\
|
||||
$(eval VISITED_PKGS += $1))
|
||||
|
||||
_pkg_deps_rec = $(call _check_unvisited,$1) $1 \
|
||||
$(foreach PKG,$(call _pkg_archives,$1),\
|
||||
$(call _pkg_deps_rec,$(PKG)))
|
||||
|
||||
_pkg_deps = $(foreach PKG,$1,\
|
||||
$(eval VISITED_PKGS :=) $(call _pkg_deps_rec,$(PKG)))
|
||||
|
||||
ARCHIVES(pkg) := $(sort ${ARCHIVES(pkg)} $(call _pkg_deps,${ARCHIVES(pkg)}))
|
||||
|
||||
|
||||
#
|
||||
# Extend ARCHIVES(binpkg) with binary-package dependencies
|
||||
#
|
||||
|
||||
# return list of source archives needed by a given binary package
|
||||
_binpkg_src_archives = $(call pkg_src_archives,$(call pkg_of_binpkg,$1))
|
||||
|
||||
# return list of binary archives contained in a binary package
|
||||
_binpkg_bin_archives = $(foreach S,$(call _binpkg_src_archives,$1),\
|
||||
$(call bin_for_src,$(call bin_archive_spec,$1),$S))
|
||||
|
||||
# return list of package archives contained in a binary package
|
||||
_binpkg_pkg_archives = $(foreach P,$(call pkg_pkg_archives,$(call pkg_of_binpkg,$1)),\
|
||||
$(call binpkg_for_pkg,$(call bin_archive_spec,$1),$P))
|
||||
|
||||
# override behavior of '_pkg_archives' to work on binary packages
|
||||
_pkg_archives = $(call _binpkg_pkg_archives,$1)
|
||||
|
||||
ARCHIVES(binpkg) := $(sort ${ARCHIVES(binpkg)} $(call _pkg_deps,${ARCHIVES(binpkg)}))
|
||||
|
||||
|
||||
#
|
||||
# Extend ARCHIVES(pkg) with binary-package dependencies
|
||||
#
|
||||
|
||||
ARCHIVES(pkg) := $(sort ${ARCHIVES(pkg)} $(foreach P,${ARCHIVES(binpkg)},\
|
||||
$(call pkg_of_binpkg,$P)))
|
||||
|
||||
#
|
||||
# Extend ARCHIVES(bin) with binary-package dependencies
|
||||
#
|
||||
|
||||
ARCHIVES(bin) := $(sort ${ARCHIVES(bin)} $(foreach P,${ARCHIVES(binpkg)},\
|
||||
$(call _binpkg_bin_archives,$P)))
|
||||
|
||||
#
|
||||
# Extend ARCHIVES(src) with package dependencies
|
||||
#
|
||||
|
||||
ARCHIVES(src) := $(sort ${ARCHIVES(src)} $(foreach P,${ARCHIVES(pkg)},\
|
||||
$(call pkg_src_archives,$P)))
|
||||
|
||||
#
|
||||
# Extend ARCHIVES(raw) with package dependencies
|
||||
#
|
||||
|
||||
ARCHIVES(raw) := $(sort ${ARCHIVES(raw)} $(foreach P,${ARCHIVES(pkg)},\
|
||||
$(call pkg_raw_archives,$P)))
|
||||
|
||||
#
|
||||
# Extend ARCHIVES(src) with binary dependencies
|
||||
#
|
||||
|
||||
ARCHIVES(src) := $(sort ${ARCHIVES(src)}\
|
||||
$(foreach B,${ARCHIVES(bin)},\
|
||||
$(call src_of_bin,$B)))
|
||||
|
||||
#
|
||||
# Extend ARCHIVES(api) with the APIs used by ARCHIVES(src)
|
||||
#
|
||||
|
||||
_used_apis = $(call file_content,$(call used_apis_file,$1))
|
||||
|
||||
src_api_archives = $(addprefix $(call archive_user,$1)/api/,$(call _used_apis,$1))
|
||||
|
||||
ARCHIVES(api) := $(sort ${ARCHIVES(api)} $(foreach A,${ARCHIVES(src)},\
|
||||
$(call src_api_archives,$A)))
|
||||
|
||||
#
|
||||
# Extend ARCHIVES(api) with the APIs implemented by library ARCHIVES(src)
|
||||
#
|
||||
|
||||
_lib_api = $(call file_content,$(call api_file,$1))
|
||||
|
||||
_lib_api_archive = $(addprefix $(call archive_user,$1)/api/,$(call _lib_api,$1))
|
||||
|
||||
ARCHIVES(api) := $(sort ${ARCHIVES(api)} $(foreach A,${ARCHIVES(src)},\
|
||||
$(call _lib_api_archive,$A)))
|
213
tool/depot/mk/extract.inc
Normal file
213
tool/depot/mk/extract.inc
Normal file
@ -0,0 +1,213 @@
|
||||
#
|
||||
# \brief Common steps of creating an archive within the depot
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-17
|
||||
#
|
||||
# Variables that must be defined when including this file:
|
||||
#
|
||||
# ARCHIVE - archive name, corresponds to recipe name
|
||||
# RECIPE_DIR - location of the archive recipe within the source tree
|
||||
# DEPOT_SUB_DIR - archive-type-dependent destination within the depot
|
||||
# TAG_FILE - file within the archive used as tag for make dependencies
|
||||
# UPDATE_VERSIONS - update recipe hash file if archive content changed
|
||||
#
|
||||
|
||||
|
||||
##
|
||||
## Obtain information about the user-specified archive recipe
|
||||
##
|
||||
## Validate 'RECIPE_DIR', determine the version and content hash as given in
|
||||
## the recipe, and define 'RECIPE_HASH_VALUE' and 'RECIPE_VERSION'. Rules using
|
||||
## those definitions should depend on 'checked_recipe_hash_value_exists'.
|
||||
##
|
||||
|
||||
checked_recipe_dir_specified:
|
||||
ifeq ($(RECIPE_DIR),)
|
||||
@$(ECHO) "Error: recipe for '$(TARGET)' is missing"; false
|
||||
endif
|
||||
|
||||
$(TARGET): checked_recipe_dir_specified
|
||||
|
||||
checked_recipe_is_unique: checked_recipe_dir_specified
|
||||
ifneq ($(RECIPE_DIR),$(firstword $(RECIPE_DIR)))
|
||||
@echo "Error: recipe for '$(TARGET)' is ambiguous, candidates are:";\
|
||||
for dir in $(RECIPE_DIR_CANDIDATES); do \
|
||||
echo " $$dir"; done; \
|
||||
false
|
||||
RECIPE_DIR_CANDIDATES := $(subst %,&,$(RECIPE_DIR))
|
||||
RECIPE_DIR :=
|
||||
endif
|
||||
|
||||
$(TARGET): checked_recipe_is_unique
|
||||
|
||||
#
|
||||
# Determine hash file of current archive version as defined by the recipe
|
||||
#
|
||||
|
||||
ifneq ($(RECIPE_DIR),)
|
||||
EXPECTED_RECIPE_HASH_FILE := $(RECIPE_DIR)/hash
|
||||
RECIPE_HASH_FILE := $(wildcard $(EXPECTED_RECIPE_HASH_FILE))
|
||||
endif
|
||||
|
||||
checked_recipe_hash_file_exists: checked_recipe_is_unique
|
||||
ifeq ($(RECIPE_HASH_FILE),)
|
||||
@$(ECHO) "Error: Recipe hash file is missing,\n" \
|
||||
" expected at '$(EXPECTED_RECIPE_HASH_FILE)'"; false
|
||||
endif
|
||||
|
||||
$(TARGET): checked_recipe_hash_file_exists
|
||||
|
||||
#
|
||||
# Obtain hash value and version identifier from hash file. If no version
|
||||
# identifier is present, the hash value is taken as version ('lastword' is
|
||||
# the same as 'firstword'). This is the normal case for source archives.
|
||||
#
|
||||
|
||||
ifneq ($(RECIPE_HASH_FILE),)
|
||||
_RECIPE_HASH_FILE_CONTENT = $(call file_content,$(RECIPE_HASH_FILE))
|
||||
RECIPE_HASH_VALUE = $(lastword $(_RECIPE_HASH_FILE_CONTENT))
|
||||
RECIPE_VERSION = $(firstword $(_RECIPE_HASH_FILE_CONTENT))
|
||||
endif
|
||||
|
||||
checked_recipe_hash_value_exists:
|
||||
ifeq ($(RECIPE_HASH_VALUE),)
|
||||
@$(ECHO) "Error: archive hash is undefined"; false
|
||||
endif
|
||||
|
||||
#
|
||||
# Remember content hash at invocation time, to detect a potential update caused
|
||||
# by the 'UPDATE_VERSIONS' feature.
|
||||
#
|
||||
ORIG_RECIPE_HASH_VALUE := $(RECIPE_HASH_VALUE)
|
||||
|
||||
#
|
||||
# Define name of temporary archive directory that we use until we know the
|
||||
# archive hash.
|
||||
#
|
||||
|
||||
DEPOT_ARCHIVE_DIR := $(DEPOT_SUB_DIR)/$(ARCHIVE).incomplete
|
||||
|
||||
reset_stale_temporary_archive_dir:
|
||||
ifneq ($(wildcard $(DEPOT_ARCHIVE_DIR)),)
|
||||
$(VERBOSE)rm -rf $(DEPOT_ARCHIVE_DIR); mkdir -p $(DEPOT_ARCHIVE_DIR)
|
||||
endif
|
||||
|
||||
$(DEPOT_ARCHIVE_DIR)/$(TAG_FILE): reset_stale_temporary_archive_dir
|
||||
|
||||
|
||||
##
|
||||
## Create archive
|
||||
##
|
||||
|
||||
#
|
||||
# Rename archive to the hashed name after successful completion
|
||||
#
|
||||
$(ARCHIVE): _rename_to_final_archive
|
||||
|
||||
#
|
||||
# Rename archive name from the temporary name to the hashed name. However,
|
||||
# if the hashed archive name already exists, keep the existing one and
|
||||
# discard the just-built archive.
|
||||
#
|
||||
_rename_to_final_archive: _check_hash
|
||||
@$(VERBOSE)final_name=$(ARCHIVE)-$(RECIPE_VERSION); \
|
||||
rm -rf $(DEPOT_SUB_DIR)/$$final_name; \
|
||||
mv $(DEPOT_ARCHIVE_DIR) $(DEPOT_SUB_DIR)/$$final_name; \
|
||||
hash=$$(< $(DEPOT_ARCHIVE_DIR).hash); hint=""; \
|
||||
test $$hash = $(ORIG_RECIPE_HASH_VALUE) ||\
|
||||
hint=" $(BRIGHT_COL)(new version)$(DEFAULT_COL)"; \
|
||||
rm -f $(DEPOT_ARCHIVE_DIR).hash; \
|
||||
$(ECHO) "$(DARK_COL)created$(DEFAULT_COL)" \
|
||||
"$(USER)/$(notdir $(DEPOT_SUB_DIR))/$$final_name$$hint"; \
|
||||
true;
|
||||
|
||||
#
|
||||
# Generate suggested version name for 'HASH_OUT_OF_DATE_MESSAGE'
|
||||
#
|
||||
# We suggest to use the current date as version. If there is already a version
|
||||
# with the current date, we add a single-letter suffix to distinguish the new
|
||||
# version. If we run out of letters or if the old recipe's version cannot be
|
||||
# compared with the current date, we suggest to append a '-x' to the old
|
||||
# recipe's version. In the latter case (e.g., when using a versioning scheme
|
||||
# not based on dates), the package creator may want to manually adjust the
|
||||
# version identifier anyway.
|
||||
#
|
||||
suffix_from_list = $(subst $(EMPTY) $(EMPTY),,$(strip $1))
|
||||
suffixed_version = $1$(if $(call suffix_from_list,$2),-$(call suffix_from_list,$2),)
|
||||
|
||||
_string_higher_than = $(filter-out $(firstword $(sort $1 $2)),$1)
|
||||
_higher_string = $(if $(call _string_higher_than,$1,$2),$1,$2)
|
||||
|
||||
CURRENT_DATE = $(strip $(shell date --iso-8601))
|
||||
|
||||
_version_higher_than_recipe = $(call _string_higher_than,\
|
||||
$(call suffixed_version,$1,$2),$(RECIPE_VERSION))
|
||||
|
||||
_next_version = $(eval FOUND := $(if $(call _version_higher_than_recipe,$1,$2),\
|
||||
$(call suffixed_version,$1,$2)))\
|
||||
$(foreach C,a b c d e f g h i j k l m n o p q r s t u v w x y z,\
|
||||
$(if $(FOUND),,\
|
||||
$(if $(call _version_higher_than_recipe,$1,$2 $C),\
|
||||
$(eval FOUND := $(call suffixed_version,$1,$2 $C)))))\
|
||||
$(if $(FOUND),$(FOUND),$(addsuffix -x,$(RECIPE_VERSION)))
|
||||
|
||||
next_version = $(strip $(call _next_version,$(CURRENT_DATE)))
|
||||
|
||||
#
|
||||
# Message presented to the user whenever a recipe hash is out of date
|
||||
#
|
||||
define HASH_OUT_OF_DATE_MESSAGE
|
||||
|
||||
Error: $(RECIPE_HASH_FILE) is out of date.
|
||||
|
||||
This error indicates that the archived source code has changed, which should
|
||||
be reflected by incrementing the archive version and updating the hash of
|
||||
the recipe. You may update the recipe hash via the following command:
|
||||
|
||||
echo" "$(next_version)" $$hash "> $(RECIPE_HASH_FILE)
|
||||
|
||||
The above command takes the current date as version identifier. Should this
|
||||
not be your intention, please adjust the hash file manually.
|
||||
|
||||
endef
|
||||
|
||||
|
||||
ifeq ($(UPDATE_VERSIONS),)
|
||||
HASH_MISMATCH_CMD = $(ECHO) "$(subst $(NEWLINE),\n,$(HASH_OUT_OF_DATE_MESSAGE))"; false
|
||||
else
|
||||
HASH_MISMATCH_CMD = echo "$(next_version) $$hash" > $(RECIPE_HASH_FILE);
|
||||
endif
|
||||
|
||||
#
|
||||
# Check the consistency between the hash of the archive recipe and the actual
|
||||
# hash of the generated archive. If both hash values differ, we print the
|
||||
# expected hash value and remove the archive. The user is expected to
|
||||
# update the recipe hash before attempting the archive creation again.
|
||||
#
|
||||
_check_hash: $(DEPOT_ARCHIVE_DIR).hash checked_recipe_hash_value_exists
|
||||
$(VERBOSE)hash=$$(< $(DEPOT_ARCHIVE_DIR).hash); \
|
||||
test $$hash = $(RECIPE_HASH_VALUE) || ($(HASH_MISMATCH_CMD))
|
||||
|
||||
#
|
||||
# Shell command used to calculate the hash of an archive
|
||||
#
|
||||
# The command is invoked from within the archive directory within the depot.
|
||||
#
|
||||
# The 'echo' right before 'cat' is needed to handle the special case where
|
||||
# 'find' is executed in an empty directory (yielding an empty result), which
|
||||
# would otherwise prompt 'cat' to block for standard input.
|
||||
#
|
||||
HASH_CMD := cd $(DEPOT_ARCHIVE_DIR); \
|
||||
echo | cat `find . -type f | LC_COLLATE=C sort` | $(HASHSUM) | sed "s/ .*//" \
|
||||
|
||||
#
|
||||
# Generate the hash from the archive content
|
||||
#
|
||||
$(DEPOT_ARCHIVE_DIR).hash: $(DEPOT_ARCHIVE_DIR)/$(TAG_FILE)
|
||||
$(VERBOSE)$(HASH_CMD) > $@
|
||||
|
||||
$(DEPOT_ARCHIVE_DIR):
|
||||
$(VERBOSE)mkdir -p $@
|
||||
|
||||
$(DEPOT_ARCHIVE_DIR)/$(TAG_FILE): $(DEPOT_ARCHIVE_DIR)
|
||||
|
54
tool/depot/mk/extract_api_archive
Executable file
54
tool/depot/mk/extract_api_archive
Executable file
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Tool for assembling an API archive
|
||||
# \author Norman Feske
|
||||
# \date 2016-05-13
|
||||
#
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Tool for assembling an API archive
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <api-name> USER=<user>
|
||||
|
||||
<api-name> name of API, usually the name of the library that
|
||||
implements the API
|
||||
<user> identity of the archive creator
|
||||
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../../..)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
|
||||
#
|
||||
# The target is the name of the archive
|
||||
#
|
||||
ARCHIVE := $(TARGET)
|
||||
TAG_FILE := LICENSE
|
||||
|
||||
#
|
||||
# Define location of recipe and the exported archive
|
||||
#
|
||||
RECIPE_DIR := $(call recipe_dir,api/$(ARCHIVE))
|
||||
REP_DIR := $(RECIPE_DIR:/recipes/api/$(ARCHIVE)=)
|
||||
DEPOT_SUB_DIR := $(DEPOT_DIR)/$(USER)/api
|
||||
|
||||
#
|
||||
# Include common archive-creation steps
|
||||
#
|
||||
include $(GENODE_DIR)/tool/depot/mk/extract.inc
|
||||
include $(GENODE_DIR)/tool/depot/mk/extract_content.inc
|
||||
|
||||
#
|
||||
# Add suplements that are specific for API archives
|
||||
#
|
||||
$(DEPOT_ARCHIVE_DIR).hash: $(DEPOT_ARCHIVE_DIR)/lib/mk/$(ARCHIVE).mk
|
||||
|
||||
$(DEPOT_ARCHIVE_DIR)/lib/mk/$(ARCHIVE).mk:
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)touch $@
|
||||
|
62
tool/depot/mk/extract_content.inc
Normal file
62
tool/depot/mk/extract_content.inc
Normal file
@ -0,0 +1,62 @@
|
||||
#
|
||||
# \brief Rule for populating an archive by evaluating a content.mk file
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-17
|
||||
#
|
||||
# This file complements 'create.inc' for the creation of API and source
|
||||
# archives.
|
||||
#
|
||||
# Arguments:
|
||||
#
|
||||
# RECIPE_DIR - location of the recipe for the source or API archive
|
||||
# DEPOT_ARCHIVE_DIR - archive destination within the depot
|
||||
# TAG_FILE - file within archive used as tag for make dependencies
|
||||
# GENODE_DIR - root of the Genode source tree
|
||||
# REP_DIR - source repository where 'RECIPE_DIR' is located
|
||||
#
|
||||
|
||||
#
|
||||
# Validate existance of a content.mk file for the archive recipe
|
||||
#
|
||||
ifneq ($(RECIPE_DIR),)
|
||||
EXPECTED_CONTENT_MK_FILE := $(RECIPE_DIR)/content.mk
|
||||
CONTENT_MK_FILE := $(wildcard $(EXPECTED_CONTENT_MK_FILE))
|
||||
endif
|
||||
|
||||
checked_content_mk_exists: checked_recipe_is_unique
|
||||
ifeq ($(CONTENT_MK_FILE),)
|
||||
@$(ECHO) "Error: Recipe misses content.mk file,\n" \
|
||||
" expected at '$(EXPECTED_CONTENT_MK_FILE)'"; false
|
||||
endif
|
||||
|
||||
$(TARGET) $(DEPOT_ARCHIVE_DIR)/$(TAG_FILE): checked_content_mk_exists
|
||||
|
||||
#
|
||||
# Handle the creation of the TAG_FILE (and the population of the archive
|
||||
# directory as its side effect) as an atomic step. Otherwise a dependent
|
||||
# rule - in particular the rule for generating the hash - could be
|
||||
# triggered as soon as the specific tag file appears but before the entire
|
||||
# sub make is finished with populating the archive directory.
|
||||
#
|
||||
.NOTPARALLEL: $(DEPOT_ARCHIVE_DIR)/$(TAG_FILE)
|
||||
|
||||
#
|
||||
# Assemble archive content by invoking the recipe's content.mk file
|
||||
#
|
||||
# If an error (such as a missing installation of a port) occurs during this
|
||||
# step, remove the incomplete archive before returning an error.
|
||||
#
|
||||
QUIET := $(if $(VERBOSE),--quiet)
|
||||
$(DEPOT_ARCHIVE_DIR)/$(TAG_FILE): $(CONTENT_MK_FILE)
|
||||
$(VERBOSE)$(MAKE) $(QUIET) -f $(GENODE_DIR)/tool/depot/mk/content_env.mk \
|
||||
-C $(DEPOT_ARCHIVE_DIR) \
|
||||
CONTENT_MK=$< \
|
||||
GENODE_DIR=$(GENODE_DIR) \
|
||||
REP_DIR=$(REP_DIR) \
|
||||
CONTRIB_DIR=$(GENODE_DIR)/contrib || \
|
||||
( rm -r $(DEPOT_ARCHIVE_DIR); false )
|
||||
$(VERBOSE)find $(DEPOT_ARCHIVE_DIR) \( -name "*~" \
|
||||
-or -name "*.rej" \
|
||||
-or -name "*.orig" \
|
||||
-or -name "*.swp" \) -delete
|
||||
|
84
tool/depot/mk/extract_pkg_archive
Executable file
84
tool/depot/mk/extract_pkg_archive
Executable file
@ -0,0 +1,84 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Tool for assembling a package archive
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-17
|
||||
#
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Tool for assembling a package archive
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <pkg-name> USER=<user>
|
||||
|
||||
<pkg-name> name of the package
|
||||
<user> identity of the archive creator
|
||||
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../../..)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
|
||||
#
|
||||
# The target is the name of the archive
|
||||
#
|
||||
ARCHIVE := $(TARGET)
|
||||
TAG_FILE := README
|
||||
|
||||
#
|
||||
# Define location of recipe and the exported archive
|
||||
#
|
||||
RECIPE_DIR := $(call recipe_dir,pkg/$(ARCHIVE))
|
||||
DEPOT_SUB_DIR := $(DEPOT_DIR)/$(USER)/pkg
|
||||
|
||||
#
|
||||
# Include common archive-creation steps
|
||||
#
|
||||
include $(GENODE_DIR)/tool/depot/mk/extract.inc
|
||||
|
||||
#
|
||||
# Generate 'archives' list with version information
|
||||
#
|
||||
_version = $(call recipe_version,$(call archive_type,$1)/$(call archive_recipe,$1))
|
||||
|
||||
_versioned_entry = _/$(call archive_type,$1)/$(call archive_recipe,$1)-$(call _version,$1)
|
||||
|
||||
VERSIONED_ARCHIVES := $(foreach A,$(call file_content,$(RECIPE_DIR)/archives),\
|
||||
$(if $(call archive_has_user,$A,_),$(call _versioned_entry,$A),$A))
|
||||
|
||||
$(DEPOT_ARCHIVE_DIR).hash: $(DEPOT_ARCHIVE_DIR)/_archives
|
||||
|
||||
$(DEPOT_ARCHIVE_DIR)/_archives: checked_recipe_hash_value_exists
|
||||
$(VERBOSE)( $(foreach A,$(VERSIONED_ARCHIVES),echo "$A";) ) > $@
|
||||
|
||||
#
|
||||
# Copy remaining recipe content to archive as is, except for files with a
|
||||
# special meaning or backup files.
|
||||
#
|
||||
RECIPE_FILES := $(notdir $(wildcard $(RECIPE_DIR)/*))
|
||||
RECIPE_FILES := $(patsubst %~,,$(RECIPE_FILES))
|
||||
RECIPE_FILES := $(filter-out archives hash,$(RECIPE_FILES))
|
||||
|
||||
checked_readme_exists:
|
||||
ifneq ($(filter-out $(RECIPE_FILES),README),)
|
||||
@$(ECHO) "Error: missing README in package recipe, expected:\n" \
|
||||
" $(RECIPE_DIR)/README"; false
|
||||
endif
|
||||
|
||||
.NOTPARALLEL: $(DEPOT_ARCHIVE_DIR)/$(TAG_FILE)
|
||||
|
||||
$(DEPOT_ARCHIVE_DIR)/$(TAG_FILE): checked_readme_exists
|
||||
$(VERBOSE)cp $(addprefix $(RECIPE_DIR)/,$(RECIPE_FILES)) $(DEPOT_ARCHIVE_DIR)/
|
||||
|
||||
#
|
||||
# Replace the '_' marker in the 'archives' list with the actual user name
|
||||
#
|
||||
$(DEPOT_ARCHIVE_DIR)/archives: $(DEPOT_ARCHIVE_DIR).hash $(DEPOT_ARCHIVE_DIR)/_archives
|
||||
$(VERBOSE)sed "s/^_/$(USER)/" $(DEPOT_ARCHIVE_DIR)/_archives > $@
|
||||
$(VERBOSE)rm -f $(DEPOT_ARCHIVE_DIR)/_archives
|
||||
|
||||
_rename_to_final_archive: $(DEPOT_ARCHIVE_DIR)/archives
|
48
tool/depot/mk/extract_raw_archive
Executable file
48
tool/depot/mk/extract_raw_archive
Executable file
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Tool for assembling a raw-data archive
|
||||
# \author Norman Feske
|
||||
# \date 2016-05-13
|
||||
#
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Tool for assembling a raw-data archive
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <raw-name> USER=<user>
|
||||
|
||||
<raw-name> name of the raw-data archive
|
||||
<user> identity of the archive creator
|
||||
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../../..)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
|
||||
#
|
||||
# The target is the name of the archive
|
||||
#
|
||||
ARCHIVE := $(TARGET)
|
||||
TAG_FILE := none
|
||||
|
||||
ifeq ($(USER),)
|
||||
$(error USER undefined)
|
||||
endif
|
||||
|
||||
#
|
||||
# Define location of recipe and the exported archive
|
||||
#
|
||||
RECIPE_DIR := $(call recipe_dir,raw/$(ARCHIVE))
|
||||
REP_DIR := $(RECIPE_DIR:/recipes/raw/$(ARCHIVE)=)
|
||||
DEPOT_SUB_DIR := $(DEPOT_DIR)/$(USER)/raw
|
||||
|
||||
#
|
||||
# Include common archive-creation steps
|
||||
#
|
||||
include $(GENODE_DIR)/tool/depot/mk/extract.inc
|
||||
include $(GENODE_DIR)/tool/depot/mk/extract_content.inc
|
||||
|
93
tool/depot/mk/extract_src_archive
Executable file
93
tool/depot/mk/extract_src_archive
Executable file
@ -0,0 +1,93 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Tool for assembling a source archive
|
||||
# \author Norman Feske
|
||||
# \date 2016-05-13
|
||||
#
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Tool for assembling a source archive
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <src-name> USER=<user>
|
||||
|
||||
<src-name> name of the source archive
|
||||
<user> identity of the archive creator
|
||||
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../../..)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
|
||||
#
|
||||
# The target is the name of the archive
|
||||
#
|
||||
ARCHIVE := $(TARGET)
|
||||
TAG_FILE := LICENSE
|
||||
|
||||
ifeq ($(USER),)
|
||||
$(error USER undefined)
|
||||
endif
|
||||
|
||||
#
|
||||
# Define location of recipe and the exported archive
|
||||
#
|
||||
RECIPE_DIR := $(call recipe_dir,src/$(ARCHIVE))
|
||||
REP_DIR := $(RECIPE_DIR:/recipes/src/$(ARCHIVE)=)
|
||||
DEPOT_SUB_DIR := $(DEPOT_DIR)/$(USER)/src
|
||||
|
||||
#
|
||||
# Include common archive-creation steps
|
||||
#
|
||||
include $(GENODE_DIR)/tool/depot/mk/extract.inc
|
||||
include $(GENODE_DIR)/tool/depot/mk/extract_content.inc
|
||||
|
||||
#
|
||||
# Add used_apis information, supplemented with the current API hashes
|
||||
#
|
||||
ifneq ($(wildcard $(RECIPE_DIR)/used_apis),)
|
||||
$(DEPOT_ARCHIVE_DIR).hash: $(DEPOT_ARCHIVE_DIR)/used_apis
|
||||
endif
|
||||
|
||||
$(DEPOT_ARCHIVE_DIR)/used_apis: $(DEPOT_ARCHIVE_DIR)
|
||||
$(DEPOT_ARCHIVE_DIR)/used_apis: $(RECIPE_DIR)/used_apis
|
||||
$(VERBOSE) \
|
||||
for api in $(shell cat $<); do \
|
||||
hash_file=$(GENODE_DIR)/repos/**/recipes/api/$$api/hash; \
|
||||
if [ ! -f $$hash_file ]; then \
|
||||
echo "Error: archive $(ARCHIVE) depends on nonexisting API '$$api',"; \
|
||||
echo " expected $$hash_file"; \
|
||||
rm -r $(DEPOT_ARCHIVE_DIR); \
|
||||
result=false; \
|
||||
break; \
|
||||
fi; \
|
||||
hash_file_content=$$(< $$hash_file); \
|
||||
version=$${hash_file_content%% *}; \
|
||||
echo "$$api-$$version" >> $@; \
|
||||
done; $$result
|
||||
|
||||
#
|
||||
# If the archive is a library, add the hash of its implemented API
|
||||
#
|
||||
ifneq ($(wildcard $(RECIPE_DIR)/api),)
|
||||
$(DEPOT_ARCHIVE_DIR).hash: $(DEPOT_ARCHIVE_DIR)/api
|
||||
endif
|
||||
$(DEPOT_ARCHIVE_DIR)/api: $(DEPOT_ARCHIVE_DIR)
|
||||
$(DEPOT_ARCHIVE_DIR)/api: $(RECIPE_DIR)/api
|
||||
$(VERBOSE) \
|
||||
api=$$(< $<); \
|
||||
hash_file=$(GENODE_DIR)/repos/**/recipes/api/$$api/hash; \
|
||||
if [ ! -f $$hash_file ]; then \
|
||||
echo "Error: library '$(ARCHIVE)' implements unknown API '$$api',"; \
|
||||
echo " expected $$hash_file"; \
|
||||
rm -r $(DEPOT_ARCHIVE_DIR); \
|
||||
exit -1; \
|
||||
fi; \
|
||||
hash_file_content=$$(< $$hash_file); \
|
||||
version=$${hash_file_content%% *}; \
|
||||
echo "$$api-$$version" >> $@;
|
||||
|
67
tool/depot/mk/front_end.inc
Normal file
67
tool/depot/mk/front_end.inc
Normal file
@ -0,0 +1,67 @@
|
||||
#
|
||||
# 'GENODE_DIR' must be defined before including this file
|
||||
#
|
||||
|
||||
TARGET := $(firstword $(sort $(MAKECMDGOALS)))
|
||||
.PHONY: $(TARGET)
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/common.inc
|
||||
|
||||
# list of all repositories located at '<genode-dir>/repos/'
|
||||
REPOSITORIES ?= $(shell find $(GENODE_DIR)/repos -follow -mindepth 1 -maxdepth 1 -type d)
|
||||
|
||||
# list of all repositories that contain depot recipes
|
||||
REP_RECIPES_DIRS := $(wildcard $(addsuffix /recipes,$(REPOSITORIES)))
|
||||
|
||||
DEPOT_DIR := $(GENODE_DIR)/depot
|
||||
|
||||
usage:
|
||||
@$(ECHO) "$(subst $(NEWLINE),\n,$(HELP_MESSAGE))";
|
||||
|
||||
|
||||
#
|
||||
# Helper functions
|
||||
#
|
||||
|
||||
# function for looking up a recipe directory from one of the repositories
|
||||
recipe_dir = $(wildcard $(addsuffix /$1,$(REP_RECIPES_DIRS)))
|
||||
|
||||
# function for returning the archive version as given in the recipe
|
||||
recipe_version = $(firstword $(call file_content,$(addsuffix /hash,$(call recipe_dir,$1))))
|
||||
|
||||
|
||||
#
|
||||
# Accessor functions for various elements of archive paths
|
||||
#
|
||||
|
||||
sanitized = $(subst ..,__,$1)
|
||||
|
||||
path_element = $(call sanitized,$(word $1,$(subst /, ,$2)))
|
||||
|
||||
archive_user = $(call path_element,1,$1)
|
||||
archive_type = $(call path_element,2,$1)
|
||||
archive_recipe = $(call path_element,3,$1)
|
||||
archive_has_type = $(filter $(call archive_type,$1),$2)
|
||||
archive_has_user = $(filter $(call archive_user,$1),$2)
|
||||
archive_version = $(call recipe_version,$(addprefix $(call archive_type,$1)/,$(call archive_recipe,$1)))
|
||||
|
||||
# binary archives have the form <user>/bin/<spec>/<name>{-<version>}
|
||||
bin_archive_spec = $(call path_element,3,$1)
|
||||
bin_archive_recipe = $(call path_element,4,$1)
|
||||
bin_archive_version = $(call recipe_version,src/$(call bin_archive_recipe,$1))
|
||||
|
||||
grep_archive_type = $(foreach A,$2,$(if $(call archive_has_type,$A,$1),$A,))
|
||||
grep_archive_user = $(foreach A,$2,$(if $(call archive_has_user,$A,$1),$A,))
|
||||
|
||||
# return pkg-archive path of given binary-pkg archive path
|
||||
pkg_of_binpkg = $(call archive_user,$1)/pkg/$(call bin_archive_recipe,$1)
|
||||
|
||||
# return binary-archive path for architecture $1 and source archive $2
|
||||
bin_for_src = $(call archive_user,$2)/bin/$1/$(call archive_recipe,$2)
|
||||
|
||||
# return source-archive path for given binary-archive path
|
||||
src_of_bin = $(call archive_user,$1)/src/$(call bin_archive_recipe,$1)
|
||||
|
||||
# return binary-package archive path for architecture $1 and package archive $2
|
||||
binpkg_for_pkg = $(call archive_user,$2)/bin/$1/$(call archive_recipe,$2)
|
||||
|
21
tool/depot/mk/gpg.inc
Normal file
21
tool/depot/mk/gpg.inc
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# \brief Helper for using the GNU privacy guard
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-27
|
||||
#
|
||||
|
||||
pubkey_filename = $(call archive_user,$1)/pubkey
|
||||
pubkey_path = $(wildcard $(DEPOT_DIR)/$(call pubkey_filename,$1))
|
||||
|
||||
# obtain key ID of 'depot/<user>/pubkey' to be used to select signing key
|
||||
pubkey_id = $(shell gpg --with-colon < $(call pubkey_path,$1) | head -1 | cut -d: -f5 )
|
||||
|
||||
MISSING_PUBKEY_FILES := $(sort \
|
||||
$(foreach A,$(ARCHIVES),\
|
||||
$(if $(call pubkey_path,$A),,\
|
||||
$(DEPOT_DIR)/$(call pubkey_filename,$A))))
|
||||
|
||||
missing_pubkey_files:
|
||||
@echo "Error: missing public-key files:";\
|
||||
for i in $(MISSING_PUBKEY_FILES); do echo " $$i"; done; false
|
||||
|
87
tool/depot/publish
Executable file
87
tool/depot/publish
Executable file
@ -0,0 +1,87 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Tool for assembling a package archive
|
||||
# \author Norman Feske
|
||||
# \date 2017-03-17
|
||||
#
|
||||
|
||||
define HELP_MESSAGE
|
||||
|
||||
Compress and sign depot content for publishing
|
||||
|
||||
usage:
|
||||
|
||||
$(firstword $(MAKEFILE_LIST)) <archive-path> {PUBLIC=<public>}
|
||||
|
||||
The <archive-path> denotes the archives (and implicitly their
|
||||
dependencies) to publish from the depot to the public directory.
|
||||
It must be given including the version number of the package archive.
|
||||
|
||||
This tool does not touch any Genode source repository. It solely
|
||||
reads from the depot and writes to the public directory.
|
||||
|
||||
The optional 'PUBLIC' argument defines the location of the public
|
||||
directory. If not specified, '<genode-dir>/public/' is used.
|
||||
|
||||
endef
|
||||
|
||||
export GENODE_DIR := $(realpath $(dir $(MAKEFILE_LIST))/../..)
|
||||
|
||||
PUBLIC_DIR ?= $(GENODE_DIR)/public
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/front_end.inc
|
||||
|
||||
|
||||
#
|
||||
# Determine dependencies, check for completeness
|
||||
#
|
||||
|
||||
ifneq ($(MAKECMDGOALS),)
|
||||
DEPENDENCIES_CMD := $(GENODE_DIR)/tool/depot/dependencies $(MAKECMDGOALS)
|
||||
DEPENDENCIES_RESULT := $(shell $(DEPENDENCIES_CMD) 2> /dev/null || true)
|
||||
endif
|
||||
|
||||
ifeq ($(filter Error:,$(DEPENDENCIES_RESULT)),)
|
||||
ARCHIVES := $(DEPENDENCIES_RESULT)
|
||||
else
|
||||
ARCHIVES :=
|
||||
$(MAKECMDGOALS): dependencies_error
|
||||
endif
|
||||
|
||||
# re-execute the dependencies command to present the error to the user
|
||||
dependencies_error:
|
||||
@$(DEPENDENCIES_CMD)
|
||||
|
||||
|
||||
#
|
||||
# Generate compressed and signed archives
|
||||
#
|
||||
|
||||
include $(GENODE_DIR)/tool/depot/mk/gpg.inc
|
||||
|
||||
MISSING_PUBKEY_FILES := $(sort \
|
||||
$(foreach A,$(ARCHIVES),\
|
||||
$(if $(call pubkey_path,$A),,\
|
||||
$(DEPOT_DIR)/$(call pubkey_filename,$A))))
|
||||
|
||||
TARGETS := $(addsuffix .tgz.gpg,$(addprefix $(PUBLIC_DIR)/,$(ARCHIVES)))
|
||||
|
||||
$(PUBLIC_DIR)/%.tgz.gpg : $(PUBLIC_DIR)/%.tgz
|
||||
$(VERBOSE)rm -f $@;
|
||||
$(VERBOSE)gpg --sign --no-tty --use-agent --local-user $(call pubkey_id,$*) $<
|
||||
|
||||
.PRECIOUS: $(TARGETS:.tgz.gpg=.tgz)
|
||||
|
||||
$(PUBLIC_DIR)/%.tgz: $(DEPOT_DIR)/%
|
||||
@$(ECHO) "$(DARK_COL)publish$(DEFAULT_COL) $@"
|
||||
$(VERBOSE)test -e $(dir $@) || mkdir -p $(dir $@)
|
||||
$(VERBOSE)tar czf $@ -C $(dir $<) $(notdir $<)
|
||||
|
||||
ifneq ($(MISSING_PUBKEY_FILES),)
|
||||
$(MAKECMDGOALS) $(TARGETS): missing_pubkey_files
|
||||
endif
|
||||
|
||||
$(MAKECMDGOALS): $(TARGETS)
|
||||
@true
|
||||
|
Loading…
Reference in New Issue
Block a user