From: Thomas Petazzoni Date: Tue, 17 Apr 2012 14:45:19 +0000 (+0200) Subject: Split Makefile.package.in in pkg-download.mk, pkg-utils.mk and pkg-gentargets.mk X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6e6b99a5714834c9330c30dd3af04009f5713204;p=buildroot.git Split Makefile.package.in in pkg-download.mk, pkg-utils.mk and pkg-gentargets.mk Signed-off-by: Thomas Petazzoni Signed-off-by: Peter Korsgaard --- diff --git a/package/Makefile.in b/package/Makefile.in index ab5ea48422..943017b5dc 100644 --- a/package/Makefile.in +++ b/package/Makefile.in @@ -299,6 +299,8 @@ else SHARED_STATIC_LIBS_OPTS=--enable-static --enable-shared endif +include package/pkg-utils.mk +include package/pkg-download.mk include package/pkg-autotargets.mk include package/pkg-cmaketargets.mk -include package/Makefile.package.in +include package/pkg-gentargets.mk diff --git a/package/Makefile.package.in b/package/Makefile.package.in deleted file mode 100644 index f7b65666fa..0000000000 --- a/package/Makefile.package.in +++ /dev/null @@ -1,750 +0,0 @@ -################################################################################ -# 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)" -TERM_BOLD := $(shell tput smso) -TERM_RESET := $(shell tput rmso) - -# 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) -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 - -# -# 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_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)))' $(DL_DIR)/$(2) -endef - -define SOURCE_CHECK_SCP - $(SSH) $(call domain,$(1),:) ls '$(call notdomain,$(1),:)' > /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 - -# Download a file using wget. Only download the file if it doesn't -# already exist in the download directory. If the download fails, -# remove the file (because wget -O creates a 0-byte file even if the -# download fails). -define DOWNLOAD_WGET - test -e $(DL_DIR)/$(2) || \ - $(WGET) -O $(DL_DIR)/$(2) '$(call qstrip,$(1))' || \ - (rm -f $(DL_DIR)/$(2) ; exit 1) -endef - -define SOURCE_CHECK_WGET - $(WGET) --spider '$(call qstrip,$(1))' -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 - -################################################################################ -# 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 - $(call DOWNLOAD_INNER,$(1),$(if $(2),$(2),$(notdir $(1)))) -endef - -define DOWNLOAD_INNER - $(Q)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 ;; \ - *) $(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),$(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) - $($(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 _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/) 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),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) || 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") - $($(PKG)_CONFIGURE_CMDS) - $(foreach hook,$($(PKG)_POST_CONFIGURE_HOOKS),$(call $(hook))$(sep)) - $(Q)touch $@ - -# Build -$(BUILD_DIR)/%/.stamp_built:: - @$(call MESSAGE,"Building") - $($(PKG)_BUILD_CMDS) - $(foreach hook,$($(PKG)_POST_BUILD_HOOKS),$(call $(hook))$(sep)) - $(Q)touch $@ - -# Install to host dir -$(BUILD_DIR)/%/.stamp_host_installed: - @$(call MESSAGE,"Installing to host directory") - $($(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") - $($(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") - $($(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") - $($(PKG)_INSTALL_TARGET_CMDS) - $(foreach hook,$($(PKG)_POST_INSTALL_TARGET_HOOKS),$(call $(hook))$(sep)) - $(Q)touch $@ - -# 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) - $($(PKG)_UNINSTALL_STAGING_CMDS) - $($(PKG)_UNINSTALL_TARGET_CMDS) - -# Remove package sources -$(BUILD_DIR)/%/.stamp_dircleaned: - rm -Rf $(@D) - -################################################################################ -# 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 - 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)_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 - -$(2)_DEPENDENCIES ?= $(patsubst host-host-%,host-%,$(addprefix host-,$($(3)_DEPENDENCIES))) - -$(2)_INSTALL_STAGING ?= NO -$(2)_INSTALL_IMAGES ?= NO -$(2)_INSTALL_TARGET ?= YES -$(2)_DIR_PREFIX = $(if $(4),$(4),$(TOP_SRCDIR)/package) - -# define sub-target stamps -$(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_RSYNC = $$($(2)_DIR)/.stamp_rsynced -$(2)_TARGET_RSYNC_SOURCE = $$($(2)_DIR)/.stamp_rsync_sourced -$(2)_TARGET_PATCH = $$($(2)_DIR)/.stamp_patched -$(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 -$(2)_EXTRACT_CMDS ?= \ - $$(if $$($(2)_SOURCE),$$(INFLATE$$(suffix $$($(2)_SOURCE))) $(DL_DIR)/$$($(2)_SOURCE) | \ - $(TAR) $(TAR_STRIP_COMPONENTS)=1 -C $$($(2)_DIR) $(TAR_OPTIONS) -) - -# 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 - -ifeq ($$($(2)_TYPE),host) -$(1)-install: $(1)-install-host -else -$(1)-install: $(1)-install-staging $(1)-install-target $(1)-install-images -endif - -ifeq ($$($(2)_INSTALL_TARGET),YES) -$(1)-install-target: $(1)-build \ - $$($(2)_TARGET_INSTALL_TARGET) -else -$(1)-install-target: -endif - -ifeq ($$($(2)_INSTALL_STAGING),YES) -$(1)-install-staging: $(1)-build \ - $$($(2)_TARGET_INSTALL_STAGING) -else -$(1)-install-staging: -endif - -ifeq ($$($(2)_INSTALL_IMAGES),YES) -$(1)-install-images: $(1)-build \ - $$($(2)_TARGET_INSTALL_IMAGES) -else -$(1)-install-images: -endif - -$(1)-install-host: $(1)-build $$($(2)_TARGET_INSTALL_HOST) - -$(1)-build: $(1)-configure \ - $$($(2)_TARGET_BUILD) - -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: $(1)-patch $(1)-depends \ - $$($(2)_TARGET_CONFIGURE) - -$(1)-patch: $(1)-extract $$($(2)_TARGET_PATCH) - -$(1)-extract: $(1)-source \ - $$($(2)_TARGET_EXTRACT) - -$(1)-depends: $$($(2)_DEPENDENCIES) - -$(1)-source: $$($(2)_TARGET_SOURCE) -else -# In the package override case, the sequence of steps -# source, by rsyncing -# depends -# configure -$(1)-configure: $(1)-depends \ - $$($(2)_TARGET_CONFIGURE) - -$(1)-depends: $(1)-rsync $$($(2)_DEPENDENCIES) - -$(1)-rsync: $$($(2)_TARGET_RSYNC) - -$(1)-source: $$($(2)_TARGET_RSYNC_SOURCE) -endif - -$(1)-show-depends: - @echo $$($(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) - -$(1)-rebuild: $(1)-clean-for-rebuild all - -$(1)-clean-for-reconfigure: $(1)-clean-for-rebuild - rm -f $$($(2)_TARGET_CONFIGURE) - -$(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_STAGING): PKG=$(2) -$$($(2)_TARGET_INSTALL_IMAGES): PKG=$(2) -$$($(2)_TARGET_INSTALL_HOST): PKG=$(2) -$$($(2)_TARGET_BUILD): 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) - -# 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) - -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: diff --git a/package/pkg-download.mk b/package/pkg-download.mk new file mode 100644 index 0000000000..a565ae6960 --- /dev/null +++ b/package/pkg-download.mk @@ -0,0 +1,219 @@ +# 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) +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 + +# +# 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_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)))' $(DL_DIR)/$(2) +endef + +define SOURCE_CHECK_SCP + $(SSH) $(call domain,$(1),:) ls '$(call notdomain,$(1),:)' > /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 + +# Download a file using wget. Only download the file if it doesn't +# already exist in the download directory. If the download fails, +# remove the file (because wget -O creates a 0-byte file even if the +# download fails). +define DOWNLOAD_WGET + test -e $(DL_DIR)/$(2) || \ + $(WGET) -O $(DL_DIR)/$(2) '$(call qstrip,$(1))' || \ + (rm -f $(DL_DIR)/$(2) ; exit 1) +endef + +define SOURCE_CHECK_WGET + $(WGET) --spider '$(call qstrip,$(1))' +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 + +################################################################################ +# 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 + $(call DOWNLOAD_INNER,$(1),$(if $(2),$(2),$(notdir $(1)))) +endef + +define DOWNLOAD_INNER + $(Q)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 ;; \ + *) $(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),$(2)) && exit ; \ + fi ; \ + exit 1 +endef diff --git a/package/pkg-gentargets.mk b/package/pkg-gentargets.mk new file mode 100644 index 0000000000..a5356814a6 --- /dev/null +++ b/package/pkg-gentargets.mk @@ -0,0 +1,458 @@ +################################################################################ +# 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. +################################################################################ + +################################################################################ +# 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) + $($(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 _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/) 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),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) || 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") + $($(PKG)_CONFIGURE_CMDS) + $(foreach hook,$($(PKG)_POST_CONFIGURE_HOOKS),$(call $(hook))$(sep)) + $(Q)touch $@ + +# Build +$(BUILD_DIR)/%/.stamp_built:: + @$(call MESSAGE,"Building") + $($(PKG)_BUILD_CMDS) + $(foreach hook,$($(PKG)_POST_BUILD_HOOKS),$(call $(hook))$(sep)) + $(Q)touch $@ + +# Install to host dir +$(BUILD_DIR)/%/.stamp_host_installed: + @$(call MESSAGE,"Installing to host directory") + $($(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") + $($(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") + $($(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") + $($(PKG)_INSTALL_TARGET_CMDS) + $(foreach hook,$($(PKG)_POST_INSTALL_TARGET_HOOKS),$(call $(hook))$(sep)) + $(Q)touch $@ + +# 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) + $($(PKG)_UNINSTALL_STAGING_CMDS) + $($(PKG)_UNINSTALL_TARGET_CMDS) + +# Remove package sources +$(BUILD_DIR)/%/.stamp_dircleaned: + rm -Rf $(@D) + +################################################################################ +# 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 + 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)_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 + +$(2)_DEPENDENCIES ?= $(patsubst host-host-%,host-%,$(addprefix host-,$($(3)_DEPENDENCIES))) + +$(2)_INSTALL_STAGING ?= NO +$(2)_INSTALL_IMAGES ?= NO +$(2)_INSTALL_TARGET ?= YES +$(2)_DIR_PREFIX = $(if $(4),$(4),$(TOP_SRCDIR)/package) + +# define sub-target stamps +$(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_RSYNC = $$($(2)_DIR)/.stamp_rsynced +$(2)_TARGET_RSYNC_SOURCE = $$($(2)_DIR)/.stamp_rsync_sourced +$(2)_TARGET_PATCH = $$($(2)_DIR)/.stamp_patched +$(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 +$(2)_EXTRACT_CMDS ?= \ + $$(if $$($(2)_SOURCE),$$(INFLATE$$(suffix $$($(2)_SOURCE))) $(DL_DIR)/$$($(2)_SOURCE) | \ + $(TAR) $(TAR_STRIP_COMPONENTS)=1 -C $$($(2)_DIR) $(TAR_OPTIONS) -) + +# 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 + +ifeq ($$($(2)_TYPE),host) +$(1)-install: $(1)-install-host +else +$(1)-install: $(1)-install-staging $(1)-install-target $(1)-install-images +endif + +ifeq ($$($(2)_INSTALL_TARGET),YES) +$(1)-install-target: $(1)-build \ + $$($(2)_TARGET_INSTALL_TARGET) +else +$(1)-install-target: +endif + +ifeq ($$($(2)_INSTALL_STAGING),YES) +$(1)-install-staging: $(1)-build \ + $$($(2)_TARGET_INSTALL_STAGING) +else +$(1)-install-staging: +endif + +ifeq ($$($(2)_INSTALL_IMAGES),YES) +$(1)-install-images: $(1)-build \ + $$($(2)_TARGET_INSTALL_IMAGES) +else +$(1)-install-images: +endif + +$(1)-install-host: $(1)-build $$($(2)_TARGET_INSTALL_HOST) + +$(1)-build: $(1)-configure \ + $$($(2)_TARGET_BUILD) + +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: $(1)-patch $(1)-depends \ + $$($(2)_TARGET_CONFIGURE) + +$(1)-patch: $(1)-extract $$($(2)_TARGET_PATCH) + +$(1)-extract: $(1)-source \ + $$($(2)_TARGET_EXTRACT) + +$(1)-depends: $$($(2)_DEPENDENCIES) + +$(1)-source: $$($(2)_TARGET_SOURCE) +else +# In the package override case, the sequence of steps +# source, by rsyncing +# depends +# configure +$(1)-configure: $(1)-depends \ + $$($(2)_TARGET_CONFIGURE) + +$(1)-depends: $(1)-rsync $$($(2)_DEPENDENCIES) + +$(1)-rsync: $$($(2)_TARGET_RSYNC) + +$(1)-source: $$($(2)_TARGET_RSYNC_SOURCE) +endif + +$(1)-show-depends: + @echo $$($(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) + +$(1)-rebuild: $(1)-clean-for-rebuild all + +$(1)-clean-for-reconfigure: $(1)-clean-for-rebuild + rm -f $$($(2)_TARGET_CONFIGURE) + +$(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_STAGING): PKG=$(2) +$$($(2)_TARGET_INSTALL_IMAGES): PKG=$(2) +$$($(2)_TARGET_INSTALL_HOST): PKG=$(2) +$$($(2)_TARGET_BUILD): 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) + +# 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) + +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: diff --git a/package/pkg-utils.mk b/package/pkg-utils.mk new file mode 100644 index 0000000000..729f8bbe4b --- /dev/null +++ b/package/pkg-utils.mk @@ -0,0 +1,72 @@ +# 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)" +TERM_BOLD := $(shell tput smso) +TERM_RESET := $(shell tput rmso) + + +# 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