# Copyright 1999-2010 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ # @ECLASS: scons.eclass # @MAINTAINER: # gentoo@... # @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. # -- public variables -- # @ECLASS-VARIABLE: SCONS_MIN_VERSION # @DESCRIPTION: # The minimal version of SCons required for the build to work. # @DEFAULT-UNSET # @ECLASS-VARIABLE: SCONSOPTS # @DESCRIPTION: # The default set of options to pass to scons. Similar to MAKEOPTS, # supposed to be set in make.conf. If unset, will be generated from # MAKEOPTS. # @DEFAULT-UNSET # @ECLASS-VARIABLE: EXTRA_ESCONS # @DESCRIPTION: # The additional parameters to pass to SCons whenever escons() is used. # @DEFAULT-UNSET # @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 # -- exported phase functions -- case "${EAPI:-0}" in 1|0) EXPORT_FUNCTIONS src_compile;; *) EXPORT_FUNCTIONS src_configure src_compile;; esac # @FUNCTION: scons_src_configure # @DESCRIPTION: # A blank src_configure() for SCons packages not using explicit # configure phase. scons_src_configure() { debug-print-function ${FUNCNAME} "${@}" } # @FUNCTION: scons_src_compile # @DESCRIPTION: # The exported src_compile() implementation. Simply calls escons(). scons_src_compile() { debug-print-function ${FUNCNAME} "${@}" escons || die 'escons failed.' } # -- 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_, create them from MAKEOPTS if [[ -n ${SCONSOPTS+1} ]]; then export SCONSOPTS=$(scons_clean_makeopts) fi set -- scons ${SCONSOPTS} ${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 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 debug-print "New SCONSOPTS: ${new_makeopts}" echo ${new_makeopts} } # @FUNCTION: use_scons # @USAGE: [var-name] [var-opt-true] [var-opt-false] # @DESCRIPTION: # Output an SCons parameter with value depending on the USE flag state. # If the USE flag is set, output =; otherwise # =. # # If is not set, will be used instead. # If or is unset, USE_SCONS_TRUE # or USE_SCONS_FALSE will be used instead. use_scons() { local flag=${1} local varname=${2:-${flag#!}} local vartrue=${3:-${USE_SCONS_TRUE}} local varfalse=${4:-${USE_SCONS_FALSE}} debug-print-function ${FUNCNAME} "${@}" if [[ ${#} -eq 0 ]]; then eerror "Usage: scons-use [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 } # -- self-tests -- _scons_clean_makeopts_perform_test() { local sconsopts=$(scons_clean_makeopts ${1}) if [[ ${sconsopts} != ${2-${1}} ]]; then cat >&2 <<_EOF_ Self-test failed: Input string: ${1} Output string: ${sconsopts} Expected: ${2-${1}} _EOF_ fi } # Perform a self-test on scons-clean-makeopts. _scons_clean_makeopts_tests() { # jobcount expected for non-specified state local jc=255 # sane MAKEOPTS _scons_clean_makeopts_perform_test '--jobs=14 -k' _scons_clean_makeopts_perform_test '--jobs=14 -k' _scons_clean_makeopts_perform_test '--jobs 15 -k' _scons_clean_makeopts_perform_test '--jobs=16 --keep-going' _scons_clean_makeopts_perform_test '-j17 --keep-going' _scons_clean_makeopts_perform_test '-j 18 --keep-going' # needing cleaning _scons_clean_makeopts_perform_test '--jobs -k' "--jobs=${jc} -k" _scons_clean_makeopts_perform_test '--jobs --keep-going' "--jobs=${jc} --keep-going" _scons_clean_makeopts_perform_test '-kj' "-kj ${jc}" # broken by definition (but passed as it breaks make as well) _scons_clean_makeopts_perform_test '-jk' _scons_clean_makeopts_perform_test '--jobs=randum' _scons_clean_makeopts_perform_test '-kjrandum' # needing stripping _scons_clean_makeopts_perform_test '--load-average=25 -kj16' '-kj16' _scons_clean_makeopts_perform_test '--load-average 25 -k -j17' '-k -j17' _scons_clean_makeopts_perform_test '-j2 HOME=/tmp' '-j2' _scons_clean_makeopts_perform_test '--jobs funnystuff -k' "--jobs=${jc} -k" }