Skip to main content
AI
  • Get started with AI

    • Red Hat AI

      Accelerate the development and deployment of enterprise AI solutions.

    • AI learning hub

      Explore learning materials and tools, organized by task.

    • AI interactive demos

      Click through scenarios with Red Hat AI, including training LLMs and more.

    • AI/ML learning paths

      Expand your Red Hat OpenShift AI knowledge using these learning resources.

    • AI quickstarts

      Focused AI use cases designed for fast deployment on Red Hat AI platforms.

    • No-cost AI training

      Foundational Red Hat AI training.

  • Featured resources

    • Red Hat OpenShift AI
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

Red Hat AI Factory with NVIDIA

Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.

Learn
  • Self-guided

    • Documentation

      Find answers, get step-by-step guidance, and learn how to use Red Hat products.

    • Learning paths

      Explore curated walkthroughs for common development tasks.

    • Guided learning

      Receive custom learning paths powered by our AI assistant.

    • See all learning
  • Hands-on

    • Developer Sandbox

      Spin up Red Hat's products and technologies without setup or configuration.

    • Interactive labs

      Learn by doing in these hands-on, browser-based experiences.

    • Interactive demos

      Click through product features in these guided tours.

  • Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics
  • Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
Build
  • Get started

    • Red Hat build of Podman Desktop

      A downloadable, local development hub to experiment with our products and builds.

    • Developer Sandbox

      Spin up Red Hat's products and technologies without setup or configuration.

  • Download products

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

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset
  • References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
Community
  • Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions
  • Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github
  • Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

Join the Red Hat Developer program

Download Red Hat products and project builds, access support documentation, learning content, and more.

ConsoleDocsSupport Search
New For you

Recommended

We'll recommend resources you may like as you browse. Try these suggestions for now.

  • Product downloads
  • Cheat sheets
  • Red Hat Developer learning portal
  • Developer blog
  • E-books
  • Developer Sandbox
Log in

Get more with a Red Hat Developer account

  • Product downloads
  • Console access
  • Event registration
  • Training & trials
Explore more account benefitsLog in or register

A subscription may be required for some services.

Contact us

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

    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

    • A day in the life of an NVIDIA H100 on Red Hat OpenShift 5

    • Migrate BuildConfigs to builds for Red Hat OpenShift with one plug-in install

    • Run Red Hat Enterprise Linux CoreOS on NVIDIA BlueField DPUs

    • Agent harness engineering: Separating model capabilities from enforcement

    • What's new for developers in Red Hat Enterprise Linux 10.3 and 9.9

    Red Hat Developers logo

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

    Red Hat legal and privacy links

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