# Copyright 1999-2014 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ # @ECLASS: multilib-minimal.eclass # @MAINTAINER: # Julian Ospald # @AUTHOR: # Julian Ospald # Michał Górny # Greg Turner # @BLURB: wrapper for multilib builds providing convenient multilib_src_* functions # @DESCRIPTION: # multilib-minimal implements src_configure, src_compile, src_test # and src_install, and invokes callbacks which may be used by multi-abi # ebuilds and eclasses to cleanly separate per-ABI and global logic # within their implementations. It also provides logic to ensure that # ABI's do not scribble over each other's header files during installation. # # To use multilib-minimal.eclass, inherit from it normally and implement # functions named multilib_ (i.e.: multilib_src_install) containing # code which must run once for each ABI. multilib-minimal will invoke your # callback repeatedly and automatically, once for each active ABI, # with essential abi-specific settings for variables such as CFLAGS # automatically exported. # # Be advised that, for now at least, some features of # toolchain-funcs.eclass, specifically, those that # retrieve those same variables, will not work as expected, as this # eclass knows nothing about multilib-minimal and will return values # suitable only for the native ABI. # # A simple workaround for this limitation is to check if a variable is # already defined before querying toolchain-funcs. For example: # # @CODE@ # local CC=${CC:-$(tc-getCC)} # @CODE # # It is also important to make sure that your ebuild or eclass's dependencies # correctly reflect build- and run-time dependencies of each active ABI. # This can be simplified by using the ${MULTILIB_USEDEP} variable during # construction of *DEPEND variables. Note that not all dependencies # will require this; a judgement call will need to be made for each # dependency when porting existing ebuilds. See: # @CODE@ # http://devmanual.gentoo.org/eclass-reference/multilib-build.eclass/index.html # @CODE@ # for more information. # # Another snag you may encounter is that, in many circumstances, it is possible # for variables to flow between multilib_ functions. This is because, # unless you parallelize the phase in question, no subshell is utilized. # Extreme care must sometimes be taken to ensure that different ABI's don't # trample each other's variables. # # A reasonable precaution against this type of problem would be to localize # certian variables to the multilib_ function, for example: # # @CODE@ # multilib_src_configure() { # local CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" # local FFLAGS="${FFLAGS}" FCFLAGS="${FCFLAGS}" # if [[ ${CHOST} == *x86_64* ]] ; then # append-flags -foo_flag -bar_flag # fi # @CODE@ # # However, this approach can create subtly confusing behavior. When porting # traditional phase-function-based code to multilib minimal, keep an eye out # for code that assumes variables defined in a prior phase function will persist # in subsequent phases. Depending on a number of factors, this may not # be the case -- it certainly will not, if you have localized variables as above. # # Eventually, a feature allowing reliable automatic variable persistence across # multilib_ functions may be added, so, for the moment, it is best to # avoid any assumption about variable persistence, for example, by isolating # variable setup code in a convenience function which is invoked at the outset # of each multilib_ function, or, where possible, by refactoring code # to avoid the use of persistent variables entirely. # # If you want to use in-source builds, then you must run # multilib_copy_sources at the end of src_prepare. # Also make sure to correctly set ECONF_SOURCE, i.e., # # @CODE@ # ECONF_SOURCE=${S} # @CODE@ # # as out-of-tree builds will not be building in the same directory as # the configure script. # # Non-abi-specific installation functionality is accomodated by an # additional 'bonus' callback: multilib_src_install_all. # multilib_src_install_all is called once only, after the per-ABI # multilib_src_install functions complete, with BUILD_DIR and # the current working directory unchanged from that of the calling # scope. It is also perfectly acceptable -- and, indeed, slightly # more powerful, to implement src_install, and call # multilib-minimal_src_install from there -- the two approaches # are roughly identical. # # EAPI >= 4 is required by multilib minimial, as without it, # the ${MULTILIB_USEDEP} variable cannot be correctly implemented. # # Note: always put multilib-minimal last on the inherits list, # unless you have a really, really good reason not to. No magic # will happen if some other ebuild overrides multilib-minimal's # phase functions and that can result in a big, ugly mess for your # ebuild. # EAPI=4 is required for meaningful MULTILIB_USEDEP. case ${EAPI:-0} in 4|5) ;; *) die "EAPI=${EAPI} is not supported" ;; esac # @ECLASS-VARIABLE: MULTILIB_PARALLEL_PHASES # @DEFAULT-UNSET # @DESCRIPTION: # multilib-minimal.eclass consumers may set this to a string containing # a space-separated list of phase-function names, like so: # # @CODE@ # MULTILIB_PARALLEL_PHASES="src_configure src_test" # @CODE@ # # For each (supported) phase-function name in the list, the corresponding # multilib-minimal_ phase function will execute in parallel, in # the sense that, within limits (set by multiprocessing.eclass) the # multilib_ function invocations (or, if none is present, the # built-in default implementation) for each ABI will run simultaneously. # # Any phase-function-names not specified are executed serially, with the # native ABI coming last. # # It is OK to add extra "bonus" whitespace or duplicated values. # Changes take effect immediately, so it may be set before or after # inheriting multilib-minimal, or even during execution of a phase function # (but not in parallelized multilib_ functions; see below). # # By default, MULTILIB_PARALLEL_PHASES is empty. Consuming eclasses could # override this default by setting a new default before the inherits clause. # For example, # # @CODE # : {MULTILIB_PARALLEL_PHASES:="src_configure"} # inherit multilib-minimal # @CODE # # would create a default behavior of parallel src_configure. The question # of whether, in practice, eclasses ever should do so is potentially # complicated; you'll have to figure that out for yourself. # # Supported phase-function-names are: src_configure, src_compile, and src_test. # All other values are silently ignored. # # Note that parallel execution can lead to ugly -- and sometimes very, very ugly -- # console output at build-time. Consumers of multilib-minimal.eclass # may wish to consider activating less verbose build-time output modes, if they are # readily available, to mitigate this effect, although doing so goes against a # long-standing Gentoo tradition and might make debugging a hassle for bugzilla # and IRC participants, so use your best judgement. # # A handy per-ABI log is kept in ${T}/build-${ABI}.log by multibuild.eclass. # Debugging and bug-reporting may also benefit (unless your bug specifically # pertains to parallelization) from setting MAKEOPTS=-j1, which will prevent # parallelization entirely. # @ECLASS-VARIABLE: MULTILIB_INSECURE_INSTALL # @DEFAULT-UNSET # @DESCRIPTION: # If set to a nonempty value, multilib-minimal_src_install will not perform # automatic checking of headers for inter-ABI conflicts, nor will it automate # wrapping of header files. Instead, multilib_src_install pseudophases will # run without any special protection and the MULTILIB_WRAPPED_HEADERS array # will be ignored. # See: # @CODE@ # http://devmanual.gentoo.org/eclass-reference/multilib-build.eclass/index.html # @CODE@ # (or the multilib-build.eclass source itself) for further information about this # feature. inherit eutils multilib-build EXPORT_FUNCTIONS src_configure src_compile src_test src_install multilib-minimal_src_configure() { debug-print-function ${FUNCNAME} "$@" multilib-minimal_abi_src_configure() { debug-print-function ${FUNCNAME} "$@" mkdir -p "${BUILD_DIR}" || die pushd "${BUILD_DIR}" >/dev/null || die if declare -f multilib_src_configure >/dev/null ; then multilib_src_configure "$@" else # like default_src_configure but pass arguments if [[ -x ${ECONF_SOURCE:-.}/configure ]] ; then econf "$@" fi fi popd >/dev/null || die } if has src_configure ${MULTILIB_PARALLEL_PHASES} ; then multilib_parallel_foreach_abi multilib-minimal_abi_src_configure "$@" else multilib_foreach_abi multilib-minimal_abi_src_configure "$@" fi } multilib-minimal_src_compile() { debug-print-function ${FUNCNAME} "$@" multilib-minimal_abi_src_compile() { debug-print-function ${FUNCNAME} "$@" pushd "${BUILD_DIR}" >/dev/null || die if declare -f multilib_src_compile >/dev/null ; then multilib_src_compile "$@" else # like __eapi2_src_compile, but with argument passing... if [ -f Makefile ] || [ -f GNUmakefile ] || [ -f makefile ]; then emake "$@" || die "emake failed" fi fi popd >/dev/null || die } if has src_compile ${MULTILIB_PARALLEL_PHASES} ; then multilib_parallel_foreach_abi multilib-minimal_abi_src_compile "$@" else multilib_foreach_abi multilib-minimal_abi_src_compile "$@" fi } multilib-minimal_src_test() { debug-print-function ${FUNCNAME} "$@" multilib-minimal_abi_src_test() { debug-print-function ${FUNCNAME} "$@" pushd "${BUILD_DIR}" >/dev/null || die if declare -f multilib_src_test >/dev/null ; then multilib_src_test else default_src_test fi popd >/dev/null || die } if has src_test ${MULTILIB_PARALLEL_PHASES} ; then multilib_parallel_foreach_abi multilib-minimal_abi_src_test else multilib_foreach_abi multilib-minimal_abi_src_test fi } multilib-minimal_src_install() { debug-print-function ${FUNCNAME} "$@" multilib-minimal_abi_src_install() { debug-print-function ${FUNCNAME} "$@" pushd "${BUILD_DIR}" >/dev/null || die if declare -f multilib_src_install >/dev/null ; then multilib_src_install "$@" else # default_src_install will not work here as it will # break handling of DOCS wrt #468092 # so we split up the emake and doc-install part # this is synced with __eapi4_src_install if [[ -f Makefile || -f GNUmakefile || -f makefile ]] ; then emake DESTDIR="${D}" install "$@" fi fi # Do multilib magic only when >1 ABI is used and # MULTILIB_INSECURE_INSTALL is not set if [[ ${#MULTIBUILD_VARIANTS[@]} -gt 1 && \ -z ${MULTILIB_INSECURE_INSTALL} ]]; then multilib_prepare_wrappers multilib_check_headers fi popd >/dev/null || die } multilib_foreach_abi multilib-minimal_abi_src_install "$@" [[ ${MULTILIB_INSECURE_INSTALL} ]] || multilib_install_wrappers if declare -f multilib_src_install_all >/dev/null ; then multilib_src_install_all else einstalldocs fi }