summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2010-10-07 19:14:48 +0000
committerMichał Górny <mgorny@gentoo.org>2010-10-07 19:14:48 +0000
commita4198ba1d17dde94dd65dc5a813c9c21da7e3658 (patch)
tree20b174b4e271ff3cca41281b004e616011db3640
parentold (diff)
downloadgentoo-2-a4198ba1d17dde94dd65dc5a813c9c21da7e3658.tar.gz
gentoo-2-a4198ba1d17dde94dd65dc5a813c9c21da7e3658.tar.bz2
gentoo-2-a4198ba1d17dde94dd65dc5a813c9c21da7e3658.zip
Introducing scons-utils.eclass -- a new eclass providing functions to help using SCons buildsystem.
-rw-r--r--eclass/scons-utils.eclass200
-rwxr-xr-xeclass/tests/scons-utils.sh55
2 files changed, 255 insertions, 0 deletions
diff --git a/eclass/scons-utils.eclass b/eclass/scons-utils.eclass
new file mode 100644
index 000000000000..99791501e15d
--- /dev/null
+++ b/eclass/scons-utils.eclass
@@ -0,0 +1,200 @@
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/eclass/scons-utils.eclass,v 1.1 2010/10/07 19:14:48 mgorny Exp $
+
+# @ECLASS: scons-utils.eclass
+# @MAINTAINER:
+# mgorny@gentoo.org
+# @BLURB: helper functions to deal with SCons buildsystem
+# @DESCRIPTION:
+# This eclass provides a set of function to help developers sanely call
+# dev-util/scons and pass parameters to it.
+# @EXAMPLE:
+#
+# @CODE
+# inherit scons-utils
+#
+# src_compile() {
+# escons \
+# $(use_scons nls ENABLE_NLS) \
+# || die
+# }
+# @CODE
+
+# -- public variables --
+
+# @ECLASS-VARIABLE: SCONS_MIN_VERSION
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# The minimal version of SCons required for the build to work.
+
+# @ECLASS-VARIABLE: SCONSOPTS
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# The default set of options to pass to scons. Similar to MAKEOPTS,
+# supposed to be set in make.conf. If unset, escons() will use cleaned
+# up MAKEOPTS instead.
+
+# @ECLASS-VARIABLE: EXTRA_ESCONS
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# The additional parameters to pass to SCons whenever escons() is used.
+
+# @ECLASS-VARIABLE: USE_SCONS_TRUE
+# @DESCRIPTION:
+# The default value for truth in scons-use() (1 by default).
+: ${USE_SCONS_TRUE:=1}
+
+# @ECLASS-VARIABLE: USE_SCONS_FALSE
+# @DESCRIPTION:
+# The default value for false in scons-use() (0 by default).
+: ${USE_SCONS_FALSE:=0}
+
+# -- ebuild variables setup --
+
+if [[ -n ${SCONS_MIN_VERSION} ]]; then
+ DEPEND=">=dev-util/scons-${SCONS_MIN_VERSION}"
+else
+ DEPEND="dev-util/scons"
+fi
+
+# -- public functions --
+
+# @FUNCTION: escons
+# @USAGE: [scons-arg] ...
+# @DESCRIPTION:
+# Call scons, passing the supplied arguments, ${MAKEOPTS} and
+# ${EXTRA_ESCONS}. Similar to emake.
+escons() {
+ debug-print-function ${FUNCNAME} "${@}"
+
+ # if SCONSOPTS are _unset_, use cleaned MAKEOPTS
+ set -- scons ${SCONSOPTS-$(scons_clean_makeopts)} ${EXTRA_ESCONS} "${@}"
+ echo "${@}" >&2
+ "${@}"
+}
+
+# @FUNCTION: scons_clean_makeopts
+# @USAGE: [makeflags] [...]
+# @DESCRIPTION:
+# Strip the supplied makeflags (or ${MAKEOPTS} if called without
+# an argument) of options not supported by SCons and make sure --jobs
+# gets an argument. Output the resulting flag list (suitable
+# for an assignment to SCONSOPTS).
+scons_clean_makeopts() {
+ local new_makeopts
+
+ debug-print-function ${FUNCNAME} "${@}"
+
+ if [[ ${#} -eq 0 ]]; then
+ debug-print "Using MAKEOPTS: [${MAKEOPTS}]"
+ set -- ${MAKEOPTS}
+ else
+ # unquote if necessary
+ set -- ${*}
+ fi
+
+ # empty MAKEOPTS give out empty SCONSOPTS
+ # thus, we do need to worry about the initial setup
+ if [[ ${*} = ${_SCONS_CACHE_MAKEOPTS} ]]; then
+ set -- ${_SCONS_CACHE_SCONSOPTS}
+ debug-print "Cache hit: [${*}]"
+ echo ${*}
+ return
+ fi
+ export _SCONS_CACHE_MAKEOPTS=${*}
+
+ while [[ ${#} -gt 0 ]]; do
+ case ${1} in
+ # clean, simple to check -- we like that
+ --jobs=*|--keep-going)
+ new_makeopts=${new_makeopts+${new_makeopts} }${1}
+ ;;
+ # need to take a look at the next arg and guess
+ --jobs)
+ if [[ ${#} -gt 1 && ${2} =~ [0-9]+ ]]; then
+ new_makeopts="${new_makeopts+${new_makeopts} }${1} ${2}"
+ shift
+ else
+ # no value means no limit, let's pass a random int
+ new_makeopts=${new_makeopts+${new_makeopts} }${1}=255
+ fi
+ ;;
+ # strip other long options
+ --*)
+ ;;
+ # short option hell
+ -*)
+ local str new_optstr
+ new_optstr=
+ str=${1#-}
+
+ while [[ -n ${str} ]]; do
+ case ${str} in
+ k*)
+ new_optstr=${new_optstr}k
+ ;;
+ # -j needs to come last
+ j)
+ if [[ ${#} -gt 1 && ${2} =~ [0-9]+ ]]; then
+ new_optstr="${new_optstr}j ${2}"
+ shift
+ else
+ new_optstr="${new_optstr}j 255"
+ fi
+ ;;
+ # otherwise, everything after -j is treated as an arg
+ j*)
+ new_optstr=${new_optstr}${str}
+ break
+ ;;
+ esac
+ str=${str#?}
+ done
+
+ if [[ -n ${new_optstr} ]]; then
+ new_makeopts=${new_makeopts+${new_makeopts} }-${new_optstr}
+ fi
+ ;;
+ esac
+ shift
+ done
+
+ set -- ${new_makeopts}
+ export _SCONS_CACHE_SCONSOPTS=${*}
+ debug-print "New SCONSOPTS: [${*}]"
+ echo ${*}
+}
+
+# @FUNCTION: use_scons
+# @USAGE: <use-flag> [var-name] [var-opt-true] [var-opt-false]
+# @DESCRIPTION:
+# Output a SCons parameter with value depending on the USE flag state.
+# If the USE flag is set, output <var-name>=<var-opt-true>; otherwise
+# <var-name>=<var-opt-false>.
+#
+# If <var-name> is omitted, <use-flag> will be used instead. However,
+# if <use-flag> starts with an exclamation mark (!flag), 'no' will be
+# prepended to the name (e.g. noflag).
+#
+# If <var-opt-true> and/or <var-opt-false> are omitted,
+# ${USE_SCONS_TRUE} and/or ${USE_SCONS_FALSE} will be used instead.
+use_scons() {
+ local flag=${1}
+ local varname=${2:-${flag/\!/no}}
+ local vartrue=${3:-${USE_SCONS_TRUE}}
+ local varfalse=${4:-${USE_SCONS_FALSE}}
+
+ debug-print-function ${FUNCNAME} "${@}"
+
+ if [[ ${#} -eq 0 ]]; then
+ eerror "Usage: scons-use <use-flag> [var-name] [var-opt-true] [var-opt-false]"
+ die 'scons-use(): not enough arguments'
+ fi
+
+ if use "${flag}"; then
+ echo "${varname}=${vartrue}"
+ else
+ echo "${varname}=${varfalse}"
+ fi
+}
diff --git a/eclass/tests/scons-utils.sh b/eclass/tests/scons-utils.sh
new file mode 100755
index 000000000000..a45d082875dd
--- /dev/null
+++ b/eclass/tests/scons-utils.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+source tests-common.sh
+
+inherit scons-utils
+
+test-scons_clean_makeopts() {
+ local sconsopts=$(scons_clean_makeopts ${1})
+
+ if [[ ${sconsopts} != ${2-${1}} ]]; then
+ eerror "Self-test failed:"
+ eindent
+ eerror "MAKEOPTS: ${1}"
+ eerror "Expected: ${2-${1}}"
+ eerror "Actual: ${sconsopts}"
+ eoutdent
+ (( ++failed ))
+ return 1
+ fi
+
+ return 0
+}
+
+# jobcount expected for non-specified state
+jc=255
+# failed test counter
+failed=0
+
+ebegin "Testing scons_clean_makeopts()"
+
+# sane MAKEOPTS
+test-scons_clean_makeopts '--jobs=14 -k'
+test-scons_clean_makeopts '--jobs=14 -k'
+test-scons_clean_makeopts '--jobs 15 -k'
+test-scons_clean_makeopts '--jobs=16 --keep-going'
+test-scons_clean_makeopts '-j17 --keep-going'
+test-scons_clean_makeopts '-j 18 --keep-going'
+
+# needing cleaning
+test-scons_clean_makeopts '--jobs -k' "--jobs=${jc} -k"
+test-scons_clean_makeopts '--jobs --keep-going' "--jobs=${jc} --keep-going"
+test-scons_clean_makeopts '-kj' "-kj ${jc}"
+
+# broken by definition (but passed as it breaks make as well)
+test-scons_clean_makeopts '-jk'
+test-scons_clean_makeopts '--jobs=randum'
+test-scons_clean_makeopts '-kjrandum'
+
+# needing stripping
+test-scons_clean_makeopts '--load-average=25 -kj16' '-kj16'
+test-scons_clean_makeopts '--load-average 25 -k -j17' '-k -j17'
+test-scons_clean_makeopts '-j2 HOME=/tmp' '-j2'
+test-scons_clean_makeopts '--jobs funnystuff -k' "--jobs=${jc} -k"
+
+eend ${failed}