#!/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 '/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 '/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 [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 $@