1 # Copyright 1999-2020 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
4 # @ECLASS: autotools.eclass
6 # base-system@gentoo.org
7 # @SUPPORTED_EAPIS: 0 1 2 3 4 5 6 7
8 # @BLURB: Regenerates auto* build scripts
10 # This eclass is for safely handling autotooled software packages that need to
11 # regenerate their build scripts. All functions will abort in case of errors.
13 # Note: We require GNU m4, as does autoconf. So feel free to use any features
14 # from the GNU version of m4 without worrying about other variants (i.e. BSD).
16 if [[ ${__AUTOTOOLS_AUTO_DEPEND+set} == "set" ]] ; then
17 # See if we were included already, but someone changed the value
18 # of AUTOTOOLS_AUTO_DEPEND on us. We could reload the entire
19 # eclass at that point, but that adds overhead, and it's trivial
20 # to re-order inherit in eclasses/ebuilds instead. #409611
21 if [[ ${__AUTOTOOLS_AUTO_DEPEND} != ${AUTOTOOLS_AUTO_DEPEND} ]] ; then
22 die "AUTOTOOLS_AUTO_DEPEND changed value between inherits; please inherit autotools.eclass first! ${__AUTOTOOLS_AUTO_DEPEND} -> ${AUTOTOOLS_AUTO_DEPEND}"
26 if [[ -z ${_AUTOTOOLS_ECLASS} ]]; then
31 *) die "${ECLASS}: EAPI ${EAPI} not supported" ;;
36 # @ECLASS-VARIABLE: WANT_AUTOCONF
38 # The major version of autoconf your package needs
39 : ${WANT_AUTOCONF:=latest}
41 # @ECLASS-VARIABLE: WANT_AUTOMAKE
43 # The major version of automake your package needs
44 : ${WANT_AUTOMAKE:=latest}
46 # @ECLASS-VARIABLE: WANT_LIBTOOL
48 # Do you want libtool? Valid values here are "latest" and "none".
49 : ${WANT_LIBTOOL:=latest}
51 # @ECLASS-VARIABLE: _LATEST_AUTOMAKE
55 # The latest major unstable and stable version/slot of automake available
57 # List latest unstable version first to boost testing adoption rate because
58 # most package manager dependency resolver will pick the first suitable
60 # If a newer slot is stable on any arch, and is NOT reflected in this list,
61 # then circular dependencies may arise during emerge @system bootstraps.
63 # See bug 312315 and 465732 for further information and context.
65 # Do NOT change this variable in your ebuilds!
66 # If you want to force a newer minor version, you can specify the correct
67 # WANT value by using a colon: <PV>:<WANT_AUTOMAKE>
68 _LATEST_AUTOMAKE=( 1.16.1:1.16 1.15.1:1.15 )
70 _automake_atom="sys-devel/automake"
71 _autoconf_atom="sys-devel/autoconf"
72 if [[ -n ${WANT_AUTOMAKE} ]]; then
73 case ${WANT_AUTOMAKE} in
74 # Even if the package doesn't use automake, we still need to depend
75 # on it because we run aclocal to process m4 macros. This matches
76 # the autoreconf tool, so this requirement is correct. #401605
79 # Use SLOT deps if we can. For EAPI=0, we get pretty close.
80 if [[ ${EAPI:-0} != 0 ]] ; then
81 _automake_atom="|| ( `printf '>=sys-devel/automake-%s:%s ' ${_LATEST_AUTOMAKE[@]/:/ }` )"
83 _automake_atom="|| ( `printf '>=sys-devel/automake-%s ' ${_LATEST_AUTOMAKE[@]/%:*}` )"
86 *) _automake_atom="=sys-devel/automake-${WANT_AUTOMAKE}*" ;;
91 if [[ -n ${WANT_AUTOCONF} ]] ; then
92 case ${WANT_AUTOCONF} in
93 none) _autoconf_atom="" ;; # some packages don't require autoconf at all
94 2.1) _autoconf_atom="~sys-devel/autoconf-2.13" ;;
95 # if you change the "latest" version here, change also autotools_env_setup
96 latest|2.5) _autoconf_atom=">=sys-devel/autoconf-2.69" ;;
97 *) die "Invalid WANT_AUTOCONF value '${WANT_AUTOCONF}'" ;;
102 _libtool_atom=">=sys-devel/libtool-2.4"
103 if [[ -n ${WANT_LIBTOOL} ]] ; then
104 case ${WANT_LIBTOOL} in
105 none) _libtool_atom="" ;;
107 *) die "Invalid WANT_LIBTOOL value '${WANT_LIBTOOL}'" ;;
112 AUTOTOOLS_DEPEND="${_automake_atom}
117 # @ECLASS-VARIABLE: AUTOTOOLS_AUTO_DEPEND
119 # Set to 'no' to disable automatically adding to DEPEND. This lets
120 # ebuilds form conditional depends by using ${AUTOTOOLS_DEPEND} in
121 # their own DEPEND string.
122 : ${AUTOTOOLS_AUTO_DEPEND:=yes}
123 if [[ ${AUTOTOOLS_AUTO_DEPEND} != "no" ]] ; then
125 0|1|2|3|4|5|6) DEPEND=${AUTOTOOLS_DEPEND} ;;
126 7) BDEPEND=${AUTOTOOLS_DEPEND} ;;
129 __AUTOTOOLS_AUTO_DEPEND=${AUTOTOOLS_AUTO_DEPEND} # See top of eclass
131 unset _automake_atom _autoconf_atom
133 # @ECLASS-VARIABLE: AM_OPTS
136 # Additional options to pass to automake during
139 # @ECLASS-VARIABLE: AT_NOEAUTOMAKE
142 # Don't run eautomake command if set to 'yes'; only used to workaround
143 # broken packages. Generally you should, instead, fix the package to
144 # not call AM_INIT_AUTOMAKE if it doesn't actually use automake.
146 # @ECLASS-VARIABLE: AT_NOELIBTOOLIZE
149 # Don't run elibtoolize command if set to 'yes',
150 # useful when elibtoolize needs to be ran with
153 # @ECLASS-VARIABLE: AT_M4DIR
155 # Additional director(y|ies) aclocal should search
158 # @ECLASS-VARIABLE: AT_SYS_M4DIR
161 # For system integrators, a list of additional aclocal search paths.
162 # This variable gets eval-ed, so you can use variables in the definition
163 # that may not be valid until eautoreconf & friends are run.
166 # @FUNCTION: eautoreconf
168 # This function mimes the behavior of autoreconf, but uses the different
169 # eauto* functions to run the tools. It doesn't accept parameters, but
170 # the directory with include files can be specified with AT_M4DIR variable.
172 # Should do a full autoreconf - normally what most people will be interested in.
173 # Also should handle additional directories specified by AC_CONFIG_SUBDIRS.
177 # Subdirs often share a common build dir #529404. If so, we can't safely
178 # run in parallel because many tools clobber the content in there. Libtool
179 # and automake both `rm && cp` while aclocal reads the output. We might be
180 # able to handle this if we split the steps and grab locks on the dirs the
181 # tools actually write to. Then we'd run all the common tools that use
182 # those inputs. Doing this in bash does not scale easily.
183 # If we do re-enable parallel support, make sure #426512 is handled.
184 if [[ -z ${AT_NO_RECURSIVE} ]] ; then
185 # Take care of subdirs
186 for x in $(autotools_check_macro_val AC_CONFIG_SUBDIRS) ; do
187 if [[ -d ${x} ]] ; then
188 pushd "${x}" >/dev/null
189 # Avoid unsafe nested multijob_finish_one for bug #426512.
190 AT_NOELIBTOOLIZE="yes" eautoreconf || die
196 einfo "Running eautoreconf in '${PWD}' ..."
198 local m4dirs=$(autotools_check_macro_val AC_CONFIG_{AUX,MACRO}_DIR)
199 [[ -n ${m4dirs} ]] && mkdir -p ${m4dirs}
201 # Run all the tools before aclocal so we can gather the .m4 files.
203 # <tool> <was run> <command>
204 glibgettext false "autotools_run_tool glib-gettextize --copy --force"
205 gettext false "autotools_run_tool --at-missing autopoint --force"
206 # intltool must come after autopoint.
207 intltool false "autotools_run_tool intltoolize --automake --copy --force"
208 gtkdoc false "autotools_run_tool --at-missing gtkdocize --copy"
209 gnomedoc false "autotools_run_tool --at-missing gnome-doc-prepare --copy --force"
210 libtool false "_elibtoolize --auto-ltdl --install --copy --force"
212 for (( i = 0; i < ${#tools[@]}; i += 3 )) ; do
213 if _at_uses_${tools[i]} ; then
219 # Generate aclocal.m4 with our up-to-date m4 files.
220 local rerun_aclocal=false
223 # Check to see if we had macros expanded by other macros or in other
224 # m4 files that we couldn't detect early. This is uncommon, but some
225 # packages do this, so we have to handle it correctly.
226 for (( i = 0; i < ${#tools[@]}; i += 3 )) ; do
227 if ! ${tools[i+1]} && _at_uses_${tools[i]} ; then
232 ${rerun_aclocal} && eaclocal
234 if [[ ${WANT_AUTOCONF} = 2.1 ]] ; then
240 [[ ${AT_NOEAUTOMAKE} != "yes" ]] && FROM_EAUTORECONF="yes" eautomake ${AM_OPTS}
242 if [[ ${AT_NOELIBTOOLIZE} != "yes" ]] ; then
243 # Call it here to prevent failures due to elibtoolize called _before_
245 elibtoolize --force "${PWD}"
251 # @FUNCTION: _at_uses_pkg
254 # See if the specified macros are enabled.
256 if [[ -n $(autotools_check_macro "$@") ]] ; then
259 # If the trace didn't find it (perhaps because aclocal.m4 hasn't
260 # been generated yet), cheat, but be conservative.
263 args+=( -e "^[[:space:]]*${macro}\>" )
265 egrep -q "${args[@]}" configure.??
268 _at_uses_autoheader() { _at_uses_pkg A{C,M}_CONFIG_HEADER{S,}; }
269 _at_uses_automake() { _at_uses_pkg AM_INIT_AUTOMAKE; }
270 _at_uses_gettext() { _at_uses_pkg AM_GNU_GETTEXT_{,REQUIRE_}VERSION; }
271 _at_uses_glibgettext() { _at_uses_pkg AM_GLIB_GNU_GETTEXT; }
272 _at_uses_intltool() { _at_uses_pkg {AC,IT}_PROG_INTLTOOL; }
273 _at_uses_gtkdoc() { _at_uses_pkg GTK_DOC_CHECK; }
274 _at_uses_gnomedoc() { _at_uses_pkg GNOME_DOC_INIT; }
275 _at_uses_libtool() { _at_uses_pkg A{C,M}_PROG_LIBTOOL LT_INIT; }
276 _at_uses_libltdl() { _at_uses_pkg LT_CONFIG_LTDL_DIR; }
278 # @FUNCTION: eaclocal_amflags
280 # Extract the ACLOCAL_AMFLAGS value from the Makefile.am and try to handle
281 # (most) of the crazy crap that people throw at us.
283 local aclocal_opts amflags_file
285 for amflags_file in GNUmakefile.am Makefile.am GNUmakefile.in Makefile.in ; do
286 [[ -e ${amflags_file} ]] || continue
287 # setup the env in case the pkg does something crazy
288 # in their ACLOCAL_AMFLAGS. like run a shell script
289 # which turns around and runs autotools. #365401
290 # or split across multiple lines. #383525
292 aclocal_opts=$(sed -n \
293 "/^ACLOCAL_AMFLAGS[[:space:]]*=/{ \
294 # match the first line
296 # then gobble up all escaped lines
297 : nextline /\\\\$/{ n; p; b nextline; } \
299 eval aclocal_opts=\""${aclocal_opts}"\"
306 # @FUNCTION: eaclocal
308 # These functions runs the autotools using autotools_run_tool with the
309 # specified parametes. The name of the tool run is the same of the function
311 # They also force installing the support files for safety.
312 # Respects AT_M4DIR for additional directories to search for macro's.
314 [[ ! -f aclocal.m4 || -n $(grep -e 'generated.*by aclocal' aclocal.m4) ]] && \
315 autotools_run_tool --at-m4flags aclocal "$@" $(eaclocal_amflags)
318 # @FUNCTION: _elibtoolize
322 # Note the '_' prefix: avoid collision with elibtoolize() from libtool.eclass.
324 local LIBTOOLIZE=${LIBTOOLIZE:-$(type -P glibtoolize > /dev/null && echo glibtoolize || echo libtoolize)}
326 if [[ $1 == "--auto-ltdl" ]] ; then
328 _at_uses_libltdl && set -- "$@" --ltdl
331 [[ -f GNUmakefile.am || -f Makefile.am ]] && set -- "$@" --automake
333 autotools_run_tool ${LIBTOOLIZE} "$@"
336 # @FUNCTION: eautoheader
340 _at_uses_autoheader || return 0
341 autotools_run_tool --at-no-fail --at-m4flags autoheader "$@"
344 # @FUNCTION: eautoconf
348 if [[ ! -f configure.ac && ! -f configure.in ]] ; then
350 eerror "No configure.{ac,in} present in '${PWD}'!"
352 die "No configure.{ac,in} present!"
354 if [[ ${WANT_AUTOCONF} != "2.1" && -e configure.in ]] ; then
355 eqawarn "This package has a configure.in file which has long been deprecated. Please"
356 eqawarn "update it to use configure.ac instead as newer versions of autotools will die"
357 eqawarn "when it finds this file. See https://bugs.gentoo.org/426262 for details."
360 autotools_run_tool --at-m4flags autoconf "$@"
363 # @FUNCTION: eautomake
371 # - a Makefile.am type file exists
372 # - the configure script is using the AM_INIT_AUTOMAKE directive
373 for makefile_name in {GNUmakefile,{M,m}akefile}.am "" ; do
374 [[ -f ${makefile_name} ]] && break
377 _automake_version() {
378 autotools_run_tool --at-output automake --version 2>/dev/null |
379 sed -n -e '1{s:.*(GNU automake) ::p;q}'
382 if [[ -z ${makefile_name} ]] ; then
383 _at_uses_automake || return 0
385 elif [[ -z ${FROM_EAUTORECONF} && -f ${makefile_name%.am}.in ]]; then
387 local installed_automake
389 installed_automake=$(WANT_AUTOMAKE= _automake_version)
390 used_automake=$(head -n 1 < ${makefile_name%.am}.in | \
391 sed -e 's:.*by automake \(.*\) from .*:\1:')
393 if [[ ${installed_automake} != ${used_automake} ]]; then
394 ewarn "Automake used for the package (${used_automake}) differs from" \
395 "the installed version (${installed_automake})."
396 ewarn "Forcing a full rebuild of the autotools to workaround."
402 [[ -f INSTALL && -f AUTHORS && -f ChangeLog && -f NEWS && -f README ]] \
403 || extra_opts+=( --foreign )
405 # Older versions of automake do not support --force-missing. But we want
406 # to use this whenever possible to update random bundled files #133489.
407 case $(_automake_version) in
409 *) extra_opts+=( --force-missing ) ;;
412 autotools_run_tool automake --add-missing --copy "${extra_opts[@]}" "$@"
415 # @FUNCTION: eautopoint
417 # Runs autopoint (from the gettext package).
419 autotools_run_tool autopoint "$@"
422 # @FUNCTION: config_rpath_update
423 # @USAGE: [destination]
425 # Some packages utilize the config.rpath helper script, but don't
426 # use gettext directly. So we have to copy it in manually since
427 # we can't let `autopoint` do it for us.
428 config_rpath_update() {
429 local dst src=$(type -P gettext | sed 's:bin/gettext:share/gettext/config.rpath:')
431 [[ $# -eq 0 ]] && set -- $(find -name config.rpath)
432 [[ $# -eq 0 ]] && return 0
434 einfo "Updating all config.rpath files"
437 cp "${src}" "${dst}" || die
441 # @FUNCTION: autotools_env_setup
444 # Process the WANT_AUTO{CONF,MAKE} flags.
445 autotools_env_setup() {
446 # We do the "latest" → version switch here because it solves
447 # possible order problems, see bug #270010 as an example.
448 if [[ ${WANT_AUTOMAKE} == "latest" ]]; then
450 for pv in ${_LATEST_AUTOMAKE[@]/#*:} ; do
451 # Break on first hit to respect _LATEST_AUTOMAKE order.
455 hv_args="--host-root"
461 ROOT=/ has_version ${hv_args} "=sys-devel/automake-${pv}*" && export WANT_AUTOMAKE="${pv}" && break
463 [[ ${WANT_AUTOMAKE} == "latest" ]] && \
464 die "Cannot find the latest automake! Tried ${_LATEST_AUTOMAKE[*]}"
466 [[ ${WANT_AUTOCONF} == "latest" ]] && export WANT_AUTOCONF=2.5
469 # @FUNCTION: autotools_run_tool
470 # @USAGE: [--at-no-fail] [--at-m4flags] [--at-missing] [--at-output] <autotool> [tool-specific flags]
473 # Run the specified autotool helper, but do logging and error checking
474 # around it in the process.
475 autotools_run_tool() {
476 # Process our own internal flags first
477 local autofail=true m4flags=false missing_ok=false return_output=false
478 while [[ -n $1 ]] ; do
480 --at-no-fail) autofail=false;;
481 --at-m4flags) m4flags=true;;
482 --at-missing) missing_ok=true;;
483 --at-output) return_output=true;;
484 # whatever is left goes to the actual tool
490 if [[ ${EBUILD_PHASE} != "unpack" && ${EBUILD_PHASE} != "prepare" ]]; then
491 ewarn "QA Warning: running $1 in ${EBUILD_PHASE} phase"
494 if ${missing_ok} && ! type -P ${1} >/dev/null ; then
495 einfo "Skipping '$*' due $1 not installed"
501 # Allow people to pass in full paths. #549268
502 local STDERR_TARGET="${T}/${1##*/}.out"
503 # most of the time, there will only be one run, but if there are
504 # more, make sure we get unique log filenames
505 if [[ -e ${STDERR_TARGET} ]] ; then
508 STDERR_TARGET="${T}/${1##*/}-${i}.out"
509 [[ -e ${STDERR_TARGET} ]] || break
515 set -- "${1}" $(autotools_m4dir_include) $(autotools_m4sysdir_include) "${@:2}"
518 # If the caller wants to probe something, then let them do it directly.
519 if ${return_output} ; then
524 printf "***** $1 *****\n***** PWD: ${PWD}\n***** $*\n\n" > "${STDERR_TARGET}"
527 "$@" >> "${STDERR_TARGET}" 2>&1
528 if ! eend $? && ${autofail} ; then
530 eerror "Failed Running $1 !"
532 eerror "Include in your bugreport the contents of:"
534 eerror " ${STDERR_TARGET}"
536 die "Failed Running $1 !"
540 # Internal function to check for support
542 # Keep a list of all the macros we might use so that we only
543 # have to run the trace code once. Order doesn't matter.
544 ALL_AUTOTOOLS_MACROS=(
545 A{C,M}_PROG_LIBTOOL LT_INIT LT_CONFIG_LTDL_DIR
546 A{C,M}_CONFIG_HEADER{S,}
548 AC_CONFIG_AUX_DIR AC_CONFIG_MACRO_DIR
551 AM_GNU_GETTEXT_{,REQUIRE_}VERSION
552 {AC,IT}_PROG_INTLTOOL
556 autotools_check_macro() {
557 [[ -f configure.ac || -f configure.in ]] || return 0
559 # We can run in multiple dirs, so we have to cache the trace
560 # data in $PWD rather than an env var.
561 local trace_file=".__autoconf_trace_data"
562 if [[ ! -e ${trace_file} ]] || [[ ! aclocal.m4 -ot ${trace_file} ]] ; then
563 WANT_AUTOCONF="2.5" autoconf \
564 $(autotools_m4dir_include) \
565 ${ALL_AUTOTOOLS_MACROS[@]/#/--trace=} > ${trace_file} 2>/dev/null
570 has ${macro} ${ALL_AUTOTOOLS_MACROS[@]} || die "internal error: add ${macro} to ALL_AUTOTOOLS_MACROS"
571 args+=( -e ":${macro}:" )
573 grep "${args[@]}" ${trace_file}
576 # @FUNCTION: autotools_check_macro_val
577 # @USAGE: <macro> [macros]
580 # Look for a macro and extract its value.
581 autotools_check_macro_val() {
585 autotools_check_macro "${macro}" | \
586 gawk -v macro="${macro}" \
587 '($0 !~ /^[[:space:]]*(#|dnl)/) {
588 if (match($0, macro ":(.*)$", res))
596 _autotools_m4dir_include() {
597 local x include_opts flag
599 # Use the right flag to autoconf based on the version #448986
600 [[ ${WANT_AUTOCONF} == "2.1" ]] \
609 [[ ! -d ${x} ]] && ewarn "autotools.eclass: '${x}' does not exist"
610 include_opts+=" -${flag} ${x}"
617 autotools_m4dir_include() { _autotools_m4dir_include ${AT_M4DIR} ; }
618 autotools_m4sysdir_include() {
619 # First try to use the paths the system integrator has set up.
620 local paths=( $(eval echo ${AT_SYS_M4DIR}) )
622 if [[ ${#paths[@]} -eq 0 && -n ${SYSROOT} ]] ; then
623 # If they didn't give us anything, then default to the SYSROOT.
624 # This helps when cross-compiling.
625 local path="${SYSROOT}/usr/share/aclocal"
626 [[ -d ${path} ]] && paths+=( "${path}" )
628 _autotools_m4dir_include "${paths[@]}"