aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory M. Turner <gmt@be-evil.net>2013-10-08 20:59:02 -0700
committerGregory M. Turner <gmt@be-evil.net>2013-10-08 21:00:28 -0700
commit12461645a369cf8615077626c4d5b8f88eab0cc1 (patch)
tree7a0021b83e4723829cfc6b21b2f56115cd41fbfd /eclass/gtk-doc.eclass
parenteclass/cmake-utils: Where applicable, preserve API result codes across ehook ... (diff)
downloadgmt-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.eclass330
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
+