diff options
author | Gregory M. Turner <gmt@be-evil.net> | 2013-10-08 20:59:02 -0700 |
---|---|---|
committer | Gregory M. Turner <gmt@be-evil.net> | 2013-10-08 21:00:28 -0700 |
commit | 12461645a369cf8615077626c4d5b8f88eab0cc1 (patch) | |
tree | 7a0021b83e4723829cfc6b21b2f56115cd41fbfd /eclass/gtk-doc.eclass | |
parent | eclass/cmake-utils: Where applicable, preserve API result codes across ehook ... (diff) | |
download | gmt-12461645a369cf8615077626c4d5b8f88eab0cc1.tar.gz gmt-12461645a369cf8615077626c4d5b8f88eab0cc1.tar.bz2 gmt-12461645a369cf8615077626c4d5b8f88eab0cc1.zip |
eclass: gtk-doc.eclass: New eclass to inject out-of-tree compilation support into gtk-doc autotools files.
Signed-off-by: Gregory M. Turner <gmt@be-evil.net>
Signed-off-by: Gregory M. Turner <gmt@be-evil.net>
Diffstat (limited to 'eclass/gtk-doc.eclass')
-rw-r--r-- | eclass/gtk-doc.eclass | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/eclass/gtk-doc.eclass b/eclass/gtk-doc.eclass new file mode 100644 index 0000000..e5296a3 --- /dev/null +++ b/eclass/gtk-doc.eclass @@ -0,0 +1,330 @@ +# Copyright 1999-2013 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +# @ECLASS: gtk-doc.eclass +# @MAINTAINER: +# Greg Turner <gmt@be-evil.net> +# @BLURB: Gentoo gtk-doc enhancements +# @DESCRIPTION: +# gtk-doc.eclass automatically enhances gtk-doc for Gentoo builds +# by applying patches to gtk-doc.make before/after src_prepare. The +# patches are applied via the gtk_doc_enhance hook which will +# be fired automatically so long as gtk-doc_src_prepare is +# invoked, or any one of the following hooks are fired: +# autotools-utils-{pre,post}_src_prepare, cmake-utils-{pre,post}_src_prepare, +# qt4-build-multilib-{pre,post}_src_prepare. +# +# The nature of the enhancement is, thus-far, only to fix the +# code for automatically installing pre-generated html directories +# when disable-gtk-doc is supplied to configure. This means +# that if you build in-tree, there is probably no reason to +# use this eclass; however, it should be harmless to do so anyhow. +# +# NB: There is, thus far, no reason to believe that the upstream +# gtk-doc maintainers wouldn't be able to merge patches equivalent +# to those applied by this eclass. Failing to install the +# prebuilt documentation when building out-of-tree is almost certainly +# a bug or at best a rather pointless limitation of gtk-doc.make. +# See (FIXME: reference to gtk-doc bug report once filed) +# +# During automatic processing, only gtk-doc.make is patched during +# pre_src_prepare hook processing, and Makefile.in files are +# patched afterward if neccesary. This should help avoid triggering +# maintainer-mode problems in cases where eautoreconf is used. +# However, if eautoreconf is not used, and the Makefile.in files +# are patched, then it is quite probable that maintainer-mode will +# be triggered by this patching, if it is left enabled. +# Consumers of this eclass will have to figure out how to solve this +# problem on their own, no mechanism exists here to prevent it. + +# @ECLASS-VARIABLE: GTK_DOC_NO_AUTOMATIC +# @DEFAULT_UNSET +# @DESCRIPTION: +# If set to a nonempty value, no modifications of any kind +# will be made automatically by gtk-doc.eclass using the ehooks. +# However, if gtk-doc_patch_gtk_doc_make or gtk-doc_patch_autotools_files +# are invoked, they will still patch their respective target files + +# @ECLASS-VARIABLE: GTK_DOC_AUTO_SRC_PREPARE +# @DEFAULT_UNSET +# @DESCRIPTION: +# If set to a nonempty value, the src_prepare phase will be taken +# over by gtk-doc_src_prepare. Since this would uninstall any +# previously installed src_prepare phase function, possibly +# invonveniencing ebuild and eclass authors, it is not done +# by default. + +case "${EAPI:-0}" in + 2|3|4|5) + [[ -n ${GTK_DOC_AUTO_SRC_PREPARE} ]] && \ + EXPORT_FUNCTIONS src_prepare + ;; + *) die "EAPI=${EAPI} is not supported" ;; +esac + +if [[ ${___ECLASS_ONCE_GTK_DOC} != "recur -_+^+_- spank" ]] ; then +___ECLASS_ONCE_GTK_DOC="recur -_+^+_- spank" + +inherit ehooker + +# stores an array of previosly processed gtk-doc.make files +# so that we can respond appropriately to gtkdocize invocations +# the file is only reprocessed if it was processed once already. +declare -a _gtk_doc_patched_gtk_doc_make_files + +# @FUNCTION: _gtk_doc_install_src_prepare_notify_ehooks +# @INTERNAL +# @USAGE: +# @DESCRIPTION: +# Installs listners for various ehooks. Always runs automatically +# upon inheritance of gtk-doc.eclass +_gtk_doc_install_src_prepare_notify_ehooks() { + debug-print-function "${FUNCNAME}" "$@" + local prefix prepost + for prefix in autotools-utils cmake-utils qt4-build-multilib ; do + for prepost in pre post ; do + ehook ${prefix}-${prepost}_src_prepare _gtk_doc_${prepost}_src_prepare_notify + done + done +} + +_gtk_doc_install_src_prepare_notify_ehooks + +# @FUNCTION: gtk-doc_src_prepare +# @USAGE: +# @DESCRIPTION: +# src_prepare phase func for gtk-doc. Not wired up unless +# GTK_DOC_AUTO_SRC_PREPARE is nonempty upon gtk-doc inheritance +# Sends internal notifications and invokes default_src_prepare. +gtk-doc_src_prepare() { + debug-print-function "${FUNCNAME}" "$@" + _gtk_doc_pre_src_prepare_notify + default + local result=$? + _gtk_doc_post_src_prepare_notify + return $result +} + +# @FUNCTION: _gtk_doc_pre_src_prepare_notify +# @INTERNAL +# @USAGE: +# @DESCRIPTION: +# ehook listener function for various ehooks indiciating that a +# src_prepare phase is about to begin. gtk-doc.eclass takes +# this opportunity to dink around with gtk-doc.make such that +# if eautoreconf is run, gtk-doc-generating Makefile.in's will +# be generated with the patched logic to support out-of-tree building +_gtk_doc_pre_src_prepare_notify() { + debug-print-function "${FUNCNAME}" "$@" + [[ -n ${GTK_DOC_NO_AUTOMATIC} ]] && return 0 + # if "${S}" doesn't exist then who knows what the hell we should do... + if [[ -d "${S}" ]] ; then + gtk-doc_patch_gtk_doc_make "${S}/gtk-doc.make" + fi + return 0 +} + +# @FUNCTION: _gtk_doc_post_src_prepare_notify +# @INTERNAL +# @USAGE: +# @DESCRIPTION: +# ehook listener function for various ehooks indiciating that a +# src_prepare phase has just completed. gtk-doc.eclass takes this +# opportunity to ensure that all patches relevant to out-of-tree +# build support have been applied to various files in "${S}". +_gtk_doc_post_src_prepare_notify() { + debug-print-function "${FUNCNAME}" "$@" + [[ -n ${GTK_DOC_NO_AUTOMATIC} ]] && return 0 + + # if "${S}" doesn't exist then who knows what the hell we should do... + if [[ -d "${S}" ]] ; then + # just in case gtkdocize got called somehow and we missed it. + gtk-doc_patch_gtk_doc_make "${S}/gtk-doc.make" + + gtk-doc_patch_autotools_files "${S}" + fi + + return 0 +} + +# egtkdocize will undo our changes, so listen for that and reapply +# patches any time this happens. +ehook autotools-post_egtkdocize _gtk_doc_post_egtkdocize_notify + +# @FUNCTION: _gtk_doc_post_egtkdocize_notify +# @INTERNAL +# @USAGE: +# @DESCRIPTION: +# Automagically installed autotools-post_egtkdocize ehook listener. +# If gtkdocize may have removed gtk-doc.make patches after they were +# applied, by gtk-doc.eclass, re-apply them -- otherwise, do nothing. +_gtk_doc_post_egtkdocize_notify() { + debug-print-function "${FUNCNAME}" "$@" + + [[ -f gtk-doc.make ]] || return 0 + local f="$(pwd)/gtk-doc.make" + if has "${f}" "${_gtk_doc_patched_gtk_doc_make_files[@]}" ; then + gtk-doc_patch_gtk_doc_make "${f}" + fi + return 0 +} + +# @FUNCTION: gtk-doc_patch_gtk_doc_make +# @USAGE: [<gtk-doc.make file>] +# @DESCRIPTION: +# Analyses gtk-doc.make (or a similar, but differently named file) +# and, if needed, patches the file to support out-of-tree building. +# Memorizes that the patch was installed, so that future calls to +# egtkdocize in autotools.eclass will not overwrite the patches +# (the patches are re-applied in this case, when the +# autotools-post_egtkdocize ehook is fired) +gtk-doc_patch_gtk_doc_make() { + debug-print-function "${FUNCNAME}" "$@" + + [[ $# -gt 1 ]] && die "Too many arguments" + + local _gtk_doc_make_file + if [[ $# -eq 1 ]] ; then + _gtk_doc_make_file="$1" + else + _gtk_doc_make_file="${S}"/gtk-doc.make + fi + + [[ ${_gtk_doc_make_file} == /* ]] || die "absolute path not supplied/determined" + + [[ -f "${_gtk_doc_make_file}" ]] && \ + _do_gtk_doc_make_patch "${_gtk_doc_make_file}" + + return 0 +} + +# @FUNCTION: gtk-doc_patch_gtk_doc_make +# @INTERNAL +# @USAGE: <gtk-doc.make file> +# @DESCRIPTION: +# patch file if neccesary and ensure it's represented in +# _gtk_doc_patched_gtk_doc_make_files +_do_gtk_doc_make_patch() { + debug-print-function "${FUNCNAME}" "$@" + _do_gtk_doc_patch_file "$1" --gtkdocmake + has "$1" "${_gtk_doc_patched_gtk_doc_make_files[@]}" || \ + _gtk_doc_patched_gtk_doc_make_files+=("$1") + return 0 +} + +# @FUNCTION: gtk-doc_patch_autotools_files +# @INTERNAL +# @USAGE: [list-of-directories] +# @DESCRIPTION: +# In each of the provided directories and all of its subdirectories, +# patch each Makefile.in file (if neccesary) with changes corresponding +# to the patches in gtk-doc.make +gtk-doc_patch_autotools_files() { + debug-print-function "${FUNCNAME}" "$@" + + declare -a dirs + if [[ $# -gt 0 ]] ; then + dirs=("$@") + else + dirs=( "${S}" ) + fi + + local f + while read f ; do + _do_gtk_doc_patch_file "${f}" --makefilein + done < <( + local d + for d in "${dirs[@]}" ; do + pushd "${d}" >/dev/null || die "cannot chdir to \"${d}\" for autotools files processing" + d="$(pwd)" + popd >/dev/null || die + # Serious brute-force approach here... + find "${d}" -type f -name 'Makefile.in' -print + done + ) +} + +# @FUNCTION: _do_gtk_doc_patch_file +# @INTERNAL +# @USAGE: <file-name> <--gtkdocmake|--makefilein> +# @DESCRIPTION: +# Analyze the provided file and, if out-of-tree build patches +# have not been applied, apply them. +_do_gtk_doc_patch_file() { + debug-print-function "${FUNCNAME}" "$@" + + [[ $# -eq 2 ]] || die "_do_gtk_doc_patch_file: $# arguments are not 2" + local f="$1" + local is_gtk_doc_make=no + if [[ $2 == --gtkdocmake ]] ; then + is_gtk_doc_make=yes + elif [[ $2 != --makefilein ]] ; then + die "invalid second argument to _do_gtk_doc_patch_file: \"$2\"" + fi + [[ -f "${f}" ]] || die "no such file as \"${f}\"" + + local sedscript='/^\t\(@\|(\)installfiles=`echo \$(builddir)\/html/,' + sedscript="${sedscript}"'/^[[:space:]]*\((which gtkdoc-rebase\|\$(GTKDOC_REBASE)\)/' + sedscript="${sedscript}"' s|(builddir)|(installhtmlfromdir)|g' + + # slurp entire file into buffer so we can s/// first pattern occurence only + local sedscript2=':a;$!{N;ba};' + if [[ ${is_gtk_doc_make} == yes ]] ; then + sedscript2="${sedscript2}"'s/\nif ENABLE_GTK_DOC/' + sedscript2="${sedscript2}"'\nif ENABLE_GTK_DOC\n' + sedscript2="${sedscript2}"'installhtmlfromdir=$(builddir)\n' + sedscript2="${sedscript2}"'else\n' + sedscript2="${sedscript2}"'installhtmlfromdir=$(srcdir)\n' + sedscript2="${sedscript2}"'endif&/' + else + sedscript2="${sedscript2}"'s/\n@ENABLE_GTK_DOC_\(TRUE\|FALSE\)@/' + sedscript2="${sedscript2}"'\n@ENABLE_GTK_DOC_FALSE@installhtmlfromdir = $(srcdir)\n' + sedscript2="${sedscript2}"'@ENABLE_GTK_DOC_TRUE@installhtmlfromdir = $(builddir)&/' + fi + + local orig_file_contents=$(cat "${f}") + # basic recipe: apply sedscript; if anything changed, apply sedscript2 + # as well, and finally, announce what happened via einfo + sed -e "${sedscript}" -i "${f}" || die + local new_file_contents=$(cat "${f}") + if [[ "${orig_file_contents}" != "${new_file_contents}" ]] ; then + sed -e "${sedscript2}" -i "${f}" || die + new_file_contents=$(cat "${f}") + einfo "gtk-doc: modified \"${f}\" for out-of-tree build support" + if [[ ${ECLASS_DEBUG_OUTPUT} == on ]] ; then + debug-print "${FUNCNAME}: ==== ${f} changes injected ====" + local aline + while IFS= read -r aline ; do + debug-print "${FUNCNAME}: ${aline}" + done < <( diff -u <( echo "${orig_file_contents}" ) <( echo "${new_file_contents}" ) ; echo ) + fi + fi + return 0 +} + +# @FUNCTION: gtk-doc_do_patches +# @USAGE: [list-of-directories] +# @DESCRIPTION: +# Within the provided list of directories (or "${S}", if none +# are provided), execute any patching neccesary for gtk-doc to +# support out-of-tree builds. +gtk-doc_do_patches() { + debug-print-function "${FUNCNAME}" "$@" + local srcdir + declare -a srcdirs + if [[ -n "$*" ]] ; then + srcdirs=( "$@" ) + else + srcdirs=( "${S}" ) + fi + for srcdir in "${srcdirs[@]}" ; do + pushd "${srcdir}" >/dev/null || die "unable to cd to \"${srcdir}\"" + gtk-doc_patch_gtk_doc_make "$(pwd)"/gtk-doc.make + gtk-doc_patch_autotools_files "$(pwd)" + popd >/dev/null || die + done +} + +fi # ___ECLASS_ONCE_GTK_DOC + |