Dear all,

On Wed, Mar 04, 2026 at 01:33:10AM +0100, Bruno Haible wrote:
> See also the ticket <https://savannah.gnu.org/support/?111055>.
> There, two facts were mentioned:
> 
> * While libtool (version 2.5.3) does not support "-Xpreprocessor -fopenmp",
>   it does support "-Wp,-fopenmp".
> 
> * On macOS 26.2, with cc being "Apple clang version 17.0.0 
> (clang-1700.6.3.2)",
>   "cc -help" reports that the option '-fopenmp' exists.
>   Therefore it looks like trying "-Wp,-fopenmp" is only needed for older

GNU libtool 2.6.2 is released, and it understands "-Xpreprocessor -fopenmp".
Thus
I am pleased to attach a patch (which is based on what I had some time ago,
and mentioned here: 
https://gitlab.com/sagemath/lcalc/-/blob/14ec4fbc812dd828fe65e010b71acb3d74256844/m4/ax_openmp.m4
but reworked to the requirements of the project, hopefully,
for AC_OPENMP which allows for Apple clang
to be configured to use OpenMP, teaching it to understand "-Xpreprocessor 
-fopenmp".
I also added tests to test with OpenMP
installed, and they all pass. 
The change is also described in NEWS, and in doc/.
The patch is on top of 
commit b046829c22a822116bced40442d9bc6fb3038f6a
Author: KO Myung-Hun <[email protected]>
Date:   Wed Sep 16 00:45:52 2026 +0900
(from the github mirror, but hopefully it's the same. I have trouble
checking out from the git server at gnu.org)

On macOS (with Homebrew installed)
one has to jump a few hoops, as libomp is not installed in a location
known to the toolchain:

  gmake check TESTSUITEFLAGS='-j8 -k AC_OPENMP 
configure_options="CPPFLAGS=-I/opt/homebrew/opt/libomp/include 
  LDFLAGS=-L/opt/homebrew/opt/libomp/lib"'

and for  ./bootstrap to succeed, one needs to replace all instances of
"libtoolize" with "glibtoolize" in bin/autoreconf.in.
(and perl should be /usr/bin/perl. not the Homebrew perl,
counterintuitively).

Best,
Dima


From d46c2f464a1b26989bc4b7ee07a19880bd6333ab Mon Sep 17 00:00:00 2001
From: Dima Pasechnik <[email protected]>
Date: Tue, 6 Oct 2026 21:29:02 -0500
Subject: [PATCH] Apple clang support in AC_OPENMP

---
 NEWS              |  8 +++++++
 doc/autoconf.texi | 59 +++++++++++++++++++++++++++++++++++++++--------
 lib/autoconf/c.m4 | 40 ++++++++++++++++++++++++--------
 tests/c.at        | 14 +++++++----
 tests/fortran.at  |  6 +++--
 tests/local.at    |  4 +++-
 6 files changed, 105 insertions(+), 26 deletions(-)

diff --git a/NEWS b/NEWS
index 37b021e3..c1f6ff87 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,14 @@ GNU Autoconf NEWS - User visible changes.
 
 ** New features
 
+*** AC_OPENMP supports Apple's clang and, if needed, separate OpenMP runtime
+  libraries It now tries both '-Xpreprocessor -fopenmp' and '-Wp,-fopenmp', and
+  retries unsuccessful link tests with '-lomp' for every compiler option.  The
+  new output variables OPENMP_CLIBS, OPENMP_CXXLIBS, OPENMP_FLIBS, and
+  OPENMP_FCLIBS report any additional library needed for the current language.
+  Packages using AC_OPENMP should add the corresponding variable to their 
OpenMP
+  link commands after the object files.
+
 *** autom4te now supports defining M4 macros on the command line.
   The autom4te program now recognizes the command line options
   --define (-D) and --undefine (-U), and passes them along to M4.
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 5339a2d7..001d9a9c 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -7251,10 +7251,18 @@ etc.).
 @ovindex OPENMP_CXXFLAGS
 @ovindex OPENMP_FFLAGS
 @ovindex OPENMP_FCFLAGS
+@ovindex OPENMP_CLIBS
+@ovindex OPENMP_CXXLIBS
+@ovindex OPENMP_FLIBS
+@ovindex OPENMP_FCLIBS
 @caindex prog_c_openmp
 @caindex prog_cxx_openmp
 @caindex prog_f77_openmp
 @caindex prog_fc_openmp
+@caindex c_omplib
+@caindex cxx_omplib
+@caindex f77_omplib
+@caindex fc_omplib
 @uref{https://@/www.openmp.org/, OpenMP} specifies extensions of C, C++,
 and Fortran that simplify optimization of shared memory parallelism,
 which is a common problem on multi-core CPUs.
@@ -7274,17 +7282,33 @@ need to add @code{$(OPENMP_CFLAGS)} to @code{CPPFLAGS}. 
 The presence of
 OpenMP support is revealed at compile time by the preprocessor macro
 @code{_OPENMP}.
 
-Linking a program with @code{OPENMP_CFLAGS} typically adds one more
-shared library to the program's dependencies, so its use is recommended
-only on programs that actually require OpenMP.
-
-If the current language is C++, @code{AC_OPENMP} sets the variable
-@code{OPENMP_CXXFLAGS}, suitably for the C++ compiler.  The same remarks
-hold as for C.
+The macro also sets @code{OPENMP_CLIBS} to any additional library needed
+to link OpenMP programs, such as @option{-lomp}, or to empty if none is
+needed or OpenMP support is unavailable or disabled.  Add
+@code{$(OPENMP_CLIBS)} to @code{LIBS} (or to the appropriate Automake
+@code{LDADD} or @code{LIBADD} variable), so that it appears after object
+files on the link command line.  This library may be needed even when
+@code{OPENMP_CFLAGS} is empty.  The macro does not modify @code{CFLAGS},
+@code{CPPFLAGS}, @code{LDFLAGS}, or @code{LIBS} itself.
+
+Apple clang is tested with both @option{-Xpreprocessor -fopenmp} and
+@option{-Wp,-fopenmp}.  The OpenMP headers and runtime library must be
+installed separately; if they are outside the compiler's default search
+paths, supply the appropriate @option{-I} and @option{-L} options in
+@code{CPPFLAGS} and @code{LDFLAGS}, respectively.
+
+Linking a program with @code{OPENMP_CFLAGS} and @code{OPENMP_CLIBS}
+typically adds one more shared library to the program's dependencies, so
+its use is recommended only on programs that actually require OpenMP.
+
+If the current language is C++, @code{AC_OPENMP} sets the variables
+@code{OPENMP_CXXFLAGS} and @code{OPENMP_CXXLIBS}, suitabe for the C++
+compiler.  The same remarks hold as for C.
 
 If the current language is Fortran 77 or Fortran, @code{AC_OPENMP} sets
-the variable @code{OPENMP_FFLAGS} or @code{OPENMP_FCFLAGS},
-respectively.  Similar remarks as for C hold, except that
+the variables @code{OPENMP_FFLAGS} and @code{OPENMP_FLIBS}, or, respectively,
+@code{OPENMP_FCFLAGS} and @code{OPENMP_FCLIBS}. 
+Similar remarks as for C hold, except that
 @code{CPPFLAGS} is not used for Fortran, and no preprocessor macro
 signals OpenMP support.
 
@@ -7296,6 +7320,23 @@ latter.
 This macro caches its result in the @code{ac_cv_prog_c_openmp},
 @code{ac_cv_prog_cxx_openmp}, @code{ac_cv_prog_f77_openmp}, or
 @code{ac_cv_prog_fc_openmp} variable, depending on the current language.
+The value is @samp{unsupported} if OpenMP support was not found,
+@samp{none needed} if no extra compiler flags are needed, or the compiler
+flags otherwise.  The additional library is cached in
+@code{ac_cv_c_omplib}, @code{ac_cv_cxx_omplib}, @code{ac_cv_f77_omplib},
+or @code{ac_cv_fc_omplib}, respectively.
+
+When @option{--disable-openmp} is given, the cache variables are neither
+tested nor updated, and both output variables are empty.  Therefore,
+configure-time decisions about OpenMP support must also check
+@code{enable_openmp}.  For example, after invoking @code{AC_OPENMP} for C:
+
+@example
+AS_IF([test "$enable_openmp" != no &&
+       test "$ac_cv_prog_c_openmp" != unsupported],
+  [@var{action-if-supported}],
+  [@var{action-if-disabled-or-unsupported}])
+@end example
 
 @strong{Caution:} Some of the compiler options that @code{AC_OPENMP}
 tests, mean ``enable OpenMP'' to one compiler, but ``write output to a
diff --git a/lib/autoconf/c.m4 b/lib/autoconf/c.m4
index 07542d1a..c2d47a0b 100644
--- a/lib/autoconf/c.m4
+++ b/lib/autoconf/c.m4
@@ -2462,18 +2462,20 @@ m4_copy([_AC_LANG_OPENMP(Fortran 77)], 
[_AC_LANG_OPENMP(Fortran)])
 # AC_OPENMP
 # ---------
 # Check which options need to be passed to the C compiler to support OpenMP.
-# Set the OPENMP_CFLAGS / OPENMP_CXXFLAGS / OPENMP_FFLAGS variable to these
-# options.
+# Set the OPENMP_CFLAGS / OPENMP_CXXFLAGS / OPENMP_FFLAGS / OPENMP_FCFLAGS
+# variable to these options, and the corresponding OPENMP_*LIBS variable
+# to any additional library needed at link time.
 # The options are necessary at compile time (so the #pragmas are understood)
 # and at link time (so the appropriate library is linked with).
 # This macro takes care to not produce redundant options if $CC $CFLAGS already
 # supports OpenMP.
 #
 # For each candidate option, we do a compile test first, then a link test;
-# if the compile test succeeds but the link test fails, that means we have
-# found the correct option but it doesn't work because the libraries are
-# broken.  (This can happen, for instance, with SunPRO C and a bad combination
-# of operating system patches.)
+# if the compile test succeeds but the link test fails, retry with -lomp.
+# If neither link test succeeds, we have found the correct option but it
+# doesn't work because the libraries are missing or broken.  (This can
+# happen, for instance, with SunPRO C and a bad combination of operating
+# system patches.)
 #
 # Several of the options in our candidate list can be misinterpreted by
 # compilers that don't use them to activate OpenMP support; for example,
@@ -2488,13 +2490,17 @@ AC_DEFUN([AC_OPENMP],
    [AS_HELP_STRING([--disable-openmp], [do not use OpenMP])])]dnl
 [
   OPENMP_[]_AC_LANG_PREFIX[]FLAGS=
+  OPENMP_[]_AC_LANG_PREFIX[]LIBS=
   if test "$enable_openmp" != no; then
     AC_CACHE_CHECK([for $[]_AC_CC[] option to support OpenMP],
       [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp],
       [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='not found'
+      ac_cv_[]_AC_LANG_ABBREV[]_omplib=
       dnl Try these flags:
       dnl   (on by default)      ''
       dnl   GCC >= 4.2           -fopenmp
+      dnl   Apple Clang          -Xpreprocessor -fopenmp
+      dnl                        -Wp,-fopenmp
       dnl   SunPRO C             -xopenmp
       dnl   Intel C              -openmp
       dnl   SGI C, PGI C         -mp
@@ -2503,15 +2509,25 @@ AC_DEFUN([AC_OPENMP],
       dnl   Cray CCE             -homp
       dnl   NEC SX               -Popenmp
       dnl   Lahey Fortran (Linux)  --openmp
-      for ac_option in '' -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp -homp \
+      for ac_option in '' -fopenmp '-Xpreprocessor -fopenmp' -Wp,-fopenmp \
+                       -xopenmp -openmp -mp -omp -qsmp=omp -homp \
                        -Popenmp --openmp; do
 
         ac_save_[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
         _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $ac_option"
         AC_COMPILE_IFELSE([_AC_LANG_OPENMP],
-          [AC_LINK_IFELSE([_AC_LANG_OPENMP],
-            [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp=$ac_option],
-            [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='unsupported'])])
+          [ac_save_LIBS=$LIBS
+           for ac_openmp_lib in '' -lomp; do
+             LIBS="$ac_openmp_lib $ac_save_LIBS"
+             AC_LINK_IFELSE([_AC_LANG_OPENMP],
+               [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp=$ac_option
+                ac_cv_[]_AC_LANG_ABBREV[]_omplib=$ac_openmp_lib],
+               [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='unsupported'])
+             if test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" != unsupported; 
then
+               break
+             fi
+           done
+           LIBS=$ac_save_LIBS])
         _AC_LANG_PREFIX[]FLAGS=$ac_save_[]_AC_LANG_PREFIX[]FLAGS
 
         if test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" != 'not found'; then
@@ -2531,8 +2547,12 @@ AC_DEFUN([AC_OPENMP],
        test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" != 'none needed'; then
       OPENMP_[]_AC_LANG_PREFIX[]FLAGS="$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp"
     fi
+    if test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" != 'unsupported'; then
+      OPENMP_[]_AC_LANG_PREFIX[]LIBS="$ac_cv_[]_AC_LANG_ABBREV[]_omplib"
+    fi
   fi
   AC_SUBST([OPENMP_]_AC_LANG_PREFIX[FLAGS])
+  AC_SUBST([OPENMP_]_AC_LANG_PREFIX[LIBS])
 ])
 
 # _AC_OPENMP_SAFE_WD
diff --git a/tests/c.at b/tests/c.at
index 0683bbe9..da60edac 100644
--- a/tests/c.at
+++ b/tests/c.at
@@ -377,6 +377,7 @@ if test "X$ac_cv_prog_c_openmp" = Xunsupported; then
   AS_EXIT([77])
 fi
 CFLAGS="$CFLAGS $OPENMP_CFLAGS"
+LIBS="$OPENMP_CLIBS $LIBS"
 CPPFLAGS="$CPPFLAGS $OPENMP_CFLAGS"
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -384,7 +385,7 @@ AC_OUTPUT
 
 AT_DATA([Makefile.in],
 [[foo@EXEEXT@: foo.@OBJEXT@
-       @CC@ @CFLAGS@ @LDFLAGS@ -o $@ foo.@OBJEXT@
+       @CC@ @CFLAGS@ @LDFLAGS@ -o $@ foo.@OBJEXT@ @LIBS@
 
 foo.@OBJEXT@: foo.c
        @CC@ @CPPFLAGS@ @CFLAGS@ -c foo.c
@@ -431,6 +432,7 @@ if test "X$ac_cv_prog_cxx_openmp" = Xunsupported; then
   AS_EXIT([77])
 fi
 CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS"
+LIBS="$OPENMP_CXXLIBS $LIBS"
 CPPFLAGS="$CPPFLAGS $OPENMP_CXXFLAGS"
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -438,16 +440,20 @@ AC_OUTPUT
 
 AT_DATA([Makefile.in],
 [[foo@EXEEXT@: foo.@OBJEXT@
-       @CXX@ @CXXFLAGS@ @LDFLAGS@ -o $@ foo.@OBJEXT@
+       @CXX@ @CXXFLAGS@ @LDFLAGS@ -o $@ foo.@OBJEXT@ @LIBS@
 
 foo.@OBJEXT@: foo.cpp
        @CXX@ @CPPFLAGS@ @CXXFLAGS@ -c foo.cpp
 ]])
 
 AT_DATA([foo.cpp],
-[[int main (void)
+[[#include <omp.h>
+int main (void)
 {
-  return 0;
+  int nthreads = 0;
+#pragma omp parallel reduction (+:nthreads)
+  nthreads += omp_get_num_threads ();
+  return nthreads == 0;
 }
 ]])
 
diff --git a/tests/fortran.at b/tests/fortran.at
index 795eebdf..7fac062a 100644
--- a/tests/fortran.at
+++ b/tests/fortran.at
@@ -92,13 +92,14 @@ if test "X$ac_cv_prog_f77_openmp" = Xunsupported; then
   AS_EXIT([77])
 fi
 FFLAGS="$FFLAGS $OPENMP_FFLAGS"
+LIBS="$OPENMP_FLIBS $LIBS"
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
 ]])
 
 AT_DATA([Makefile.in],
 [[foo@EXEEXT@: foo.@OBJEXT@
-       @F77@ @FFLAGS@ @LDFLAGS@ -o $@ foo.@OBJEXT@
+       @F77@ @FFLAGS@ @LDFLAGS@ -o $@ foo.@OBJEXT@ @LIBS@
 
 foo.@OBJEXT@: foo.f
        @F77@ @FFLAGS@ -c foo.f
@@ -132,13 +133,14 @@ if test "X$ac_cv_prog_fc_openmp" = Xunsupported; then
   AS_EXIT([77])
 fi
 FCFLAGS="$FCFLAGS $OPENMP_FCFLAGS"
+LIBS="$OPENMP_FCLIBS $LIBS"
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
 ]])
 
 AT_DATA([Makefile.in],
 [[foo@EXEEXT@: foo.@OBJEXT@
-       @FC@ @FCFLAGS@ @LDFLAGS@ -o $@ foo.@OBJEXT@
+       @FC@ @FCFLAGS@ @LDFLAGS@ -o $@ foo.@OBJEXT@ @LIBS@
 
 foo.@OBJEXT@: foo.f
        @FC@ @FCFLAGS@ -c foo.f
diff --git a/tests/local.at b/tests/local.at
index c47769e1..2de38ff0 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -829,7 +829,7 @@ if test -f state-env.before && test -f state-env.after; then
       [ERLANG_INSTALL_LIB_DIR_.*|ERLANG_ERTS_VER|OBJC|OBJCPP|OBJCFLAGS],
       [OBJCXX|OBJCXXCPP|OBJCXXFLAGS],
       [GOC|GOFLAGS],
-      [OPENMP_(C|CXX)FLAGS],
+      [OPENMP_(C|CXX)(FLAGS|LIBS)],
       [LIBS|LIB@&t@OBJS|LTLIBOBJS|LDFLAGS],
       [INSTALL(_(DATA|PROGRAM|SCRIPT))?],
       [EXEEXT|OBJEXT],
@@ -903,6 +903,7 @@ fi
 #     - ac_cv_prog_(ac_ct_)?(CC|CXX|CPP|CXXCPP)
 #     + other ac_cv_c_* are renamed to ac_cv_cxx_*
 #     + OPENMP_CFLAGS is renamed to OPENMP_CXXFLAGS
+#     + OPENMP_CLIBS is renamed to OPENMP_CXXLIBS
 #   vary:NAME (where NAME is any identifier): ignore ac_cv_NAME
 #
 # Furthermore, it is okay for a non-cache variable initialized to empty in one
@@ -1000,6 +1001,7 @@ m4_define([_AT_CONFIG_CMP_PRUNE],
        /^ac_cv_prog_cxx_@<:@^=@:>@*=/ d
        s/^ac_cv_c_/ac_cv_cxx_/
        s/^OPENMP_CFLAGS=/OPENMP_CXXFLAGS=/
+       s/^OPENMP_CLIBS=/OPENMP_CXXLIBS=/
 ],
   [^vary:],
 [      /^ac_cv_]m4_bpatsubsts([$1], [\<vary:], [])[=/ d
-- 
2.54.0 (Apple Git-157)

Attachment: signature.asc
Description: PGP signature

        • ... Zack Weinberg
          • ... Dima Pasechnik
            • ... Jacob Bachmeyer
              • ... Michael Orlitzky
  • Re: fixing ... Bruno Haible via Discussion list for the autoconf build system
    • Re: fi... Dima Pasechnik
      • Re... Bruno Haible via Discussion list for the autoconf build system
    • Re: fi... Dima Pasechnik
      • Re... Bruno Haible via Discussion list for the autoconf build system
        • ... Dima Pasechnik
    • patch ... Dima Pasechnik

Reply via email to