mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-02 16:52:52 +00:00
parent
ba291bcc57
commit
a128b40f03
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,7 +4,7 @@
|
|||||||
*.rej
|
*.rej
|
||||||
|
|
||||||
/build
|
/build
|
||||||
|
/contrib
|
||||||
/repos/base-codezero/contrib
|
/repos/base-codezero/contrib
|
||||||
/repos/base-fiasco/contrib
|
/repos/base-fiasco/contrib
|
||||||
/repos/base-fiasco/download
|
/repos/base-fiasco/download
|
||||||
|
273
tool/ports/mk/install.mk
Normal file
273
tool/ports/mk/install.mk
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
#
|
||||||
|
# \brief Download and patch port of 3rd-party source code
|
||||||
|
# \author Norman Feske
|
||||||
|
# \date 2014-05-07
|
||||||
|
#
|
||||||
|
# This makefile must be invoked from the port directory.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
#
|
||||||
|
# PORT - port description file
|
||||||
|
#
|
||||||
|
# This makefile includes the port description file. The namespace for variables
|
||||||
|
# is organized as follows: Variables and functions that are private to the
|
||||||
|
# prepare_port tool are prefixed with '_'. Port description files must not
|
||||||
|
# declare any variable with a leading '_'. Variables that interface the
|
||||||
|
# prepare_port tool with the port description file are written uppercase. Local
|
||||||
|
# helper variables in the port description files should be written lowercase.
|
||||||
|
#
|
||||||
|
|
||||||
|
# XXX remove this line when the tool has stabilized
|
||||||
|
STRICT_HASH ?= no
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
# repository that contains the port description, used to look up patch files
|
||||||
|
REP_DIR := $(realpath $(dir $(PORT))/..)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check presence of argument $1. Back out with error message $2 if not defined.
|
||||||
|
#
|
||||||
|
_assert = $(if $(strip $1),$1,$(info Error: $(strip $2))$(error ))
|
||||||
|
|
||||||
|
#
|
||||||
|
# Helper function that returns $1 if defined, otherwise it returns $2
|
||||||
|
#
|
||||||
|
_prefer = $(if $1,$1,$2)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Include definitions provided by the port description file
|
||||||
|
#
|
||||||
|
include $(PORT)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Common environment
|
||||||
|
#
|
||||||
|
SHELL := bash
|
||||||
|
VERBOSE ?= @
|
||||||
|
ECHO := echo -e
|
||||||
|
HASHSUM := sha1sum
|
||||||
|
|
||||||
|
BRIGHT_COL ?= \033[01;33m
|
||||||
|
DARK_COL ?= \033[00;33m
|
||||||
|
DEFAULT_COL ?= \033[0m
|
||||||
|
|
||||||
|
MSG_PREFIX := $(ECHO) "$(DARK_COL)$(notdir $(PORT:.port=)) $(DEFAULT_COL)"
|
||||||
|
MSG_DOWNLOAD := $(MSG_PREFIX)"download "
|
||||||
|
MSG_APPLY := $(MSG_PREFIX)"apply "
|
||||||
|
MSG_UPDATE := $(MSG_PREFIX)"update "
|
||||||
|
MSG_INSTALL := $(MSG_PREFIX)"install "
|
||||||
|
MSG_GENERATE := $(MSG_PREFIX)"generate "
|
||||||
|
MSG_EXTRACT := $(MSG_PREFIX)"extract "
|
||||||
|
|
||||||
|
#
|
||||||
|
# Assertion for the presence of a LICENSE and VERSION declarations in the port
|
||||||
|
# description
|
||||||
|
#
|
||||||
|
ifeq ($(LICENSE),)
|
||||||
|
default: license_undefined
|
||||||
|
license_undefined:
|
||||||
|
@$(ECHO) "Error: License undefined"; false
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(VERSION),)
|
||||||
|
default: version_undefined
|
||||||
|
version_undefined:
|
||||||
|
@$(ECHO) "Error: Version undefined"; false
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
_PATCHES_IN_REP_DIR := $(foreach P,$(PATCHES),$(wildcard $(REP_DIR)/$(P)))
|
||||||
|
|
||||||
|
_DST_HASH_FILE := $(notdir $(PORT:.port=)).hash
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Default rule that triggers the actual preparation steps
|
||||||
|
#
|
||||||
|
default: $(DOWNLOADS) _patch $(_DST_HASH_FILE) _dirs
|
||||||
|
|
||||||
|
_dirs: $(DOWNLOADS)
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Generate the HASH file
|
||||||
|
##
|
||||||
|
|
||||||
|
# The hash depends on the content of the port description file and the
|
||||||
|
# patches originating from REP_DIR. Patches that are downloaded are already
|
||||||
|
# captured by the hash sums of the downloaded files, which are declared in the
|
||||||
|
# port description file.
|
||||||
|
#
|
||||||
|
# During development when the files of MAKEFILE_LIST often change, the
|
||||||
|
# keeping all port hashes up to date is an inconvenience. By setting
|
||||||
|
# STRICT_HASH to 'no', the MAKEFILE_LIST can be exluded.
|
||||||
|
#
|
||||||
|
|
||||||
|
HASH_INPUT += $(_PATCHES_IN_REP_DIR) $(PORT)
|
||||||
|
ifneq ($(STRICT_HASH),no)
|
||||||
|
HASH_INPUT += $(MAKEFILE_LIST)
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(_DST_HASH_FILE): $(HASH_INPUT) $(MAKEFILE_LIST)
|
||||||
|
@$(MSG_GENERATE)$(notdir $@)
|
||||||
|
$(VERBOSE)cat $(HASH_INPUT) | $(HASHSUM) | sed "s/ .*//" > $@
|
||||||
|
|
||||||
|
_check_hash: $(_DST_HASH_FILE)
|
||||||
|
ifneq ($(CHECK_HASH),no)
|
||||||
|
$(VERBOSE)diff $< $(HASH_FILE) > /dev/null ||\
|
||||||
|
($(ECHO) "Error: $(_REL_HASH_FILE) is out of date, expected" `cat $<` ""; false)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Apply patches
|
||||||
|
##
|
||||||
|
|
||||||
|
# default arguments for the patch command
|
||||||
|
PATCH_OPT ?= -p0
|
||||||
|
|
||||||
|
#
|
||||||
|
# Helper function to obtain options for applying a patch
|
||||||
|
#
|
||||||
|
_patch_opt = $(call _prefer,$(PATCH_OPT($1)),$(PATCH_OPT))
|
||||||
|
|
||||||
|
#
|
||||||
|
# Helper function to look up the input file for a patch
|
||||||
|
#
|
||||||
|
_patch_input = $(wildcard $1 $(REP_DIR)/$1)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Rules for applying patches
|
||||||
|
#
|
||||||
|
# The 'patch' rule is a phony rule that is used as default rule. It triggers
|
||||||
|
# all other steps such as downloading and hash-sum checks. For each patch, there
|
||||||
|
# dependency to a phony rule.
|
||||||
|
#
|
||||||
|
_PATCH_TARGETS := $(addprefix phony/patches/,$(PATCHES))
|
||||||
|
|
||||||
|
_patch: $(_PATCH_TARGETS)
|
||||||
|
|
||||||
|
$(_PATCH_TARGETS): $(DOWNLOADS)
|
||||||
|
|
||||||
|
phony/patches/%:
|
||||||
|
@$(MSG_APPLY)$*
|
||||||
|
$(VERBOSE)test -f $(firstword $(call _patch_input,$*) fail) ||\
|
||||||
|
($(ECHO) "Error: Could not find patch $*"; false)
|
||||||
|
$(VERBOSE)for i in $(call _patch_input,$*); do\
|
||||||
|
patch -s $(call _patch_opt,$*) < $$i; done
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Assemble custom directory structures within the port directory
|
||||||
|
##
|
||||||
|
|
||||||
|
_DIR_TARGETS := $(addprefix phony/dirs/,$(DIRS))
|
||||||
|
|
||||||
|
_dirs: $(_DIR_TARGETS)
|
||||||
|
|
||||||
|
$(_DIR_TARGETS): _patch
|
||||||
|
|
||||||
|
_dir_content = $(call _assert,$(DIR_CONTENT($1)), \
|
||||||
|
Missing declaration of DIR_CONTENT($1))
|
||||||
|
|
||||||
|
phony/dirs/%:
|
||||||
|
@$(MSG_INSTALL)$*
|
||||||
|
$(VERBOSE)mkdir -p $*
|
||||||
|
$(VERBOSE)cp -Lrf $(call _dir_content,$*) $*
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Obtain source codes from a Git repository
|
||||||
|
##
|
||||||
|
|
||||||
|
_git_dir = $(call _assert,$(DIR($1)),Missing declaration of DIR($*))
|
||||||
|
|
||||||
|
%.git:
|
||||||
|
$(VERBOSE)test -n "$(REV($*))" ||\
|
||||||
|
($(ECHO) "Error: Undefined revision for $*"; false);
|
||||||
|
$(VERBOSE)test -n "$(URL($*))" ||\
|
||||||
|
($(ECHO) "Error: Undefined URL for $*"; false);
|
||||||
|
$(VERBOSE)dir=$(call _git_dir,$*);\
|
||||||
|
test -d $$dir || $(MSG_DOWNLOAD)$(URL($*)); \
|
||||||
|
test -d $$dir || git clone $(URL($*)) $$dir; \
|
||||||
|
$(MSG_UPDATE)$$dir; \
|
||||||
|
cd $$dir && git fetch && git reset -q --hard HEAD && git checkout -q $(REV($*))
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Obtain source codes from Subversion repository
|
||||||
|
##
|
||||||
|
|
||||||
|
_svn_dir = $(call _assert,$(DIR($1)),Missing declaration of DIR($*))
|
||||||
|
|
||||||
|
%.svn:
|
||||||
|
$(VERBOSE)test -n "$(REV($*))" ||\
|
||||||
|
($(ECHO) "Error: Undefined revision for $*"; false);
|
||||||
|
$(VERBOSE)test -n "$(URL($*))" ||\
|
||||||
|
($(ECHO) "Error: Undefined URL for $*"; false);
|
||||||
|
$(VERBOSE)dir=$(call _svn_dir,$*);\
|
||||||
|
rm -rf $$dir; \
|
||||||
|
$(MSG_DOWNLOAD)$(URL($*)); \
|
||||||
|
svn export -q $(URL($*))@$(REV($*)) $$dir;
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Download a plain file
|
||||||
|
##
|
||||||
|
|
||||||
|
_file_name = $(call _prefer,$(NAME($1)),$(notdir $(URL($1))))
|
||||||
|
|
||||||
|
%.file:
|
||||||
|
$(VERBOSE)test -n "$(URL($*))" ||\
|
||||||
|
($(ECHO) "Error: Undefined URL for $(call _file_name,$*)"; false);
|
||||||
|
$(VERBOSE)name=$(call _file_name,$*);\
|
||||||
|
(test -f $$name || $(MSG_DOWNLOAD)$(URL($*))); \
|
||||||
|
(test -f $$name || wget --quiet $(URL($*)) -O $$name);
|
||||||
|
$(VERBOSE)\
|
||||||
|
($(ECHO) "$(SHA($*)) $(call _file_name,$*)" |\
|
||||||
|
$(HASHSUM) -c > /dev/null 2> /dev/null) || \
|
||||||
|
($(ECHO) Error: Hash sum check for $* failed; false)
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Download and unpack an archive
|
||||||
|
##
|
||||||
|
|
||||||
|
_archive_name = $(call _prefer,$(NAME($1)),$(notdir $(URL($1))))
|
||||||
|
_archive_dir = $(call _assert,$(DIR($1)),Missing definition of DIR($*) in $(PORT))
|
||||||
|
|
||||||
|
_tar_opt = $(call _prefer,$(TAR_OPT($1)),--strip-components=1)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Archive extraction functions for various archive types
|
||||||
|
#
|
||||||
|
_extract_function(tgz) = tar xfz $(ARCHIVE) -C $(DIR) $(call _tar_opt,$1)
|
||||||
|
_extract_function(tar.gz) = tar xfz $(ARCHIVE) -C $(DIR) $(call _tar_opt,$1)
|
||||||
|
_extract_function(tar.xz) = tar xfJ $(ARCHIVE) -C $(DIR) $(call _tar_opt,$1)
|
||||||
|
_extract_function(tar.bz2) = tar xfj $(ARCHIVE) -C $(DIR) $(call _tar_opt,$1)
|
||||||
|
_extract_function(zip) = unzip -o -q -d $(DIR) $(ARCHIVE)
|
||||||
|
|
||||||
|
_ARCHIVE_EXTS := tar.gz tar.xz tgz tar.bz2 zip
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that returns the matching extraction function for a given archive
|
||||||
|
#
|
||||||
|
# Because this function refers to the 'ARCHIVE' variable, it is only supposed
|
||||||
|
# to work from the scope of the %.archive rule.
|
||||||
|
#
|
||||||
|
_extract_function = $(call _assert,\
|
||||||
|
$(foreach E,$(_ARCHIVE_EXTS),\
|
||||||
|
$(if $(filter %.$E,$(ARCHIVE)),\
|
||||||
|
$(_extract_function($E)),)),\
|
||||||
|
Don't know how to extract $(ARCHIVE))
|
||||||
|
|
||||||
|
%.archive: ARCHIVE = $(call _archive_name,$*)
|
||||||
|
%.archive: DIR = $(call _archive_dir,$*)
|
||||||
|
|
||||||
|
%.archive: %.file
|
||||||
|
@$(MSG_EXTRACT)$(ARCHIVE)
|
||||||
|
$(VERBOSE)\
|
||||||
|
mkdir -p $(DIR);\
|
||||||
|
$(call _extract_function,$*)
|
||||||
|
|
133
tool/ports/prepare_port
Executable file
133
tool/ports/prepare_port
Executable file
@ -0,0 +1,133 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
|
||||||
|
#
|
||||||
|
# \brief Tool for downloading and patching 3rd-party source code
|
||||||
|
# \author Norman Feske
|
||||||
|
# \date 2014-05-07
|
||||||
|
#
|
||||||
|
|
||||||
|
VERBOSE ?= @
|
||||||
|
ECHO := echo -e
|
||||||
|
|
||||||
|
#
|
||||||
|
# Always execute the $(TARGET) rule regardless of the supplied command-line
|
||||||
|
# argument
|
||||||
|
#
|
||||||
|
TARGET := $(MAKECMDGOALS) default
|
||||||
|
$(MAKECMDGOALS) default:
|
||||||
|
|
||||||
|
# the single argument is the name of the port to prepare
|
||||||
|
ARGUMENT := $(MAKECMDGOALS)
|
||||||
|
PORT_NAME := $(firstword $(ARGUMENT))
|
||||||
|
|
||||||
|
#
|
||||||
|
# Determine Genode base directory based on the known location of the
|
||||||
|
# 'create_builddir' tool within the Genode source tree
|
||||||
|
#
|
||||||
|
GENODE_DIR ?= $(realpath $(dir $(MAKEFILE_LIST))/../..)
|
||||||
|
|
||||||
|
# compound directory where all 3rd-party source codes are installed
|
||||||
|
CONTRIB_DIR ?= $(GENODE_DIR)/contrib
|
||||||
|
|
||||||
|
# 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 ports of 3rd-party source code
|
||||||
|
_REP_PORTS_DIRS := $(wildcard $(addsuffix /ports,$(REPOSITORIES)))
|
||||||
|
|
||||||
|
# list of all available ports
|
||||||
|
_PORTS := $(foreach DIR,$(_REP_PORTS_DIRS),$(wildcard $(DIR)/*.port))
|
||||||
|
|
||||||
|
# port file to use
|
||||||
|
PORT := $(filter %/$(PORT_NAME).port,$(_PORTS))
|
||||||
|
|
||||||
|
# repository that contains the port description, used to look up patch files
|
||||||
|
REP_DIR := $(realpath $(dir $(PORT))/..)
|
||||||
|
|
||||||
|
# read hash that uniquely identifies the version to install
|
||||||
|
HASH_FILE := $(wildcard $(PORT:.port=.hash))
|
||||||
|
HASH := $(if $(HASH_FILE),$(shell cat $(HASH_FILE)),)
|
||||||
|
|
||||||
|
# path to hash file relative to '<genode-dir>/repos', used for error messages
|
||||||
|
_REL_HASH_FILE := $(notdir $(REP_DIR))/ports/$(notdir $(PORT))
|
||||||
|
|
||||||
|
# directory where to install the port
|
||||||
|
PORT_DIR := $(CONTRIB_DIR)/$(PORT_NAME)-$(HASH)
|
||||||
|
|
||||||
|
# path to hash file generated during installation
|
||||||
|
PORT_HASH_FILE := $(PORT_DIR)/$(PORT_NAME).hash
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check validity of user input
|
||||||
|
#
|
||||||
|
ifeq ($(ARGUMENT),)
|
||||||
|
$(TARGET): missing_argument
|
||||||
|
missing_argument: usage
|
||||||
|
@$(ECHO) "Error: Missing port name as argument"; false
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(words $(ARGUMENT)),1)
|
||||||
|
$(TARGET): too_many_arguments
|
||||||
|
too_many_arguments: usage
|
||||||
|
@$(ECHO) "Error: Too many arguments specified, expecting one argument"; false
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(PORT),)
|
||||||
|
$(TARGET): nonexisting_port
|
||||||
|
nonexisting_port:
|
||||||
|
@$(ECHO) "Error: Port $(PORT_NAME) does not exist"; false
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(HASH),)
|
||||||
|
$(TARGET): nonexisting_hash
|
||||||
|
nonexisting_hash:
|
||||||
|
@$(ECHO) "Error: Port $(PORT_NAME) lacks a valid hash"; false
|
||||||
|
endif
|
||||||
|
|
||||||
|
usage:
|
||||||
|
@$(ECHO)
|
||||||
|
@$(ECHO) "--- download and patch 3rd-party source code ---"
|
||||||
|
@$(ECHO) "usage: prepare_port <port-name> [CHECK_HASH=no]"
|
||||||
|
@$(ECHO)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Default rule that triggers the actual preparation steps
|
||||||
|
#
|
||||||
|
$(TARGET): _check_integrity
|
||||||
|
|
||||||
|
_check_integrity : _install_in_port_dir
|
||||||
|
ifneq ($(CHECK_HASH),no)
|
||||||
|
$(VERBOSE)diff $(PORT_HASH_FILE) $(HASH_FILE) > /dev/null ||\
|
||||||
|
($(ECHO) "Error: $(_REL_HASH_FILE) is out of date, expected" `cat $(PORT_HASH_FILE)` ""; false)
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# During the preparatio steps, the port directory is renamed. We use the suffix
|
||||||
|
# ".incomplete" to mark this transient state of the port directory.
|
||||||
|
#
|
||||||
|
_install_in_port_dir: $(PORT_DIR)
|
||||||
|
@#\
|
||||||
|
# if the transient directory already exists, reuse it as it may contain\
|
||||||
|
# finished steps such as downloads. By reusing it, we avoid downloading\
|
||||||
|
# the same files again and again while working on a port. However, in this\
|
||||||
|
# case, we already have created an empty port directory via the $(PORT_DIR)\
|
||||||
|
# rule below. To avoid having both the port directory and the transient\
|
||||||
|
# port directory present, remove the just-created port directory.\
|
||||||
|
#
|
||||||
|
$(VERBOSE)(test -d $(PORT_DIR).incomplete && rmdir $(PORT_DIR)) || true
|
||||||
|
@#\
|
||||||
|
# If no transient directory exists, rename the port directory accordingly.\
|
||||||
|
#
|
||||||
|
$(VERBOSE)test -d $(PORT_DIR).incomplete || mv --force $(PORT_DIR) $(PORT_DIR).incomplete
|
||||||
|
$(VERBOSE)$(MAKE) --no-print-directory \
|
||||||
|
-f $(GENODE_DIR)/tool/ports/mk/install.mk \
|
||||||
|
-C $(PORT_DIR).incomplete \
|
||||||
|
PORT=$(PORT) VERBOSE=$(VERBOSE)
|
||||||
|
@#\
|
||||||
|
# The preparation finished successfully. So we can rename the transient\
|
||||||
|
# directory to the real one.\
|
||||||
|
#
|
||||||
|
$(VERBOSE)mv $(PORT_DIR).incomplete $(PORT_DIR)
|
||||||
|
|
||||||
|
$(PORT_DIR):
|
||||||
|
$(VERBOSE)mkdir -p $@
|
Loading…
x
Reference in New Issue
Block a user