Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Autoconf 2.72 broke my build. How do I fix it?

February 23, 2023
Frédéric Bérat
Related topics:
C, C#, C++
Related products:
Red Hat Enterprise Linux

Share:

    Autoconf 2.70 was released at the end of 2021. This release had several compatibility issues and defects, and was rapidly replaced by Autoconf 2.71.

    The upstream community is going to release another version, Autoconf 2.72. It may be time to have a closer look at its potential impact.

    In a previous article, I explained that we developed a tool that can be useful in such a use case. The idea behind this tool is to massively rebuild packages that depend on a component for which we want to release a new version. With this tool, we could evaluate how many packages would break if the community decided to use Autoconf 2.72 at this point in development. The evaluation would allow us to propose fixes ahead of this release.

    There were still some packages for which no fix could be made in Autoconf, because these packages were at fault for incorrect API usage.

    In this article we cover common build failures that are seen with the new version, and how they can be fixed.

    But everything was working fine before this new version!

    Let's be honest, m4 is horrible as a language. It's easy to make mistakes, and these mistakes don't even necessarily lead to obvious errors.

    The easiest and most common mistake is underquoting.

    Some functions accept parameters, which may or may not need to be quoted (using [] by default). Yet, it may happen that not using these quotes will not break the processing, nor generate incorrect shell code; until it does.

    During Autoconf 2.72 development, some code snippet was modified in order to port AC_LANG_CALL to C++, this small and innocent change was accompanied by a change in the associated comment, which introduced a comma, as shown in the diff below:

       Port AC_LANG_CALL(C) to C++
    
        
    
        * lib/autoconf/c.m4 (AC_LANG_CALL(C)): Add an extern "C" if C++.
    
        Problem reported by Vincent Lefèvre (sr #110532).
    
    
    diff --git a/lib/autoconf/c.m4 b/lib/autoconf/c.m4
    
    index 44443a39..48bd49a3 100644
    
    --- a/lib/autoconf/c.m4
    
    +++ b/lib/autoconf/c.m4
    
    @@ -126,7 +126,13 @@ m4_define([AC_LANG_CALL(C)],
    
     m4_if([$2], [main], ,
    
     [/* Override any GCC internal prototype to avoid an error.
    
        Use char because int might match the return type of a GCC
    
    -   builtin and then its argument prototype would still apply.  */
    
    +   builtin and then its argument prototype would still apply.
    
    +   The 'extern "C"' is for builds by C++ compilers;
    
    +   although this is not generally supported in C code, supporting it here
    
    +   has little cost and some practical benefit (sr 110532).  */
    
    +#ifdef __cplusplus
    
    +extern "C"
    
    +#endif
    
     char $2 ();])], [return $2 ();])])

    This little character, between 'code' and 'supporting' broke 70 package builds in Fedora, out of around 1200 packages that need autoconf.

    Why did they break? Because of underquoting. This function gets executed within other functions which need their parameters to be quoted by the caller, but are not. The result being that m4 interpreted the "," in the C code's comment as a split of the parameter list of the calling function, leading to the generation of incorrect shell code.

    Another common mistake is a wrongly placed 'fi'.

    This one was even found in Autoconf itself, during the development, and got fixed as follows:

    diff --git a/lib/autoconf/functions.m4 b/lib/autoconf/functions.m4
    
    index e7c54846..51aeb0b9 100644
    
    --- a/lib/autoconf/functions.m4
    
    +++ b/lib/autoconf/functions.m4
    
    @@ -448,8 +448,10 @@ void *alloca (size_t);
    
     ]],                               [[char *p = (char *) alloca (1);
    
                                        if (p) return 0;]])],
    
                    [ac_cv_func_alloca_works=yes],
    
    -               [ac_cv_func_alloca_works=no])])
    
    +               [ac_cv_func_alloca_works=no]
    
    +               )
    
     fi
    
    +])
    
    
     if test $ac_cv_func_alloca_works = yes; then
    
       AC_DEFINE(HAVE_ALLOCA, 1,

    Why is this one popping up now? Because Autoconf modified the way it handles "if" statements, and more specifically the "else" part. It now makes use of a trick involving "case" statements in order to properly deal with cases where there is nothing to do in this "else".

    The consequence is that these errors get unveiled, and now need to be fixed.

    Another less common case is the appearance of a circular dependency. This kind of error isn't really the user's fault, as we can't ask you to know the internals of Autoconf before writing your code, but can still be avoided by using different constructs.

    How are these errors detected?

    Both underquoting and bad "fi" placement may lead to the same kind of error.

    Basically, the generated configure code will likely raise a "syntax error" when being executed.

    If you have underquoted code, the error will likely look like the following:

    checking for IPv6 compile-time support without -DINET6...
    
    ./configure: line 10559: syntax error near unexpected token ';;'
    
    ./configure: line 10559: 'rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;'

    If you have a misplaced "fi", the error will likely look like the following:

    checking for CAIRO... yes
    
    ./configure: line 30733: syntax error near unexpected token 'fi'
    
    ./configure: line 30733: 'fi'

    Yet, sometimes the error may be completely different from the above:

    checking for zlib.h... yes
    
    ./configure: line 14589: syntax error near unexpected token 'newline'
    
    ./configure: line 14589: ' '''

    In this case, the syntax error happened way after the actual quoting error, which may make the analysis more difficult.

    How to find the source of the problem, and fix it?

    In order to find the source of the error, you need to contextualize it first.

    Look a few lines above, in order to figure out what kind of test was being executed, so that you can identify the piece of configure.ac that was wrongly translated to generate the error.

    Then, you need to review the corresponding piece of code. Look at common AS_* functions, and verify that the parameters are properly quoted:

    ​AS_IF([test "$enable_tests" = yes],
    
    - PKG_CHECK_MODULES([GLIB], [glib-2.0])
    
    + [PKG_CHECK_MODULES([GLIB], [glib-2.0])
    
      AC_CHECK_LIB([event], [event_base_new], [EVENT_LIBS=-levent])
    
    - AC_SUBST(EVENT_LIBS))
    
    + AC_SUBST(EVENT_LIBS)])
    
    ​

    In the example above, you can see that quotes were missing around the second argument of the AS_IF function. These quotes should be there even if there is only one function call as the second argument:

    -AS_IF([test "x$MD5PROG" = "x"], AC_CHECK_PROG([MD5PROG], [md5sum], [md5sum -t]), [])
    
    +AS_IF([test "x$MD5PROG" = "x"], [AC_CHECK_PROG([MD5PROG], [md5sum], [md5sum -t])], [])

    If you have some "if" statement, check that the "fi" is properly placed:

      AC_CHECK_LIB(edit, readline, [READLINE=edit EDITLINE_FLG=Y],
    
         AC_CHECK_LIB(editline, readline, [READLINE=editline EDITLINE_FLG=Y],
    
           AC_CHECK_LIB(readline, readline, [READLINE=readline EDITLINE_FLG=Y],
    
             [STD_EDITLINE=false
    
              if test "$EDITLINE_FLG" = "Y"; then
    
    -           AC_MSG_WARN([[[--with-system-editline specified, not found. Using bundled editline]]])])))
    
    +           AC_MSG_WARN([[[--with-system-editline specified, not found. Using bundled editline]]])
    
      fi
    
    +           ])))

    Finally, avoid to use AC_EGREP_CPP when AC_PREPROC_IFELSE can do the job (and more efficiently):

    dnl -------------------------
    
     dnl CHECK_HEADER_DEFINE(LABEL, HEADER [,ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ] ])
    
     AC_DEFUN([CHECK_HEADER_DEFINE],
    
     [
    
      AC_MSG_CHECKING("if $1 is defined in $2")
    
    - AC_EGREP_CPP(yes,
    
    -[#include <$2>
    
    -#ifdef $1
    
    -  yes
    
    + AC_PREPROC_IFELSE(
    
    +[[#include <$2>
    
    +#ifndef $1
    
    +#error not defined
    
     #endif
    
    -], [
    
    +]], [
    
      AC_MSG_RESULT(yes)
    
      [$3]
    
     ], [
    
      AC_MSG_RESULT(no)
    
      [$4]

    This change fixed a circular dependency introduced by a change in the implementation of AC_EGREP_CPP. A side effect is simpler shell code for the test: about 25 lines of shell code that got removed from the configure script, per CHECK_HEADER_DEFINE call.

    Conclusion

    Autoconf 2.72 may be made available in a future version of Red Hat Enterprise Linux, by then, it may be useful to take the time to build your components that make use of it, in order to prepare for this upgrade. At the time of writing, there are EPEL packages available with Autoconf 2.71, which is already a big step forward from Autoconf 2. 69.

    Last updated: August 14, 2023
    Disclaimer: Please note the content in this blog post has not been thoroughly reviewed by the Red Hat Developer editorial team. Any opinions expressed in this post are the author's own and do not necessarily reflect the policies or positions of Red Hat.

    Related Posts

  • 2022 Fall C++ Standards Committee Meeting trip report

  • Recent Posts

    • Meet the Red Hat Node.js team at PowerUP 2025

    • How to use pipelines for AI/ML automation at the edge

    • What's new in network observability 1.8

    • LLM Compressor: Optimize LLMs for low-latency deployments

    • How to set up NVIDIA NIM on Red Hat OpenShift AI

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue