Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat 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
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud 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

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • 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

    • What's New in OpenShift GitOps 1.18

    • Beyond a single cluster with OpenShift Service Mesh 3

    • Kubernetes MCP server: AI-powered cluster management

    • Unlocking the power of OpenShift Service Mesh 3

    • Run DialoGPT-small on OpenShift AI for internal model testing

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    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
    © 2025 Red Hat

    Red Hat legal and privacy links

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

    Report a website issue