1 # Copyright 1999-2018 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
4 # @ECLASS: autotools.eclass
6 # base-system@gentoo.org
7 # @BLURB: Regenerates auto* build scripts
9 # This eclass is for safely handling autotooled software packages that need to
10 # regenerate their build scripts. All functions will abort in case of errors.
12 # Note: We require GNU m4, as does autoconf. So feel free to use any features
13 # from the GNU version of m4 without worrying about other variants (i.e. BSD).
15 if [[ ${__AUTOTOOLS_AUTO_DEPEND+set} == "set" ]] ; then
16 # See if we were included already, but someone changed the value
17 # of AUTOTOOLS_AUTO_DEPEND on us. We could reload the entire
18 # eclass at that point, but that adds overhead, and it's trivial
19 # to re-order inherit in eclasses/ebuilds instead. #409611
20 if [[ ${__AUTOTOOLS_AUTO_DEPEND} != ${AUTOTOOLS_AUTO_DEPEND} ]] ; then
21 die "AUTOTOOLS_AUTO_DEPEND changed value between inherits; please inherit autotools.eclass first! ${__AUTOTOOLS_AUTO_DEPEND} -> ${AUTOTOOLS_AUTO_DEPEND}"
25 if [[ -z ${_AUTOTOOLS_ECLASS} ]]; then
30 # @ECLASS-VARIABLE: WANT_AUTOCONF
32 # The major version of autoconf your package needs
33 : ${WANT_AUTOCONF:=latest}
35 # @ECLASS-VARIABLE: WANT_AUTOMAKE
37 # The major version of automake your package needs
38 : ${WANT_AUTOMAKE:=latest}
40 # @ECLASS-VARIABLE: WANT_LIBTOOL
42 # Do you want libtool? Valid values here are "latest" and "none".
43 : ${WANT_LIBTOOL:=latest}
45 # @ECLASS-VARIABLE: _LATEST_AUTOMAKE
49 # The latest major unstable and stable version/slot of automake available
51 # List latest unstable version first to boost testing adoption rate because
52 # most package manager dependency resolver will pick the first suitable
54 # If a newer slot is stable on any arch, and is NOT reflected in this list,
55 # then circular dependencies may arise during emerge @system bootstraps.
57 # See bug 312315 and 465732 for further information and context.
59 # Do NOT change this variable in your ebuilds!
60 # If you want to force a newer minor version, you can specify the correct
61 # WANT value by using a colon: <PV>:<WANT_AUTOMAKE>
62 _LATEST_AUTOMAKE=( 1.16.1:1.16 1.15.1:1.15 )
64 _automake_atom="sys-devel/automake"
65 _autoconf_atom="sys-devel/autoconf"
66 if [[ -n ${WANT_AUTOMAKE} ]]; then
67 case ${WANT_AUTOMAKE} in
68 # Even if the package doesn't use automake, we still need to depend
69 # on it because we run aclocal to process m4 macros. This matches
70 # the autoreconf tool, so this requirement is correct. #401605
73 # Use SLOT deps if we can. For EAPI=0, we get pretty close.
74 if [[ ${EAPI:-0} != 0 ]] ; then
75 _automake_atom="|| ( `printf '>=sys-devel/automake-%s:%s ' ${_LATEST_AUTOMAKE[@]/:/ }` )"
77 _automake_atom="|| ( `printf '>=sys-devel/automake-%s ' ${_LATEST_AUTOMAKE[@]/%:*}` )"
80 *) _automake_atom="=sys-devel/automake-${WANT_AUTOMAKE}*" ;;
85 if [[ -n ${WANT_AUTOCONF} ]] ; then
86 case ${WANT_AUTOCONF} in
87 none) _autoconf_atom="" ;; # some packages don't require autoconf at all
88 2.1) _autoconf_atom="~sys-devel/autoconf-2.13" ;;
89 # if you change the "latest" version here, change also autotools_env_setup
90 latest|2.5) _autoconf_atom=">=sys-devel/autoconf-2.69" ;;
91 *) die "Invalid WANT_AUTOCONF value '${WANT_AUTOCONF}'" ;;
96 _libtool_atom=">=sys-devel/libtool-2.4"
97 if [[ -n ${WANT_LIBTOOL} ]] ; then
98 case ${WANT_LIBTOOL} in
99 none) _libtool_atom="" ;;
101 *) die "Invalid WANT_LIBTOOL value '${WANT_LIBTOOL}'" ;;
106 # Force people (nicely) to upgrade to a newer version of gettext as
107 # older ones are known to be crappy. #496454
108 AUTOTOOLS_DEPEND="!<sys-devel/gettext-0.18.1.1-r3
114 # @ECLASS-VARIABLE: AUTOTOOLS_AUTO_DEPEND
116 # Set to 'no' to disable automatically adding to DEPEND. This lets
117 # ebuilds form conditional depends by using ${AUTOTOOLS_DEPEND} in
118 # their own DEPEND string.
119 : ${AUTOTOOLS_AUTO_DEPEND:=yes}
120 if [[ ${AUTOTOOLS_AUTO_DEPEND} != "no" ]] ; then
121 DEPEND=${AUTOTOOLS_DEPEND}
123 __AUTOTOOLS_AUTO_DEPEND=${AUTOTOOLS_AUTO_DEPEND} # See top of eclass
125 unset _automake_atom _autoconf_atom
127 # @ECLASS-VARIABLE: AM_OPTS
130 # Additional options to pass to automake during
133 # @ECLASS-VARIABLE: AT_NOEAUTOMAKE
136 # Don't run eautomake command if set to 'yes'; only used to workaround
137 # broken packages. Generally you should, instead, fix the package to
138 # not call AM_INIT_AUTOMAKE if it doesn't actually use automake.
140 # @ECLASS-VARIABLE: AT_NOELIBTOOLIZE
143 # Don't run elibtoolize command if set to 'yes',
144 # useful when elibtoolize needs to be ran with
147 # @ECLASS-VARIABLE: AT_M4DIR
149 # Additional director(y|ies) aclocal should search
152 # @ECLASS-VARIABLE: AT_SYS_M4DIR
155 # For system integrators, a list of additional aclocal search paths.
156 # This variable gets eval-ed, so you can use variables in the definition
157 # that may not be valid until eautoreconf & friends are run.
160 # @FUNCTION: eautoreconf
162 # This function mimes the behavior of autoreconf, but uses the different
163 # eauto* functions to run the tools. It doesn't accept parameters, but
164 # the directory with include files can be specified with AT_M4DIR variable.
166 # Should do a full autoreconf - normally what most people will be interested in.
167 # Also should handle additional directories specified by AC_CONFIG_SUBDIRS.
171 # Subdirs often share a common build dir #529404. If so, we can't safely
172 # run in parallel because many tools clobber the content in there. Libtool
173 # and automake both `rm && cp` while aclocal reads the output. We might be
174 # able to handle this if we split the steps and grab locks on the dirs the
175 # tools actually write to. Then we'd run all the common tools that use
176 # those inputs. Doing this in bash does not scale easily.
177 # If we do re-enable parallel support, make sure #426512 is handled.
178 if [[ -z ${AT_NO_RECURSIVE} ]] ; then
179 # Take care of subdirs
180 for x in $(autotools_check_macro_val AC_CONFIG_SUBDIRS) ; do
181 if [[ -d ${x} ]] ; then
182 pushd "${x}" >/dev/null
183 # Avoid unsafe nested multijob_finish_one for bug #426512.
184 AT_NOELIBTOOLIZE="yes" eautoreconf || die
190 einfo "Running eautoreconf in '${PWD}' ..."
192 local m4dirs=$(autotools_check_macro_val AC_CONFIG_{AUX,MACRO}_DIR)
193 [[ -n ${m4dirs} ]] && mkdir -p ${m4dirs}
195 # Run all the tools before aclocal so we can gather the .m4 files.
197 # <tool> <was run> <command>
198 glibgettext false "autotools_run_tool glib-gettextize --copy --force"
199 gettext false "autotools_run_tool --at-missing autopoint --force"
200 # intltool must come after autopoint.
201 intltool false "autotools_run_tool intltoolize --automake --copy --force"
202 gtkdoc false "autotools_run_tool --at-missing gtkdocize --copy"
203 gnomedoc false "autotools_run_tool --at-missing gnome-doc-prepare --copy --force"
204 libtool false "_elibtoolize --auto-ltdl --install --copy --force"
206 for (( i = 0; i < ${#tools[@]}; i += 3 )) ; do
207 if _at_uses_${tools[i]} ; then
213 # Generate aclocal.m4 with our up-to-date m4 files.
214 local rerun_aclocal=false
217 # Check to see if we had macros expanded by other macros or in other
218 # m4 files that we couldn't detect early. This is uncommon, but some
219 # packages do this, so we have to handle it correctly.
220 for (( i = 0; i < ${#tools[@]}; i += 3 )) ; do
221 if ! ${tools[i+1]} && _at_uses_${tools[i]} ; then
226 ${rerun_aclocal} && eaclocal
228 if [[ ${WANT_AUTOCONF} = 2.1 ]] ; then
234 [[ ${AT_NOEAUTOMAKE} != "yes" ]] && FROM_EAUTORECONF="yes" eautomake ${AM_OPTS}
236 if [[ ${AT_NOELIBTOOLIZE} != "yes" ]] ; then
237 # Call it here to prevent failures due to elibtoolize called _before_
239 elibtoolize --force "${PWD}"
245 # @FUNCTION: _at_uses_pkg
248 # See if the specified macros are enabled.
250 if [[ -n $(autotools_check_macro "$@") ]] ; then
253 # If the trace didn't find it (perhaps because aclocal.m4 hasn't
254 # been generated yet), cheat, but be conservative.
257 args+=( -e "^[[:space:]]*${macro}\>" )
259 egrep -q "${args[@]}" configure.??
262 _at_uses_autoheader() { _at_uses_pkg A{C,M}_CONFIG_HEADER{S,}; }
263 _at_uses_automake() { _at_uses_pkg AM_INIT_AUTOMAKE; }
264 _at_uses_gettext() { _at_uses_pkg AM_GNU_GETTEXT_{,REQUIRE_}VERSION; }
265 _at_uses_glibgettext() { _at_uses_pkg AM_GLIB_GNU_GETTEXT; }
266 _at_uses_intltool() { _at_uses_pkg {AC,IT}_PROG_INTLTOOL; }
267 _at_uses_gtkdoc() { _at_uses_pkg GTK_DOC_CHECK; }
268 _at_uses_gnomedoc() { _at_uses_pkg GNOME_DOC_INIT; }
269 _at_uses_libtool() { _at_uses_pkg A{C,M}_PROG_LIBTOOL LT_INIT; }
270 _at_uses_libltdl() { _at_uses_pkg LT_CONFIG_LTDL_DIR; }
272 # @FUNCTION: eaclocal_amflags
274 # Extract the ACLOCAL_AMFLAGS value from the Makefile.am and try to handle
275 # (most) of the crazy crap that people throw at us.
277 local aclocal_opts amflags_file
279 for amflags_file in GNUmakefile.am Makefile.am GNUmakefile.in Makefile.in ; do
280 [[ -e ${amflags_file} ]] || continue
281 # setup the env in case the pkg does something crazy
282 # in their ACLOCAL_AMFLAGS. like run a shell script
283 # which turns around and runs autotools. #365401
284 # or split across multiple lines. #383525
286 aclocal_opts=$(sed -n \
287 "/^ACLOCAL_AMFLAGS[[:space:]]*=/{ \
288 # match the first line
290 # then gobble up all escaped lines
291 : nextline /\\\\$/{ n; p; b nextline; } \
293 eval aclocal_opts=\""${aclocal_opts}"\"
300 # @FUNCTION: eaclocal
302 # These functions runs the autotools using autotools_run_tool with the
303 # specified parametes. The name of the tool run is the same of the function
305 # They also force installing the support files for safety.
306 # Respects AT_M4DIR for additional directories to search for macro's.
308 [[ ! -f aclocal.m4 || -n $(grep -e 'generated.*by aclocal' aclocal.m4) ]] && \
309 autotools_run_tool --at-m4flags aclocal "$@" $(eaclocal_amflags)
312 # @FUNCTION: _elibtoolize
316 # Note the '_' prefix: avoid collision with elibtoolize() from libtool.eclass.
318 local LIBTOOLIZE=${LIBTOOLIZE:-$(type -P glibtoolize > /dev/null && echo glibtoolize || echo libtoolize)}
320 if [[ $1 == "--auto-ltdl" ]] ; then
322 _at_uses_libltdl && set -- "$@" --ltdl
325 [[ -f GNUmakefile.am || -f Makefile.am ]] && set -- "$@" --automake
327 autotools_run_tool ${LIBTOOLIZE} "$@"
330 # @FUNCTION: eautoheader
334 _at_uses_autoheader || return 0
335 autotools_run_tool --at-no-fail --at-m4flags autoheader "$@"
338 # @FUNCTION: eautoconf
342 if [[ ! -f configure.ac && ! -f configure.in ]] ; then
344 eerror "No configure.{ac,in} present in '${PWD}'!"
346 die "No configure.{ac,in} present!"
348 if [[ ${WANT_AUTOCONF} != "2.1" && -e configure.in ]] ; then
349 eqawarn "This package has a configure.in file which has long been deprecated. Please"
350 eqawarn "update it to use configure.ac instead as newer versions of autotools will die"
351 eqawarn "when it finds this file. See https://bugs.gentoo.org/426262 for details."
354 autotools_run_tool --at-m4flags autoconf "$@"
357 # @FUNCTION: eautomake
365 # - a Makefile.am type file exists
366 # - the configure script is using the AM_INIT_AUTOMAKE directive
367 for makefile_name in {GNUmakefile,{M,m}akefile}.am "" ; do
368 [[ -f ${makefile_name} ]] && break
371 _automake_version() {
372 autotools_run_tool --at-output automake --version 2>/dev/null |
373 sed -n -e '1{s:.*(GNU automake) ::p;q}'
376 if [[ -z ${makefile_name} ]] ; then
377 _at_uses_automake || return 0
379 elif [[ -z ${FROM_EAUTORECONF} && -f ${makefile_name%.am}.in ]]; then
381 local installed_automake
383 installed_automake=$(WANT_AUTOMAKE= _automake_version)
384 used_automake=$(head -n 1 < ${makefile_name%.am}.in | \
385 sed -e 's:.*by automake \(.*\) from .*:\1:')
387 if [[ ${installed_automake} != ${used_automake} ]]; then
388 ewarn "Automake used for the package (${used_automake}) differs from" \
389 "the installed version (${installed_automake})."
390 ewarn "Forcing a full rebuild of the autotools to workaround."
396 [[ -f INSTALL && -f AUTHORS && -f ChangeLog && -f NEWS && -f README ]] \
397 || extra_opts+=( --foreign )
399 # Older versions of automake do not support --force-missing. But we want
400 # to use this whenever possible to update random bundled files #133489.
401 case $(_automake_version) in
403 *) extra_opts+=( --force-missing ) ;;
406 autotools_run_tool automake --add-missing --copy "${extra_opts[@]}" "$@"
409 # @FUNCTION: eautopoint
411 # Runs autopoint (from the gettext package).
413 autotools_run_tool autopoint "$@"
416 # @FUNCTION: config_rpath_update
417 # @USAGE: [destination]
419 # Some packages utilize the config.rpath helper script, but don't
420 # use gettext directly. So we have to copy it in manually since
421 # we can't let `autopoint` do it for us.
422 config_rpath_update() {
423 local dst src=$(type -P gettext | sed 's:bin/gettext:share/gettext/config.rpath:')
425 [[ $# -eq 0 ]] && set -- $(find -name config.rpath)
426 [[ $# -eq 0 ]] && return 0
428 einfo "Updating all config.rpath files"
431 cp "${src}" "${dst}" || die
435 # @FUNCTION: autotools_env_setup
438 # Process the WANT_AUTO{CONF,MAKE} flags.
439 autotools_env_setup() {
440 # We do the "latest" → version switch here because it solves
441 # possible order problems, see bug #270010 as an example.
442 if [[ ${WANT_AUTOMAKE} == "latest" ]]; then
444 for pv in ${_LATEST_AUTOMAKE[@]/#*:} ; do
445 # Break on first hit to respect _LATEST_AUTOMAKE order.
449 hv_args="--host-root"
455 ROOT=/ has_version ${hv_args} "=sys-devel/automake-${pv}*" && export WANT_AUTOMAKE="${pv}" && break
457 [[ ${WANT_AUTOMAKE} == "latest" ]] && \
458 die "Cannot find the latest automake! Tried ${_LATEST_AUTOMAKE[*]}"
460 [[ ${WANT_AUTOCONF} == "latest" ]] && export WANT_AUTOCONF=2.5
463 # @FUNCTION: autotools_run_tool
464 # @USAGE: [--at-no-fail] [--at-m4flags] [--at-missing] [--at-output] <autotool> [tool-specific flags]
467 # Run the specified autotool helper, but do logging and error checking
468 # around it in the process.
469 autotools_run_tool() {
470 # Process our own internal flags first
471 local autofail=true m4flags=false missing_ok=false return_output=false
472 while [[ -n $1 ]] ; do
474 --at-no-fail) autofail=false;;
475 --at-m4flags) m4flags=true;;
476 --at-missing) missing_ok=true;;
477 --at-output) return_output=true;;
478 # whatever is left goes to the actual tool
484 if [[ ${EBUILD_PHASE} != "unpack" && ${EBUILD_PHASE} != "prepare" ]]; then
485 ewarn "QA Warning: running $1 in ${EBUILD_PHASE} phase"
488 if ${missing_ok} && ! type -P ${1} >/dev/null ; then
489 einfo "Skipping '$*' due $1 not installed"
495 # Allow people to pass in full paths. #549268
496 local STDERR_TARGET="${T}/${1##*/}.out"
497 # most of the time, there will only be one run, but if there are
498 # more, make sure we get unique log filenames
499 if [[ -e ${STDERR_TARGET} ]] ; then
502 STDERR_TARGET="${T}/${1##*/}-${i}.out"
503 [[ -e ${STDERR_TARGET} ]] || break
509 set -- "${1}" $(autotools_m4dir_include) "${@:2}" $(autotools_m4sysdir_include)
512 # If the caller wants to probe something, then let them do it directly.
513 if ${return_output} ; then
518 printf "***** $1 *****\n***** PWD: ${PWD}\n***** $*\n\n" > "${STDERR_TARGET}"
521 "$@" >> "${STDERR_TARGET}" 2>&1
522 if ! eend $? && ${autofail} ; then
524 eerror "Failed Running $1 !"
526 eerror "Include in your bugreport the contents of:"
528 eerror " ${STDERR_TARGET}"
530 die "Failed Running $1 !"
534 # Internal function to check for support
536 # Keep a list of all the macros we might use so that we only
537 # have to run the trace code once. Order doesn't matter.
538 ALL_AUTOTOOLS_MACROS=(
539 A{C,M}_PROG_LIBTOOL LT_INIT LT_CONFIG_LTDL_DIR
540 A{C,M}_CONFIG_HEADER{S,}
542 AC_CONFIG_AUX_DIR AC_CONFIG_MACRO_DIR
545 AM_GNU_GETTEXT_{,REQUIRE_}VERSION
546 {AC,IT}_PROG_INTLTOOL
550 autotools_check_macro() {
551 [[ -f configure.ac || -f configure.in ]] || return 0
553 # We can run in multiple dirs, so we have to cache the trace
554 # data in $PWD rather than an env var.
555 local trace_file=".__autoconf_trace_data"
556 if [[ ! -e ${trace_file} ]] || [[ ! aclocal.m4 -ot ${trace_file} ]] ; then
557 WANT_AUTOCONF="2.5" autoconf \
558 $(autotools_m4dir_include) \
559 ${ALL_AUTOTOOLS_MACROS[@]/#/--trace=} > ${trace_file} 2>/dev/null
564 has ${macro} ${ALL_AUTOTOOLS_MACROS[@]} || die "internal error: add ${macro} to ALL_AUTOTOOLS_MACROS"
565 args+=( -e ":${macro}:" )
567 grep "${args[@]}" ${trace_file}
570 # @FUNCTION: autotools_check_macro_val
571 # @USAGE: <macro> [macros]
574 # Look for a macro and extract its value.
575 autotools_check_macro_val() {
579 autotools_check_macro "${macro}" | \
580 gawk -v macro="${macro}" \
581 '($0 !~ /^[[:space:]]*(#|dnl)/) {
582 if (match($0, macro ":(.*)$", res))
590 _autotools_m4dir_include() {
591 local x include_opts flag
593 # Use the right flag to autoconf based on the version #448986
594 [[ ${WANT_AUTOCONF} == "2.1" ]] \
603 [[ ! -d ${x} ]] && ewarn "autotools.eclass: '${x}' does not exist"
604 include_opts+=" -${flag} ${x}"
611 autotools_m4dir_include() { _autotools_m4dir_include ${AT_M4DIR} ; }
612 autotools_m4sysdir_include() {
613 # First try to use the paths the system integrator has set up.
614 local paths=( $(eval echo ${AT_SYS_M4DIR}) )
616 if [[ ${#paths[@]} -eq 0 && -n ${SYSROOT} ]] ; then
617 # If they didn't give us anything, then default to the SYSROOT.
618 # This helps when cross-compiling.
619 local path="${SYSROOT}/usr/share/aclocal"
620 [[ -d ${path} ]] && paths+=( "${path}" )
622 _autotools_m4dir_include "${paths[@]}"