123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- # Copyright 1999-2015 Gentoo Foundation
- # Distributed under the terms of the GNU General Public License v2
- # @ECLASS: ghc-package.eclass
- # @MAINTAINER:
- # "Gentoo's Haskell Language team" <haskell@gentoo.org>
- # @AUTHOR:
- # Original Author: Andres Loeh <kosmikus@gentoo.org>
- # @BLURB: This eclass helps with the Glasgow Haskell Compiler's package configuration utility.
- # @DESCRIPTION:
- # Helper eclass to handle ghc installation/upgrade/deinstallation process.
- inherit multiprocessing versionator
- # @FUNCTION: ghc-getghc
- # @DESCRIPTION:
- # returns the name of the ghc executable
- ghc-getghc() {
- type -P ghc
- }
- # @FUNCTION: ghc-getghcpkg
- # @DESCRIPTION:
- # Internal function determines returns the name of the ghc-pkg executable
- ghc-getghcpkg() {
- type -P ghc-pkg
- }
- # @FUNCTION: ghc-getghcpkgbin
- # @DESCRIPTION:
- # returns the name of the ghc-pkg binary (ghc-pkg
- # itself usually is a shell script, and we have to
- # bypass the script under certain circumstances);
- # for Cabal, we add an empty global package config file,
- # because for some reason the global package file
- # must be specified
- ghc-getghcpkgbin() {
- if version_is_at_least "7.9.20141222" "$(ghc-version)"; then
- # ghc-7.10 stopped supporting single-file database
- local empty_db="${T}/empty.conf.d" ghc_pkg="$(ghc-libdir)/bin/ghc-pkg"
- if [[ ! -d ${empty_db} ]]; then
- "${ghc_pkg}" init "${empty_db}" || die "Failed to initialize empty global db"
- fi
- echo "$(ghc-libdir)/bin/ghc-pkg" "--global-package-db=${empty_db}"
- elif version_is_at_least "7.7.20121101" "$(ghc-version)"; then
- # the ghc-pkg executable changed name in ghc 6.10, as it no longer needs
- # the wrapper script with the static flags
- # was moved to bin/ subtree by:
- # http://www.haskell.org/pipermail/cvs-ghc/2012-September/076546.html
- echo '[]' > "${T}/empty.conf"
- echo "$(ghc-libdir)/bin/ghc-pkg" "--global-package-db=${T}/empty.conf"
- elif version_is_at_least "7.5.20120516" "$(ghc-version)"; then
- echo '[]' > "${T}/empty.conf"
- echo "$(ghc-libdir)/ghc-pkg" "--global-package-db=${T}/empty.conf"
- else
- echo '[]' > "${T}/empty.conf"
- echo "$(ghc-libdir)/ghc-pkg" "--global-conf=${T}/empty.conf"
- fi
- }
- # @FUNCTION: ghc-version
- # @DESCRIPTION:
- # returns upstream version of ghc
- # as reported by '--numeric-version'
- # Examples: "7.10.2", "7.9.20141222"
- _GHC_VERSION_CACHE=""
- ghc-version() {
- if [[ -z "${_GHC_VERSION_CACHE}" ]]; then
- _GHC_VERSION_CACHE="$($(ghc-getghc) --numeric-version)"
- fi
- echo "${_GHC_VERSION_CACHE}"
- }
- # @FUNCTION: ghc-pm-version
- # @DESCRIPTION:
- # returns package manager(PM) version of ghc
- # as reported by '$(best_version)'
- # Examples: "PM:7.10.2", "PM:7.10.2_rc1", "PM:7.8.4-r4"
- _GHC_PM_VERSION_CACHE=""
- ghc-pm-version() {
- local pm_ghc_p
- if [[ -z "${_GHC_PM_VERSION_CACHE}" ]]; then
- pm_ghc_p=$(best_version dev-lang/ghc)
- _GHC_PM_VERSION_CACHE="PM:${pm_ghc_p#dev-lang/ghc-}"
- fi
- echo "${_GHC_PM_VERSION_CACHE}"
- }
- # @FUNCTION: ghc-cabal-version
- # @DESCRIPTION:
- # return version of the Cabal library bundled with ghc
- ghc-cabal-version() {
- if version_is_at_least "7.9.20141222" "$(ghc-version)"; then
- # outputs in format: 'version: 1.18.1.5'
- set -- `$(ghc-getghcpkg) --package-db=$(ghc-libdir)/package.conf.d.initial field Cabal version`
- echo "$2"
- else
- local cabal_package=`echo "$(ghc-libdir)"/Cabal-*`
- # /path/to/ghc/Cabal-${VER} -> ${VER}
- echo "${cabal_package/*Cabal-/}"
- fi
- }
- # @FUNCTION: ghc-is-dynamic
- # @DESCRIPTION:
- # checks if ghc is built against dynamic libraries
- # binaries linked against GHC library (and using plugin loading)
- # have to be linked the same way:
- # https://ghc.haskell.org/trac/ghc/ticket/10301
- ghc-is-dynamic() {
- $(ghc-getghc) --info | grep "GHC Dynamic" | grep -q "YES"
- }
- # @FUNCTION: ghc-supports-shared-libraries
- # @DESCRIPTION:
- # checks if ghc is built with support for building
- # shared libraries (aka '-dynamic' option)
- ghc-supports-shared-libraries() {
- $(ghc-getghc) --info | grep "RTS ways" | grep -q "dyn"
- }
- # @FUNCTION: ghc-supports-threaded-runtime
- # @DESCRIPTION:
- # checks if ghc is built with support for threaded
- # runtime (aka '-threaded' option)
- ghc-supports-threaded-runtime() {
- $(ghc-getghc) --info | grep "RTS ways" | grep -q "thr"
- }
- # @FUNCTION: ghc-supports-smp
- # @DESCRIPTION:
- # checks if ghc is built with support for multiple cores runtime
- ghc-supports-smp() {
- $(ghc-getghc) --info | grep "Support SMP" | grep -q "YES"
- }
- # @FUNCTION: ghc-supports-interpreter
- # @DESCRIPTION:
- # checks if ghc has interpreter mode (aka GHCi)
- # It usually means that ghc supports for template haskell.
- ghc-supports-interpreter() {
- $(ghc-getghc) --info | grep "Have interpreter" | grep -q "YES"
- }
- # @FUNCTION: ghc-supports-parallel-make
- # @DESCRIPTION:
- # checks if ghc has support for '--make -j' mode
- # The option was introduced in ghc-7.8-rc1.
- ghc-supports-parallel-make() {
- $(ghc-getghc) --info | grep "Support parallel --make" | grep -q "YES"
- }
- # @FUNCTION: ghc-extractportageversion
- # @DESCRIPTION:
- # extract the version of a portage-installed package
- ghc-extractportageversion() {
- local pkg
- local version
- pkg="$(best_version $1)"
- version="${pkg#$1-}"
- version="${version%-r*}"
- version="${version%_pre*}"
- echo "${version}"
- }
- # @FUNCTION: ghc-libdir
- # @DESCRIPTION:
- # returns the library directory
- _GHC_LIBDIR_CACHE=""
- ghc-libdir() {
- if [[ -z "${_GHC_LIBDIR_CACHE}" ]]; then
- _GHC_LIBDIR_CACHE="$($(ghc-getghc) --print-libdir)"
- fi
- echo "${_GHC_LIBDIR_CACHE}"
- }
- # @FUNCTION: ghc-make-args
- # @DESCRIPTION:
- # Returns default arguments passed along 'ghc --make'
- # build mode. Used mainly to enable parallel build mode.
- ghc-make-args() {
- local ghc_make_args=()
- # parallel on all available cores
- if ghc-supports-smp && ghc-supports-parallel-make; then
- # It should have been just -j$(makeopts_jobs)
- # but GHC does not yet have nice defaults:
- # https://ghc.haskell.org/trac/ghc/ticket/9221#comment:57
- # SMP is a requirement for parallel GC's gen0
- # 'qb' balancing.
- echo "-j$(makeopts_jobs) +RTS -A256M -qb0 -RTS"
- ghc_make_args=()
- fi
- echo "${ghc_make_args[@]}"
- }
- # @FUNCTION: ghc-confdir
- # @DESCRIPTION:
- # returns the (Gentoo) library configuration directory, we
- # store here a hint for 'haskell-updater' about packages
- # installed for old ghc versions and current ones.
- ghc-confdir() {
- echo "$(ghc-libdir)/gentoo"
- }
- # @FUNCTION: ghc-package-db
- # @DESCRIPTION:
- # returns the global package database directory
- ghc-package-db() {
- echo "$(ghc-libdir)/package.conf.d"
- }
- # @FUNCTION: ghc-localpkgconfd
- # @DESCRIPTION:
- # returns the name of the local (package-specific)
- # package configuration file
- ghc-localpkgconfd() {
- echo "${PF}.conf.d"
- }
- # @FUNCTION: ghc-package-exists
- # @DESCRIPTION:
- # tests if a ghc package exists
- ghc-package-exists() {
- $(ghc-getghcpkg) describe "$1" > /dev/null 2>&1
- }
- # @FUNCTION: check-for-collisions
- # @DESCRIPTION:
- # makes sure no packages
- # have the same version as initial package setup
- check-for-collisions() {
- local localpkgconf=$1
- local checked_pkg
- local initial_pkg_db="$(ghc-libdir)/package.conf.d.initial"
- for checked_pkg in `$(ghc-getghcpkgbin) -f "${localpkgconf}" list --simple-output`
- do
- # should return empty output
- local collided=`$(ghc-getghcpkgbin) -f ${initial_pkg_db} list --simple-output "${checked_pkg}"`
- if [[ -n ${collided} ]]; then
- eerror "Cabal package '${checked_pkg}' is shipped with '$(ghc-pm-version)' ('$(ghc-version)')."
- eerror "Ebuild author forgot an entry in CABAL_CORE_LIB_GHC_PV='${CABAL_CORE_LIB_GHC_PV}'."
- eerror "Found in ${initial_pkg_db}."
- die
- fi
- done
- }
- # @FUNCTION: ghc-install-pkg
- # @DESCRIPTION:
- # moves the local (package-specific) package configuration
- # file to its final destination
- ghc-install-pkg() {
- local pkg_config_file=$1
- local localpkgconf="${T}/$(ghc-localpkgconfd)"
- local pkg_path pkg pkg_db="${D}/$(ghc-package-db)" hint_db="${D}/$(ghc-confdir)"
- $(ghc-getghcpkgbin) init "${localpkgconf}" || die "Failed to initialize empty local db"
- $(ghc-getghcpkgbin) -f "${localpkgconf}" update - --force \
- < "${pkg_config_file}" || die "failed to register ${pkg}"
- check-for-collisions "${localpkgconf}"
- mkdir -p "${pkg_db}" || die
- for pkg_path in "${localpkgconf}"/*.conf; do
- pkg=$(basename "${pkg_path}")
- cp "${pkg_path}" "${pkg_db}/${pkg}" || die
- done
- mkdir -p "${hint_db}" || die
- cp "${pkg_config_file}" "${hint_db}/${PF}.conf" || die
- chmod 0644 "${hint_db}/${PF}.conf" || die
- }
- # @FUNCTION: ghc-recache-db
- # @DESCRIPTION:
- # updates 'package.cache' binary cacne for registered '*.conf'
- # packages
- ghc-recache-db() {
- einfo "Recaching GHC package DB"
- $(ghc-getghcpkg) recache
- }
- # @FUNCTION: ghc-register-pkg
- # @DESCRIPTION:
- # registers all packages in the local (package-specific)
- # package configuration file
- ghc-register-pkg() {
- ghc-recache-db
- }
- # @FUNCTION: ghc-reregister
- # @DESCRIPTION:
- # re-adds all available .conf files to the global
- # package conf file, to be used on a ghc reinstallation
- ghc-reregister() {
- ghc-recache-db
- }
- # @FUNCTION: ghc-unregister-pkg
- # @DESCRIPTION:
- # unregisters a package configuration file
- ghc-unregister-pkg() {
- ghc-recache-db
- }
- # @FUNCTION: ghc-pkgdeps
- # @DESCRIPTION:
- # exported function: loads a package dependency in a form
- # cabal_package version
- ghc-pkgdeps() {
- echo $($(ghc-getghcpkg) describe "${1}") \
- | sed \
- -e '/depends/,/^.*:/ !d' \
- -e 's/\(.*\)-\(.*\)-\(.*\)/\1 \2/' \
- -e 's/^.*://g'
- }
- # @FUNCTION: ghc-package_pkg_postinst
- # @DESCRIPTION:
- # updates package.cache after package install
- ghc-package_pkg_postinst() {
- ghc-recache-db
- }
- # @FUNCTION: ghc-package_pkg_prerm
- # @DESCRIPTION:
- # updates package.cache after package deinstall
- ghc-package_pkg_prerm() {
- ewarn "ghc-package.eclass: 'ghc-package_pkg_prerm()' is a noop"
- ewarn "ghc-package.eclass: consider 'haskell-cabal_pkg_postrm()' instead"
- }
- # @FUNCTION: ghc-package_pkg_postrm
- # @DESCRIPTION:
- # updates package.cache after package deinstall
- ghc-package_pkg_postrm() {
- ghc-recache-db
- }
|