blob: 95d1063fc2b72ac4bb119427d7e9e3162ff56a1c [file] [log] [blame]
################################################################################
# Generic package infrastructure
#
# This file implements an infrastructure that eases development of
# package .mk files. It should be used for all non-autotools based
# packages. Autotools-based packages should use the specialized
# autotools infrastructure in package/Makefile.autotools.in.
#
# See the Buildroot documentation for details on the usage of this
# infrastructure
#
# In terms of implementation, this generic infrastructure requires the
# .mk file to specify:
#
# 1. Metadata informations about the package: name, version,
# download URL, etc.
#
# 2. Description of the commands to be executed to configure, build
# and install the package
#
# The autotools infrastructure specializes this generic infrastructure
# by already implementing the configure, build and install steps.
################################################################################
# UPPERCASE Macro -- transform its argument to uppercase and replace dots and
# hyphens to underscores
# Heavily inspired by the up macro from gmsl (http://gmsl.sf.net)
# This is approx 5 times faster than forking a shell and tr, and
# as this macro is used a lot it matters
# This works by creating translation character pairs (E.G. a:A b:B)
# and then looping though all of them running $(subst from,to,text)
[FROM] := 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 . -
[TO] := 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 _ _
UPPERCASE = $(strip $(eval __tmp := $1) \
$(foreach c, $(join $(addsuffix :,$([FROM])),$([TO])), \
$(eval __tmp := \
$(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)),\
$(__tmp)))) \
$(__tmp))
define KCONFIG_ENABLE_OPT
$(SED) "/\\<$(1)\\>/d" $(2)
echo "$(1)=y" >> $(2)
endef
define KCONFIG_SET_OPT
$(SED) "/\\<$(1)\\>/d" $(3)
echo "$(1)=$(2)" >> $(3)
endef
define KCONFIG_DISABLE_OPT
$(SED) "/\\<$(1)\\>/d" $(2)
echo "# $(1) is not set" >> $(2)
endef
# Helper functions to determine the name of a package and its
# directory from its makefile directory, using the $(MAKEFILE_LIST)
# variable provided by make. This is used by the *TARGETS macros to
# automagically find where the package is located. Note that the
# pkgdir macro is carefully written to handle the case of the Linux
# package, for which the package directory is an empty string.
define pkgdir
$(dir $(lastword $(MAKEFILE_LIST)))
endef
define pkgname
$(lastword $(subst /, ,$(call pkgdir)))
endef
define pkgparentdir
$(patsubst %$(call pkgname)/,%,$(call pkgdir))
endef
# Define extractors for different archive suffixes
INFLATE.bz2 = $(BZCAT)
INFLATE.gz = $(ZCAT)
INFLATE.tbz = $(BZCAT)
INFLATE.tbz2 = $(BZCAT)
INFLATE.tgz = $(ZCAT)
INFLATE.xz = $(XZCAT)
INFLATE.tar = cat
# MESSAGE Macro -- display a message in bold type
MESSAGE = echo "$(TERM_BOLD)>>> $($(PKG)_NAME) $($(PKG)_VERSION) $(1)$(TERM_RESET)"
MESSAGE_NOPKG = echo "$(TERM_BOLD)>>> $(1)$(TERM_RESET)"
TERM_BOLD := $(shell tput smso)
TERM_RESET := $(shell tput rmso)
BASH_HEADER = echo "$(TERM_BOLD)>>> $$($(2)_NAME) $$($(2)_VERSION) buildbash$(TERM_RESET)"
# Download method commands
WGET:=$(call qstrip,$(BR2_WGET)) $(QUIET)
SVN:=$(call qstrip,$(BR2_SVN))
BZR:=$(call qstrip,$(BR2_BZR))
GIT:=$(call qstrip,$(BR2_GIT))
HG:=$(call qstrip,$(BR2_HG)) $(QUIET)
SCP:=$(call qstrip,$(BR2_SCP)) $(QUIET)
SSH:=$(call qstrip,$(BR2_SSH)) $(QUIET)
MPM:=$(call qstrip,$(BR2_MPM)) $(QUIET)
GCLIENT:=$(call qstrip,$(BR2_GCLIENT))
LOCALFILES:=$(call qstrip,$(BR2_LOCALFILES))
# Default spider mode is 'DOWNLOAD'. Other possible values are 'SOURCE_CHECK'
# used by the _source-check target and 'SHOW_EXTERNAL_DEPS', used by the
# external-deps target.
DL_MODE=DOWNLOAD
DL_DIR=$(call qstrip,$(BR2_DL_DIR))
ifeq ($(DL_DIR),)
DL_DIR:=$(TOPDIR)/dl
endif
################################################################################
# BUILD_AFTER_BUSYBOX: make the given target build only *after* busybox-like
# packages. That ensures the given target will install on top of busybox
# (and overwrite the builtin tool with a better one) instead of the other
# way around.
#
# Argument 1 is the name of the package that depends on busybox
################################################################################
define _BUILD_AFTER_BUSYBOX
ifeq ($(BR2_PACKAGE_TOOLBOX),y)
$(call UPPERCASE,$(1))_DEPENDENCIES += toolbox
endif
ifeq ($(BR2_PACKAGE_TOYBOX),y)
$(call UPPERCASE,$(1))_DEPENDENCIES += toybox
endif
ifeq ($(BR2_PACKAGE_BUSYBOX),y)
$(call UPPERCASE,$(1))_DEPENDENCIES += busybox
endif
endef
define BUILD_AFTER_BUSYBOX
$(eval $(call _BUILD_AFTER_BUSYBOX,$(1)))
endef
#
# URI scheme helper functions
# Example URIs:
# * http://www.example.com/dir/file
# * scp://www.example.com:dir/file (with domainseparator :)
#
# geturischeme: http
geturischeme=$(firstword $(subst ://, ,$(call qstrip,$(1))))
# stripurischeme: www.example.com/dir/file
stripurischeme=$(lastword $(subst ://, ,$(call qstrip,$(1))))
# domain: www.example.com
domain=$(firstword $(subst $(call domainseparator,$(2)), ,$(call stripurischeme,$(1))))
# notdomain: dir/file
notdomain=$(patsubst $(call domain,$(1),$(2))$(call domainseparator,$(2))%,%,$(call stripurischeme,$(1)))
#
# default domainseparator is /, specify alternative value as first argument
domainseparator=$(if $(1),$(1),/)
################################################################################
# The DOWNLOAD_{GIT,SVN,BZR,HG,LOCALFILES} helpers are in charge of getting a
# working copy of the source repository for their corresponding SCM,
# checking out the requested version / commit / tag, and create an
# archive out of it. DOWNLOAD_SCP uses scp to obtain a remote file with
# ssh authentication. DOWNLOAD_WGET is the normal wget-based download
# mechanism.
#
# The SOURCE_CHECK_{GIT,SVN,BZR,HG,WGET,LOCALFILES,SCP} helpers are in charge of
# simply checking that the source is available for download. This can be used
# to make sure one will be able to get all the sources needed for
# one's build configuration.
#
# The SHOW_EXTERNAL_DEPS_{GIT,SVN,BZR,HG,WGET,LOCALFILES,SCP} helpers simply
# output to the console the names of the files that will be downloaded, or path
# and revision of the source repositories, producing a list of all the
# "external dependencies" of a given build configuration.
################################################################################
define DOWNLOAD_REPO
if [ -d $(BUILD_DIR)/$($(PKG)_BASE_NAME)/.git ]; then \
(cd $(BUILD_DIR)/$($(PKG)_BASE_NAME) && $(GIT) reset --hard) \
else \
(cd $(BUILD_DIR) && \
rm -rf $($(PKG)_BASE_NAME) && \
cd $(TOPDIR)/../$($(PKG)_REPO_PATH) && \
git worktree prune && \
git worktree add -f --detach $(BUILD_DIR)/$($(PKG)_BASE_NAME) \
"$$(git rev-parse --abbrev-ref HEAD)"; \
) \
fi
endef
define SOURCE_CHECK_REPO
echo "unimplemented"
endef
define SHOW_EXTERNAL_DEPS_REPO
echo $($(PKG)_SITE)
endef
define DOWNLOAD_RREPO
${DOWNLOAD_REPO} ;\
for dir in $$(find $(TOPDIR)/../$($(PKG)_REPO_PATH) -mindepth 2 -name .git -type d) ; do \
repo_dir=$$(echo $${dir} | sed 's:$(TOPDIR)/../:$(TOPDIR)/../.repo/projects/:g' | sed 's:/.git$$:.git:'); \
target_dir=$($(PKG)_BASE_NAME)/$$(echo $${dir} | sed 's:$(TOPDIR)/../$($(PKG)_REPO_PATH)/::g' | sed 's:/.git$$::'); \
if [ -d $(BUILD_DIR)/$${target_dir}/.git ]; then \
(cd $(BUILD_DIR)/$${target_dir} && $(GIT) reset --hard) ; \
else \
(cd $(BUILD_DIR) && \
if [ "$($(PKG)_DL_VERSION)" == "HEAD" ]; then \
DL_VERSION="$$($(GIT) --git-dir=$${dir} show-ref --head HEAD --hash)"; \
DL_BRANCH="$$($(GIT) --git-dir=$${dir} symbolic-ref HEAD 2>/dev/null)"; \
[ -n "$$DL_BRANCH" ] && DL_VERSION="$${DL_BRANCH#refs/heads/}"; \
else \
DL_VERSION=$($(PKG)_DL_VERSION); \
fi; \
rm -rf $${target_dir}.tmp/ && \
sh /usr/share/doc/git/contrib/workdir/git-new-workdir \
$${repo_dir} \
$${target_dir}.tmp/ $$DL_VERSION && \
mkdir -p $${target_dir}/ && \
rsync -a $${target_dir}.tmp/ $${target_dir}/ && \
rm -rf $${target_dir}.tmp/ \
) ; \
fi ; \
done
endef
define SOURCE_CHECK_RREPO
echo "unimplemented"
endef
define SHOW_EXTERNAL_DEPS_RREPO
echo $($(PKG)_SITE)
endef
define DOWNLOAD_GIT
test -e $(DL_DIR)/$($(PKG)_SOURCE) || \
(pushd $(DL_DIR) > /dev/null && \
$(GIT) clone --bare $($(PKG)_SITE) $($(PKG)_BASE_NAME) && \
pushd $($(PKG)_BASE_NAME) > /dev/null && \
$(GIT) archive --format=tar --prefix=$($(PKG)_BASE_NAME)/ $($(PKG)_DL_VERSION) | \
gzip -c > $(DL_DIR)/$($(PKG)_SOURCE) && \
popd > /dev/null && \
rm -rf $($(PKG)_DL_DIR) && \
popd > /dev/null)
endef
# TODO: improve to check that the given PKG_DL_VERSION exists on the remote
# repository
define SOURCE_CHECK_GIT
$(GIT) ls-remote --heads $($(PKG)_SITE) > /dev/null
endef
define SHOW_EXTERNAL_DEPS_GIT
echo $($(PKG)_SOURCE)
endef
define DOWNLOAD_BZR
test -e $(DL_DIR)/$($(PKG)_SOURCE) || \
$(BZR) export $(DL_DIR)/$($(PKG)_SOURCE) $($(PKG)_SITE) -r $($(PKG)_DL_VERSION)
endef
define SOURCE_CHECK_BZR
$(BZR) ls --quiet $($(PKG)_SITE) > /dev/null
endef
define SHOW_EXTERNAL_DEPS_BZR
echo $($(PKG)_SOURCE)
endef
define DOWNLOAD_SVN
test -e $(DL_DIR)/$($(PKG)_SOURCE) || \
(pushd $(DL_DIR) > /dev/null && \
$(SVN) export -r $($(PKG)_DL_VERSION) $($(PKG)_SITE) $($(PKG)_DL_DIR) && \
$(TAR) czf $($(PKG)_SOURCE) $($(PKG)_BASE_NAME)/ && \
rm -rf $($(PKG)_DL_DIR) && \
popd > /dev/null)
endef
define SOURCE_CHECK_SVN
$(SVN) ls $($(PKG)_SITE) > /dev/null
endef
define SHOW_EXTERNAL_DEPS_SVN
echo $($(PKG)_SOURCE)
endef
# SCP URIs should be of the form scp://[user@]host:filepath
# Note that filepath is relative to the user's home directory, so you may want
# to prepend the path with a slash: scp://[user@]host:/absolutepath
define DOWNLOAD_SCP
test -e $(DL_DIR)/$(2) || \
$(SCP) $(call stripurischeme,$(call qstrip,$(1)))/$(2) $(DL_DIR)
endef
define SOURCE_CHECK_SCP
$(SSH) $(call domain,$(1),:) ls $(call notdomain,$(1)/$(2),:) > /dev/null
endef
define SHOW_EXTERNAL_DEPS_SCP
echo $(2)
endef
define DOWNLOAD_HG
test -e $(DL_DIR)/$($(PKG)_SOURCE) || \
(pushd $(DL_DIR) > /dev/null && \
$(HG) clone --noupdate --rev $($(PKG)_DL_VERSION) $($(PKG)_SITE) $($(PKG)_BASE_NAME) && \
$(HG) archive --repository $($(PKG)_BASE_NAME) --type tgz --prefix $($(PKG)_BASE_NAME)/ \
--rev $($(PKG)_DL_VERSION) $(DL_DIR)/$($(PKG)_SOURCE) && \
rm -rf $($(PKG)_DL_DIR) && \
popd > /dev/null)
endef
# TODO: improve to check that the given PKG_DL_VERSION exists on the remote
# repository
define SOURCE_CHECK_HG
$(HG) incoming --force -l1 $($(PKG)_SITE) > /dev/null
endef
define SHOW_EXTERNAL_DEPS_HG
echo $($(PKG)_SOURCE)
endef
define DOWNLOAD_MPM
test -e $(DL_DIR)/$($(PKG)_SOURCE) || \
(pushd $(DL_DIR) > /dev/null && \
$(MPM) fetch -a -v $($(PKG)_VERSION) $(call stripurischeme,$(call qstrip,$(1))) $($(PKG)_BASE_NAME) && \
$(TAR) chf $($(PKG)_SOURCE) $($(PKG)_BASE_NAME)/ && \
rm -rf $($(PKG)_BASE_NAME) $($(PKG)_BASE_NAME).mpm && \
popd > /dev/null)
endef
define SOURCE_CHECK_MPM
$(MPM) packageinfo -b $($(PKG)_VERSION) $(call stripurischeme,$(call qstrip,$(1)))
endef
define SHOW_EXTERNAL_DEPS_MPM
echo $(2)
endef
define DOWNLOAD_WGET
if ! test -e $(DL_DIR)/$(2); then \
if test -n "$(BUILDROOT_DL_NEVER)"; then \
echo "Downloads disabled, skipping download of $(2)"; \
exit 1; \
fi && \
$(WGET) -P $(DL_DIR) $(call qstrip,$(1))/$(2); \
fi
endef
define SOURCE_CHECK_WGET
$(WGET) --spider $(call qstrip,$(1))/$(2)
endef
define SHOW_EXTERNAL_DEPS_WGET
echo $(2)
endef
define DOWNLOAD_LOCALFILES
test -e $(DL_DIR)/$($(PKG)_SOURCE) || \
$(LOCALFILES) $(call qstrip,$(subst file://,,$($(PKG)_SITE)))/$($(PKG)_SOURCE) $(DL_DIR)
endef
define SOURCE_CHECK_LOCALFILES
test -e $(call qstrip,$(subst file://,,$($(PKG)_SITE)))/$($(PKG)_SOURCE)
endef
define SHOW_EXTERNAL_DEPS_LOCALFILES
echo $($(PKG)_SITE)/$($(PKG)_SOURCE)
endef
define DOWNLOAD_GCLIENT
test -e $(DL_DIR)/$($(PKG)_SOURCE) || \
(pushd $(DL_DIR) > /dev/null && \
mkdir -p $($(PKG)_BASE_NAME) && \
pushd $($(PKG)_DL_DIR) > /dev/null && \
$(GCLIENT) config $($(PKG)_SITE) && \
$(GCLIENT) sync -r $($(PKG)_DL_VERSION) -t && \
rm -rf .gclient .gclient_entries && \
find . -name '.svn' -print0 | xargs -0 sh -c 'for i in "$$@" ; do test -e "$$i" && rm -rf "$$i" ; done' _ && \
find . -name '.git' -print0 | xargs -0 sh -c 'for i in "$$@" ; do test -e "$$i" && rm -rf "$$i" ; done' _ && \
popd > /dev/null && \
$(TAR) czf $($(PKG)_SOURCE) $($(PKG)_BASE_NAME)/ && \
rm -rf $($(PKG)_DL_DIR) && \
popd > /dev/null)
endef
define SOURCE_CHECK_GCLIENT
$(SVN) ls $($(PKG)_SITE) > /dev/null || \
$(GIT) ls-remote --heads $($(PKG)_SITE) > /dev/null
endef
define SHOW_EXTERNAL_DEPS_GCLIENT
echo $($(PKG)_SOURCE)
endef
################################################################################
# DOWNLOAD -- Download helper. Will try to download source from:
# 1) BR2_PRIMARY_SITE if enabled
# 2) Download site
# 3) BR2_BACKUP_SITE if enabled
#
# Argument 1 is the source location
# Argument 2 is the source filename
#
# E.G. use like this:
# $(call DOWNLOAD,$(FOO_SITE),$(FOO_SOURCE))
################################################################################
define DOWNLOAD
if test -n "$(call qstrip,$(BR2_PRIMARY_SITE))" ; then \
case "$(call geturischeme,$(BR2_PRIMARY_SITE))" in \
scp) $(call $(DL_MODE)_SCP,$(BR2_PRIMARY_SITE),$(2)) && exit ;; \
*) $(call $(DL_MODE)_WGET,$(BR2_PRIMARY_SITE),$(2)) && exit ;; \
esac ; \
fi ; \
if test -n "$(1)" ; then \
case "$($(PKG)_SITE_METHOD)" in \
git) $($(DL_MODE)_GIT) && exit ;; \
svn) $($(DL_MODE)_SVN) && exit ;; \
bzr) $($(DL_MODE)_BZR) && exit ;; \
file) $($(DL_MODE)_LOCALFILES) && exit ;; \
scp) $($(DL_MODE)_SCP) && exit ;; \
hg) $($(DL_MODE)_HG) && exit ;; \
repo) $($(DL_MODE)_REPO) && exit ;; \
rrepo) $($(DL_MODE)_RREPO) && exit ;; \
mpm) $($(DL_MODE)_MPM) && exit ;; \
gclient) $($(DL_MODE)_GCLIENT) && exit ;; \
null) exit ;; \
*) $(call $(DL_MODE)_WGET,$(1),$(2)) && exit ;; \
esac ; \
fi ; \
if test -n "$(call qstrip,$(BR2_BACKUP_SITE))" ; then \
$(call $(DL_MODE)_WGET,$(BR2_BACKUP_SITE),$(2)) && exit ; \
fi ; \
exit 1
endef
# Needed for the foreach loops to loop over the list of hooks, so that
# each hook call is properly separated by a newline.
define sep
endef
################################################################################
# Implicit targets -- produce a stamp file for each step of a package build
################################################################################
# Retrieve the archive
$(BUILD_DIR)/%/.stamp_downloaded:
ifeq ($(DL_MODE),DOWNLOAD)
# Only show the download message if it isn't already downloaded
$(Q)(test -e $(DL_DIR)/$($(PKG)_SOURCE) && \
(test -z $($(PKG)_PATCH) || test -e $(DL_DIR)$($(PKG)_PATCH))) || \
$(call MESSAGE,"Downloading")
endif
$(if $($(PKG)_SOURCE),$(call DOWNLOAD,$($(PKG)_SITE),$($(PKG)_SOURCE)))
$(if $($(PKG)_PATCH),$(call DOWNLOAD,$($(PKG)_SITE),$($(PKG)_PATCH)))
$(foreach hook,$($(PKG)_POST_DOWNLOAD_HOOKS),$(call $(hook))$(sep))
ifeq ($(DL_MODE),DOWNLOAD)
$(Q)mkdir -p $(@D)
$(Q)touch $@
endif
# Unpack the archive
$(BUILD_DIR)/%/.stamp_extracted:
@$(call MESSAGE,"Extracting")
$(Q)mkdir -p $(@D)
$(Q)$($(PKG)_EXTRACT_CMDS)
# some packages have messed up permissions inside
$(Q)chmod -R +rw $(@D)
$(foreach hook,$($(PKG)_POST_EXTRACT_HOOKS),$(call $(hook))$(sep))
$(Q)touch $@
# Rsync the source directory if the <pkg>_OVERRIDE_SRCDIR feature is
# used.
$(BUILD_DIR)/%/.stamp_rsynced:
@$(call MESSAGE,"Syncing from source dir $(SRCDIR)")
@test -d $(SRCDIR) || (echo "ERROR: $(SRCDIR) does not exist" ; exit 1)
rsync -au $(SRCDIR)/ $(@D)
$(Q)touch $@
# Handle the SOURCE_CHECK and SHOW_EXTERNAL_DEPS cases for rsynced
# packages
$(BUILD_DIR)/%/.stamp_rsync_sourced:
ifeq ($(DL_MODE),SOURCE_CHECK)
test -d $(SRCDIR)
else ifeq ($(DL_MODE),SHOW_EXTERNAL_DEPS)
echo "file://$(SRCDIR)"
else
@true # Nothing to do to source a local package
endif
# Patch
#
# The RAWNAME variable is the lowercased package name, which allows to
# find the package directory (typically package/<pkgname>) and the
# prefix of the patches
$(BUILD_DIR)/%/.stamp_patched: NAMEVER = $(RAWNAME)-$($(PKG)_VERSION)
$(BUILD_DIR)/%/.stamp_patched:
@$(call MESSAGE,"Patching $($(PKG)_DIR_PREFIX)/$(RAWNAME)")
$(foreach hook,$($(PKG)_PRE_PATCH_HOOKS),$(call $(hook))$(sep))
$(if $($(PKG)_PATCH),$(Q)support/scripts/apply-patches.sh $(@D) $(DL_DIR) $($(PKG)_PATCH))
$(Q)( \
if test -d $($(PKG)_DIR_PREFIX)/$(RAWNAME); then \
if test "$(wildcard $($(PKG)_DIR_PREFIX)/$(RAWNAME)/$(NAMEVER)*.patch*)"; then \
support/scripts/apply-patches.sh $(@D) $($(PKG)_DIR_PREFIX)/$(RAWNAME) $(NAMEVER)\*.patch $(NAMEVER)\*.patch.$(ARCH) $(NAMEVER)\*.patch.$(BR2_TARGET_GENERIC_PLATFORM_NAME) || exit 1; \
else \
support/scripts/apply-patches.sh $(@D) $($(PKG)_DIR_PREFIX)/$(RAWNAME) $(RAWNAME)\*.patch $(RAWNAME)\*.patch.$(ARCH) || exit 1; \
if test -d $($(PKG)_DIR_PREFIX)/$(RAWNAME)/$(NAMEVER); then \
support/scripts/apply-patches.sh $(@D) $($(PKG)_DIR_PREFIX)/$(RAWNAME)/$(NAMEVER) \*.patch \*.patch.$(ARCH) || exit 1; \
fi; \
fi; \
fi; \
)
$(foreach hook,$($(PKG)_POST_PATCH_HOOKS),$(call $(hook))$(sep))
$(Q)touch $@
# Configure
$(BUILD_DIR)/%/.stamp_configured:
$(foreach hook,$($(PKG)_PRE_CONFIGURE_HOOKS),$(call $(hook))$(sep))
@$(call MESSAGE,"Configuring")
+$(Q)$($(PKG)_CONFIGURE_CMDS)
$(foreach hook,$($(PKG)_POST_CONFIGURE_HOOKS),$(call $(hook))$(sep))
$(Q)touch $@
# Build
$(BUILD_DIR)/%/.stamp_built::
@$(call MESSAGE,"Building")
+$(Q)$($(PKG)_BUILD_CMDS)
$(foreach hook,$($(PKG)_POST_BUILD_HOOKS),$(call $(hook))$(sep))
$(Q)touch $@
# Test
$(BUILD_DIR)/%/.stamp_tested::
@$(call MESSAGE,"Testing")
+$(Q)$($(PKG)_TEST_CMDS)
$(Q)touch $@
# Coverage
$(BUILD_DIR)/%/.stamp_coverage_done::
@$(call MESSAGE,"Generating code coverage information")
+$(Q)$($(PKG)_COVERAGE_CMDS)
$(Q)touch $@
# Install to host dir
$(BUILD_DIR)/%/.stamp_host_installed:
@$(call MESSAGE,"Installing to host directory")
+$(Q)$($(PKG)_INSTALL_CMDS)
$(foreach hook,$($(PKG)_POST_INSTALL_HOOKS),$(call $(hook))$(sep))
$(Q)touch $@
# Install to staging dir
$(BUILD_DIR)/%/.stamp_staging_installed:
@$(call MESSAGE,"Installing to staging directory")
+$(Q)$($(PKG)_INSTALL_STAGING_CMDS)
$(foreach hook,$($(PKG)_POST_INSTALL_STAGING_HOOKS),$(call $(hook))$(sep))
$(Q)touch $@
# Install to images dir
$(BUILD_DIR)/%/.stamp_images_installed:
@$(call MESSAGE,"Installing to images directory")
+$(Q)$($(PKG)_INSTALL_IMAGES_CMDS)
$(foreach hook,$($(PKG)_POST_INSTALL_IMAGES_HOOKS),$(call $(hook))$(sep))
$(Q)touch $@
# Install to target dir
$(BUILD_DIR)/%/.stamp_target_installed:
@$(call MESSAGE,"Installing to target")
+$(Q)$($(PKG)_INSTALL_TARGET_CMDS)
$(Q)(rcd="$($(PKG)_DIR_PREFIX)/$(RAWNAME)/rc"; \
ocd="$(STAGING_DIR)/etc/s6-rc/source"; \
for d in $$rcd/*; do \
mkdir -p "$$ocd" && \
if test -d "$$d"; then \
rm -rf "$$ocd/$$(basename "$$d")"; \
cp -alf "$$d" "$$ocd/"; \
fi; \
done \
)
$(foreach hook,$($(PKG)_POST_INSTALL_TARGET_HOOKS),$(call $(hook))$(sep))
$(Q)touch $@
# Install to all appropriate destinations.
# (dependencies are specified elsewhere)
$(STAMP_DIR)/%:
@$(call MESSAGE_NOPKG,"Stamping $@")
$(Q)touch $@
# For packages that don't use GENTARGETS
%-show-depends:
@echo $* :
# Clean package
$(BUILD_DIR)/%/.stamp_cleaned:
@$(call MESSAGE,"Cleaning up")
$($(PKG)_CLEAN_CMDS)
rm -f $(@D)/.stamp_built
# Uninstall package from target and staging
# Uninstall commands tend to fail, so remove the stamp files first
$(BUILD_DIR)/%/.stamp_uninstalled:
@$(call MESSAGE,"Uninstalling")
rm -f $($(PKG)_TARGET_INSTALL_STAGING)
rm -f $($(PKG)_TARGET_INSTALL_TARGET)
rm -f $($(PKG)_TARGET_INSTALL_IMAGES)
$($(PKG)_UNINSTALL_STAGING_CMDS)
$($(PKG)_UNINSTALL_TARGET_CMDS)
$($(PKG)_UNINSTALL_IMAGES_CMDS)
# Remove package sources
$(BUILD_DIR)/%/.stamp_dircleaned:
$($(PKG)_DIRCLEAN_CMDS)
rm -Rf $(@D)
@if [[ "$($(PKG)_SITE_METHOD)" == "repo" ]] || [[ "$($(PKG)_SITE_METHOD)" == "rrepo" ]]; then \
echo rm -f $(DL_DIR)/$($(PKG)_SOURCE); \
rm -f $(DL_DIR)/$($(PKG)_SOURCE); \
fi
rm -f $($(PKG)_TARGET_INSTALL_ALL) $($(PKG)_TARGET_DEPENDS_DONE)
################################################################################
# GENTARGETS_INNER -- generates the make targets needed to build a
# generic package
#
# argument 1 is the lowercase package name
# argument 2 is the uppercase package name, including an HOST_ prefix
# for host packages
# argument 3 is the uppercase package name, without the HOST_ prefix
# for host packages
# argument 4 is the package directory prefix
# argument 5 is the type (target or host)
################################################################################
define GENTARGETS_INNER
# Define default values for various package-related variables, if not
# already defined. For some variables (version, source, site and
# subdir), if they are undefined, we try to see if a variable without
# the HOST_ prefix is defined. If so, we use such a variable, so that
# these informations have only to be specified once, for both the
# target and host packages of a given .mk file.
$(2)_TYPE = $(5)
$(2)_NAME = $(1)
# Keep the package version that may contain forward slashes in the _DL_VERSION
# variable, then replace all forward slashes ('/') by underscores ('_') to
# sanitize the package version that is used in paths, directory and file names.
# Forward slashes may appear in the package's version when pointing to a
# version control system branch or tag, for example remotes/origin/1_10_stable.
ifndef $(2)_VERSION
ifdef $(3)_VERSION
$(2)_DL_VERSION = $($(3)_VERSION)
$(2)_VERSION = $(subst /,_,$($(3)_VERSION))
else
$(2)_VERSION = undefined
$(2)_DL_VERSION = undefined
ifeq ($(firstword $(subst ://, ,$(call qstrip,$($(2)_SITE)))),repo)
$(2)_VERSION=HEAD
$(2)_DL_VERSION=HEAD
endif
ifeq ($(firstword $(subst ://, ,$(call qstrip,$($(2)_SITE)))),rrepo)
$(2)_VERSION=HEAD
$(2)_DL_VERSION=HEAD
endif
endif
else
$(2)_DL_VERSION = $($(2)_VERSION)
$(2)_VERSION = $(subst /,_,$($(2)_VERSION))
endif
$(2)_BASE_NAME = $(1)-$$($(2)_VERSION)
$(2)_DL_DIR = $$(DL_DIR)/$$($(2)_BASE_NAME)
$(2)_DIR = $$(BUILD_DIR)/$$($(2)_BASE_NAME)
ifneq ($$($(2)_OVERRIDE_SRCDIR),)
$(2)_VERSION = custom
endif
ifndef $(2)_SOURCE
ifdef $(3)_SOURCE
$(2)_SOURCE = $($(3)_SOURCE)
else
$(2)_SOURCE ?= $$($(2)_BASE_NAME).tar.gz
endif
endif
ifndef $(2)_PATCH
ifdef $(3)_PATCH
$(2)_PATCH = $($(3)_PATCH)
endif
endif
ifndef $(2)_TEST
ifdef $(3)_TEST
$(2)_TEST = $($(3)_TEST)
endif
endif
ifndef $(2)_COVERAGE
ifdef $(3)_COVERAGE
$(2)_COVERAGE = $($(3)_COVERAGE)
endif
endif
ifndef $(2)_SITE
ifdef $(3)_SITE
$(2)_SITE = $($(3)_SITE)
else
$(2)_SITE ?= \
http://$$(BR2_SOURCEFORGE_MIRROR).dl.sourceforge.net/sourceforge/$(1)
endif
endif
ifndef $(2)_SITE_METHOD
ifdef $(3)_SITE_METHOD
$(2)_SITE_METHOD = $($(3)_SITE_METHOD)
else
# Try automatic detection using the scheme part of the URI
$(2)_SITE_METHOD = $(firstword $(subst ://, ,$(call qstrip,$($(2)_SITE))))
endif
endif
ifeq ($$($(2)_SITE_METHOD),local)
ifeq ($$($(2)_OVERRIDE_SRCDIR),)
$(2)_OVERRIDE_SRCDIR = $($(2)_SITE)
endif
endif
ifndef $(2)_REPO_PATH
ifdef $(3)_REPO_PATH
$(2)_REPO_PATH = $($(3)_REPO_PATH)
else
$(2)_REPO_PATH=$(lastword $(subst ://, ,$(call qstrip,$($(2)_SITE))))
endif
endif
$(2)_DEPENDENCIES ?= $(patsubst host-host-%,host-%,$(addprefix host-,$($(3)_DEPENDENCIES)))
$(2)_TEST ?= NO
$(2)_COVERAGE ?= NO
$(2)_INSTALL_STAGING ?= NO
$(2)_INSTALL_IMAGES ?= NO
ifeq ($$($(2)_TYPE),host)
$(2)_INSTALL_TARGET ?= NO
else
$(2)_INSTALL_TARGET ?= YES
endif
$(2)_DIR_PREFIX = $(if $(4),$(4),$(TOP_SRCDIR)/package)
# define sub-target stamps
$(2)_TARGET_INSTALL_ALL = $(STAMP_DIR)/$(1)
$(2)_TARGET_INSTALL_TARGET = $$($(2)_DIR)/.stamp_target_installed
$(2)_TARGET_INSTALL_STAGING = $$($(2)_DIR)/.stamp_staging_installed
$(2)_TARGET_INSTALL_IMAGES = $$($(2)_DIR)/.stamp_images_installed
$(2)_TARGET_INSTALL_HOST = $$($(2)_DIR)/.stamp_host_installed
$(2)_TARGET_BUILD = $$($(2)_DIR)/.stamp_built
$(2)_TARGET_CONFIGURE = $$($(2)_DIR)/.stamp_configured
$(2)_TARGET_DEPENDS_DONE = $(STAMP_DIR)/$(1).deps
$(2)_TARGET_RSYNC = $$($(2)_DIR)/.stamp_rsynced
$(2)_TARGET_RSYNC_SOURCE = $$($(2)_DIR)/.stamp_rsync_sourced
$(2)_TARGET_PATCH = $$($(2)_DIR)/.stamp_patched
$(2)_TARGET_TEST = $$($(2)_DIR)/.stamp_tested
$(2)_TARGET_COVERAGE = $$($(2)_DIR)/.stamp_coverage_done
$(2)_TARGET_EXTRACT = $$($(2)_DIR)/.stamp_extracted
$(2)_TARGET_SOURCE = $$($(2)_DIR)/.stamp_downloaded
$(2)_TARGET_UNINSTALL = $$($(2)_DIR)/.stamp_uninstalled
$(2)_TARGET_CLEAN = $$($(2)_DIR)/.stamp_cleaned
$(2)_TARGET_DIRCLEAN = $$($(2)_DIR)/.stamp_dircleaned
# default extract command
ifeq ($$($(2)_SITE_METHOD),repo)
$(2)_EXTRACT_CMDS ?=
else
ifeq ($$($(2)_SITE_METHOD),rrepo)
$(2)_EXTRACT_CMDS ?=
else
$(2)_EXTRACT_CMDS ?= \
$$(if $$($(2)_SOURCE),$$(INFLATE$$(suffix $$($(2)_SOURCE))) $(DL_DIR)/$$($(2)_SOURCE) | \
$(TAR) $(TAR_STRIP_COMPONENTS)=1 -C $$($(2)_DIR) $(TAR_OPTIONS) -)
endif
endif
# post-steps hooks
$(2)_POST_DOWNLOAD_HOOKS ?=
$(2)_POST_EXTRACT_HOOKS ?=
$(2)_PRE_PATCH_HOOKS ?=
$(2)_POST_PATCH_HOOKS ?=
$(2)_PRE_CONFIGURE_HOOKS ?=
$(2)_POST_CONFIGURE_HOOKS ?=
$(2)_POST_BUILD_HOOKS ?=
$(2)_POST_INSTALL_HOOKS ?=
$(2)_POST_INSTALL_STAGING_HOOKS ?=
$(2)_POST_INSTALL_TARGET_HOOKS ?=
$(2)_POST_INSTALL_IMAGES_HOOKS ?=
# human-friendly targets and target sequencing
$(1): $(1)-install
$(1)-install: $$($(2)_TARGET_INSTALL_ALL)
ifeq ($$($(2)_TYPE),host)
$$($(2)_TARGET_INSTALL_ALL): $$($(2)_TARGET_INSTALL_HOST)
$(2)_DEP_HOST_X = $$($(2)_TARGET_INSTALL_HOST)
else
$$($(2)_TARGET_INSTALL_ALL):
endif
$$($(2)_TARGET_EXTRACT): $$($(2)_TARGET_SOURCE)
$$($(2)_TARGET_PATCH): $$($(2)_TARGET_EXTRACT)
$$($(2)_TARGET_CONFIGURE): $$($(2)_TARGET_PATCH) \
$$($(2)_TARGET_DEPENDS_DONE)
$$($(2)_TARGET_BUILD): $$($(2)_TARGET_CONFIGURE)
$$($(2)_TARGET_INSTALL_TARGET): $$($(2)_TARGET_BUILD) $(BUILD_DIR)/.root
$$($(2)_TARGET_INSTALL_STAGING): $$($(2)_TARGET_BUILD)
$$($(2)_TARGET_INSTALL_IMAGES): $$($(2)_TARGET_BUILD)
$$($(2)_TARGET_INSTALL_HOST): $$($(2)_TARGET_BUILD)
$$($(2)_TARGET_TEST): $$($(2)_TARGET_BUILD)
$$($(2)_TARGET_COVERAGE): $$($(2)_TARGET_CONFIGURE)
ifeq ($$($(2)_INSTALL_TARGET),YES)
$(1)-install-target: $$($(2)_TARGET_INSTALL_TARGET)
$$($(2)_TARGET_INSTALL_ALL): $$($(2)_TARGET_INSTALL_TARGET)
$(2)_DEP_TARGET_X = $$($(2)_TARGET_INSTALL_TARGET)
else
$(1)-install-target:
endif
ifeq ($$($(2)_INSTALL_STAGING),YES)
$(1)-install-staging: $$($(2)_TARGET_INSTALL_STAGING)
$$($(2)_TARGET_INSTALL_ALL): $$($(2)_TARGET_INSTALL_STAGING)
$(2)_DEP_STAGING_X = $$($(2)_TARGET_INSTALL_STAGING)
else
$(1)-install-staging:
endif
ifeq ($$($(2)_INSTALL_IMAGES),YES)
$(1)-install-images: $$($(2)_TARGET_INSTALL_IMAGES)
$$($(2)_TARGET_INSTALL_ALL): $$($(2)_TARGET_INSTALL_IMAGES)
$(2)_DEP_IMAGES_X = $$($(2)_TARGET_INSTALL_IMAGES)
else
$(1)-install-images:
endif
# Enforce strict ordering of installation steps so we don't try to install
# to two places at once (many packages crash if you try to do this, because
# they create temporary files in the source dir). This has to be complicated
# because some packages don't do various kinds of installs.
$$($(2)_TARGET_INSTALL_TARGET): $$($(2)_DEP_STAGING_X) \
$$($(2)_DEP_IMAGES_X) \
$$($(2)_DEP_HOST_X)
$$($(2)_TARGET_INSTALL_STAGING): $$($(2)_DEP_IMAGES_X) \
$$($(2)_DEP_HOST_X)
$$($(2)_TARGET_INSTALL_IMAGES): $$($(2)_DEP_HOST_X)
$(1)-install-host: $$($(2)_TARGET_INSTALL_HOST)
$(1)-build: $$($(2)_TARGET_BUILD)
$(1)-test: $$($(2)_TARGET_TEST)
$(1)-coverage: $$($(2)_TARGET_COVERAGE)
# Run host tests as part of test if configured.
ifneq ($$(HOST_$(2)_TEST_CMDS),)
$(1)-test: host-$(1)-test
endif
$(2)_DEPENDS_STAMPS = $$(patsubst %,$(STAMP_DIR)/%,$$(filter-out $(1),$$($(2)_DEPENDENCIES) $(PRE_DEPENDS)))
$(1)-dp:
@echo foo1 '|$$($(2)_DEPENDENCIES)|'
@echo foo2 '|$$($(2)_DEPENDS_STAMPS)|'
$$($(2)_TARGET_DEPENDS_DONE): $$($(2)_TARGET_EXTRACT) \
$$($(2)_DEPENDS_STAMPS)
@touch $$($(2)_TARGET_DEPENDS_DONE)
ifeq ($$($(2)_OVERRIDE_SRCDIR),)
# In the normal case (no package override), the sequence of steps is
# source, by downloading
# depends
# extract
# patch
# configure
$(1)-configure: $$($(2)_TARGET_CONFIGURE)
$$($(2)_TARGET_CONFIGURE): $$($(2)_TARGET_PATCH)
$(1)-patch: $$($(2)_TARGET_PATCH)
$(1)-extract: $$($(2)_TARGET_EXTRACT)
$(1)-depends: $$($(2)_TARGET_DEPENDS_DONE)
$(1)-source: $$($(2)_TARGET_SOURCE)
else
# In the package override case, the sequence of steps
# source, by rsyncing
# depends
# configure
$(1)-configure: $$($(2)_TARGET_CONFIGURE)
$(1)-depends: $$($(2)_TARGET_RSYNC) $$($(2)_TARGET_DEPENDS_DONE)
$(1)-rsync: $$($(2)_TARGET_RSYNC)
$(1)-source: $$($(2)_TARGET_RSYNC_SOURCE)
endif
$(1)-show-depends: $(patsubst %,%-show-depends,$($(2)_DEPENDENCIES))
@echo $(1) : $$($(2)_DEPENDENCIES)
$(1)-is-enabled:
@echo "is-enabled: $(1): '$$(BR2_PACKAGE_$(2))'"
$(Q) \
[ "$(1)" = linux ] || \
[ "$(1)" = automake ] || \
[ "$(1)" = autoconf ] || \
[ "$(1)" = libtool ] || \
[ "$(1)" = cmake ] || \
[ "$(1)" = gdb_target ] || \
if [ "$$(BR2_PACKAGE_$(2))" != 'y' ]; then \
echo "error: $(1) is depended on but BR2_PACKAGE_$(2) not set" >&2; \
exit 1; \
fi
$(1)-depcheck: $$(filter-out host-%,$$(patsubst %,%-is-enabled,$$($(2)_DEPENDENCIES)))
$(1)-uninstall: $(1)-configure $$($(2)_TARGET_UNINSTALL)
$(1)-clean: $(1)-uninstall \
$$($(2)_TARGET_CLEAN)
$(1)-dirclean: $$($(2)_TARGET_DIRCLEAN)
$(1)-clean-for-rebuild:
ifneq ($$($(2)_OVERRIDE_SRCDIR),)
rm -f $$($(2)_TARGET_RSYNC)
endif
rm -f $$($(2)_TARGET_BUILD)
rm -f $$($(2)_TARGET_INSTALL_STAGING)
rm -f $$($(2)_TARGET_INSTALL_TARGET)
rm -f $$($(2)_TARGET_INSTALL_IMAGES)
rm -f $$($(2)_TARGET_INSTALL_HOST)
rm -f $$($(2)_TARGET_TEST)
rm -f $$($(2)_TARGET_COVERAGE)
$(1)-rebuild: $(1)-clean-for-rebuild all
$(1)-clean-for-reconfigure: $(1)-clean-for-rebuild
rm -f $$($(2)_TARGET_CONFIGURE)
$(1)-buildbash: $(1)-extract $$($(2)_TARGET_BASH)
@$(call BASH_HEADER,$(1),$(2))
@cd $$($(2)_DIR); env PS1="[build-$(1)] % " /bin/bash --norc -i </dev/tty
$(1)-reconfigure: $(1)-clean-for-reconfigure all
# define the PKG variable for all targets, containing the
# uppercase package variable prefix
$$($(2)_TARGET_INSTALL_TARGET): PKG=$(2)
$$($(2)_TARGET_INSTALL_TARGET): RAWNAME=$(patsubst host-%,%,$(1))
$$($(2)_TARGET_INSTALL_STAGING): PKG=$(2)
$$($(2)_TARGET_INSTALL_IMAGES): PKG=$(2)
$$($(2)_TARGET_INSTALL_HOST): PKG=$(2)
$$($(2)_TARGET_BUILD): PKG=$(2)
$$($(2)_TARGET_TEST): PKG=$(2)
$$($(2)_TARGET_COVERAGE): PKG=$(2)
$$($(2)_TARGET_CONFIGURE): PKG=$(2)
$$($(2)_TARGET_RSYNC): SRCDIR=$$($(2)_OVERRIDE_SRCDIR)
$$($(2)_TARGET_RSYNC): PKG=$(2)
$$($(2)_TARGET_RSYNC_SOURCE): SRCDIR=$$($(2)_OVERRIDE_SRCDIR)
$$($(2)_TARGET_RSYNC_SOURCE): PKG=$(2)
$$($(2)_TARGET_PATCH): PKG=$(2)
$$($(2)_TARGET_PATCH): RAWNAME=$(patsubst host-%,%,$(1))
$$($(2)_TARGET_EXTRACT): PKG=$(2)
$$($(2)_TARGET_SOURCE): PKG=$(2)
$$($(2)_TARGET_UNINSTALL): PKG=$(2)
$$($(2)_TARGET_CLEAN): PKG=$(2)
$$($(2)_TARGET_DIRCLEAN): PKG=$(2)
$$($(2)_TARGET_BASH): PKG=$(2)
# Compute the name of the Kconfig option that correspond to the
# package being enabled. We handle three cases: the special Linux
# kernel case, the bootloaders case, and the normal packages case.
ifeq ($(1),linux)
$(2)_KCONFIG_VAR = BR2_LINUX_KERNEL
else ifeq ($(4),boot/)
$(2)_KCONFIG_VAR = BR2_TARGET_$(2)
else
$(2)_KCONFIG_VAR = BR2_PACKAGE_$(2)
endif
# add package to the general list of targets if requested by the buildroot
# configuration
ifeq ($$($$($(2)_KCONFIG_VAR)),y)
TARGETS += $(1)
PACKAGES_PERMISSIONS_TABLE += $$($(2)_PERMISSIONS)$$(sep)
PACKAGES_DEVICES_TABLE += $$($(2)_DEVICES)$$(sep)
ifneq ($$($(2)_TYPE),host)
TARGET_STAMPFILES += $$($(2)_TARGET_INSTALL_TARGET)
endif
ifeq ($$($(2)_INSTALL_IMAGES),YES)
IMAGE_STAMPFILES += $$($(2)_TARGET_INSTALL_IMAGES)
endif
ifeq ($$($(2)_SITE_METHOD),svn)
DL_TOOLS_DEPENDENCIES += svn
else ifeq ($$($(2)_SITE_METHOD),git)
DL_TOOLS_DEPENDENCIES += git
else ifeq ($$($(2)_SITE_METHOD),bzr)
DL_TOOLS_DEPENDENCIES += bzr
else ifeq ($$($(2)_SITE_METHOD),scp)
DL_TOOLS_DEPENDENCIES += scp ssh
else ifeq ($$($(2)_SITE_METHOD),hg)
DL_TOOLS_DEPENDENCIES += hg
endif # SITE_METHOD
DL_TOOLS_DEPENDENCIES += $(firstword $(INFLATE$(suffix $($(2)_SOURCE))))
endif # $(2)_KCONFIG_VAR
endef # GENTARGETS_INNER
################################################################################
# GENTARGETS -- the target generator macro for generic packages
#
# Argument 1 is "target" or "host" [optional, default: "target"]
################################################################################
define GENTARGETS
ifeq ($(1),host)
# In the case of host packages, turn the package name "pkg" into "host-pkg"
$(call GENTARGETS_INNER,$(1)-$(call pkgname),$(call UPPERCASE,$(1)-$(call pkgname)),$(call UPPERCASE,$(call pkgname)),$(call pkgparentdir),host)
else
# In the case of target packages, keep the package name "pkg"
$(call GENTARGETS_INNER,$(call pkgname),$(call UPPERCASE,$(call pkgname)),$(call UPPERCASE,$(call pkgname)),$(call pkgparentdir),target)
endif
endef
# :mode=makefile: