The gnulib CIs also exercise compilation with clang, and it failed today:

clang -DHAVE_CONFIG_H -I. -I../../gllib -I..  -DGNULIB_STRICT_CHECKING=1 
-I/media/develdata/devel/inst-x86_64-64/include -Wall  -g -O2 -MT 
crc-x86_64-pclmul.o -MD -MP -MF .deps/crc-x86_64-pclmul.Tpo -c -o 
crc-x86_64-pclmul.o ../../gllib/crc-x86_64-pclmul.c
../../gllib/crc-x86_64-pclmul.c:27:13: warning: unknown pragma ignored 
[-Wunknown-pragmas]
#pragma GCC push_options
            ^
../../gllib/crc-x86_64-pclmul.c:28:13: warning: unknown pragma ignored 
[-Wunknown-pragmas]
#pragma GCC target("pclmul,avx")
            ^
../../gllib/crc-x86_64-pclmul.c:208:13: warning: unknown pragma ignored 
[-Wunknown-pragmas]
#pragma GCC pop_options
            ^
../../gllib/crc-x86_64-pclmul.c:83:16: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
          fold_high = _mm_clmulepi64_si128 (in1, shift544_shift480, 0x11);
                      ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:84:15: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
          fold_low = _mm_clmulepi64_si128 (in1, shift544_shift480, 0x00);
                     ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:87:16: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
          fold_high = _mm_clmulepi64_si128 (in2, shift544_shift480, 0x11);
                      ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:88:15: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
          fold_low = _mm_clmulepi64_si128 (in2, shift544_shift480, 0x00);
                     ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:91:16: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
          fold_high = _mm_clmulepi64_si128 (in3, shift544_shift480, 0x11);
                      ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:92:15: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
          fold_low = _mm_clmulepi64_si128 (in3, shift544_shift480, 0x00);
                     ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:95:16: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
          fold_high = _mm_clmulepi64_si128 (in4, shift544_shift480, 0x11);
                      ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:96:15: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
          fold_low = _mm_clmulepi64_si128 (in4, shift544_shift480, 0x00);
                     ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:133:19: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
      fold_high = _mm_clmulepi64_si128 (in1, shift160_shift96, 0x11);
                  ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:134:18: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
      fold_low = _mm_clmulepi64_si128 (in1, shift160_shift96, 0x00);
                 ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:164:19: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
      fold_high = _mm_clmulepi64_si128 (in1, shift160_shift96, 0x11);
                  ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:165:18: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
      fold_low = _mm_clmulepi64_si128 (in1, shift160_shift96, 0x00);
                 ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:180:9: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
  in1 = _mm_clmulepi64_si128 (shift96_shift64, in1, 0x00);
        ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:187:9: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
  in1 = _mm_clmulepi64_si128 (shift96_shift64, in2, 0x01);
        ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:194:9: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
  in2 = _mm_clmulepi64_si128 (mu_poly, in2, 0x00);
        ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
../../gllib/crc-x86_64-pclmul.c:198:9: error: '__builtin_ia32_pclmulqdq128' 
needs target feature pclmul
  in2 = _mm_clmulepi64_si128 (mu_poly, in2, 0x01);
        ^
/clang/14.0.0/include/__wmmintrin_pclmul.h:45:13: note: expanded from macro 
'_mm_clmulepi64_si128'
  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \
            ^
3 warnings and 16 errors generated.
make[3]: *** [Makefile:1123: crc-x86_64-pclmul.o] Error 1


This is reproducible with clang versions 7 to 19 (the newest one), for example
in a testdir:

  $ ./gnulib-tool --create-testdir --dir=../testdir1 --single-configure crc 
crc-x86_64

The reason is that clang does not support the '#pragma GCC target(...)'.


Three approaches to fix this are possible:

a) As suggested by Simon in
   <https://lists.gnu.org/archive/html/bug-gnulib/2024-12/msg00112.html>:
   Use the '#pragma GCC target(...)' also in configure.ac.
   Drawback: This means to disable the optimization when clang is used to
   build the package.

b) Use the per-object flag syntax from
   https://www.gnu.org/software/make/manual/html_node/Target_002dspecific.html:

     crc-x86_64-pclmul.o: CFLAGS += -mavx -mpclmul

   Drawback: This works with GNU make, FreeBSD make, NetBSD make, but not with
   OpenBSD make.

c) Use an ad-hoc library in the Makefile. This is well supported in Automake
   and thus does not cause portability problems.
   Drawback: It requires changes in gnulib-tool.

I picked approach c), and committed the two attached patches. Tested both
without libtool (in a testdir) and with libtool (in some package that uses
gnulib for some shared library).


2024-12-21  Bruno Haible  <br...@clisp.org>

        crc-x86_64: Fix compilation error with clang.
        * modules/crc-x86_64 (Makefile.am): Declare a separate library
        libpclmul.{a,la}.
        * lib/crc-x86_64-pclmul.c: Remove the GCC pragmas.

        gnulib-tool: Recognize @LT@, @la@, @lo@ tokens in module descriptions.
        * gnulib-tool.sh (func_emit_lib_Makefile_am): Replace @LT@, @la@, @lo@
        tokens.
        (func_emit_tests_Makefile_am): Likewise.
        * pygnulib/GLEmiter.py (GLEmiter.lib_Makefile_am): Likewise.
        (GLEmiter.tests_Makefile_am): Likewise.

>From ed7f79d453b773d0d0232640d243d63ee865490d Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sat, 21 Dec 2024 22:56:46 +0100
Subject: [PATCH 1/2] gnulib-tool: Recognize @LT@, @la@, @lo@ tokens in module
 descriptions.

* gnulib-tool.sh (func_emit_lib_Makefile_am): Replace @LT@, @la@, @lo@
tokens.
(func_emit_tests_Makefile_am): Likewise.
* pygnulib/GLEmiter.py (GLEmiter.lib_Makefile_am): Likewise.
(GLEmiter.tests_Makefile_am): Likewise.
---
 ChangeLog            |  9 +++++++++
 gnulib-tool.sh       | 12 ++++++++++++
 pygnulib/GLEmiter.py | 14 ++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index c9f61913d6..02a1a23ba3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2024-12-21  Bruno Haible  <br...@clisp.org>
+
+	gnulib-tool: Recognize @LT@, @la@, @lo@ tokens in module descriptions.
+	* gnulib-tool.sh (func_emit_lib_Makefile_am): Replace @LT@, @la@, @lo@
+	tokens.
+	(func_emit_tests_Makefile_am): Likewise.
+	* pygnulib/GLEmiter.py (GLEmiter.lib_Makefile_am): Likewise.
+	(GLEmiter.tests_Makefile_am): Likewise.
+
 2024-12-20  Bruno Haible  <br...@clisp.org>
 
 	stdint: Detect MSVC __typeof__ support.
diff --git a/gnulib-tool.sh b/gnulib-tool.sh
index c29de46b8f..b622d252a5 100755
--- a/gnulib-tool.sh
+++ b/gnulib-tool.sh
@@ -3798,10 +3798,12 @@ func_emit_lib_Makefile_am ()
   fi
   if test "$libtool" = true; then
     libext=la
+    objext=lo
     perhapsLT=LT
     sed_eliminate_LDFLAGS="$sed_noop"
   else
     libext=a
+    objext=o
     perhapsLT=
     sed_eliminate_LDFLAGS='/^lib_LDFLAGS[	 ]*+=/d'
   fi
@@ -3842,6 +3844,9 @@ func_emit_lib_Makefile_am ()
                 -e 's,lib_LTLIBRARIES,lib%_LTLIBRARIES,g' \
                 -e "$sed_eliminate_LDFLAGS" \
                 -e "$sed_eliminate_NMD" \
+                -e "s,@LT@,$perhapsLT,g" \
+                -e "s,@la@,$libext,g" \
+                -e "s,@lo@,$objext,g" \
                 -e 's,lib_\([A-Z][A-Z]*\),'"${libname}_${libext}"'_\1,g' \
                 -e 's,\$(GNULIB_,$('"${module_indicator_prefix}"'_GNULIB_,' \
                 -e 's,lib%_LIBRARIES,lib_LIBRARIES,g' \
@@ -4180,9 +4185,13 @@ func_emit_tests_Makefile_am ()
   witness_macro="$1"
   if test "$libtool" = true; then
     libext=la
+    objext=lo
+    perhapsLT=LT
     sed_eliminate_LDFLAGS="$sed_noop"
   else
     libext=a
+    objext=o
+    perhapsLT=
     sed_eliminate_LDFLAGS='/^lib_LDFLAGS[	 ]*+=/d'
   fi
   # Replace NMD, so as to remove redundant "$(MKDIR_P) '.'" invocations.
@@ -4222,6 +4231,9 @@ func_emit_tests_Makefile_am ()
                 -e 's,lib_LTLIBRARIES,lib%_LTLIBRARIES,g' \
                 -e "$sed_eliminate_LDFLAGS" \
                 -e "$sed_eliminate_NMD" \
+                -e "s,@LT@,$perhapsLT,g" \
+                -e "s,@la@,$libext,g" \
+                -e "s,@lo@,$objext,g" \
                 -e 's,lib_\([A-Z][A-Z]*\),libtests_a_\1,g' \
                 -e 's,\$(GNULIB_,$('"${module_indicator_prefix}"'_GNULIB_,' \
                 -e 's,lib%_LIBRARIES,lib_LIBRARIES,g' \
diff --git a/pygnulib/GLEmiter.py b/pygnulib/GLEmiter.py
index 7eb8b27d46..8bdaf2d191 100644
--- a/pygnulib/GLEmiter.py
+++ b/pygnulib/GLEmiter.py
@@ -702,10 +702,12 @@ def lib_Makefile_am(self, destfile: str, modules: list[GLModule], moduletable: G
             assign = '='
         if libtool:
             libext = 'la'
+            objext = 'lo'
             perhapsLT = 'LT'
             eliminate_LDFLAGS = False
         else:  # if not libtool
             libext = 'a'
+            objext = 'o'
             perhapsLT = ''
             eliminate_LDFLAGS = True
         if for_test:
@@ -739,6 +741,10 @@ def lib_Makefile_am(self, destfile: str, modules: list[GLModule], moduletable: G
                 # Replace NMD, so as to remove redundant "$(MKDIR_P) '.'" invocations.
                 # The logic is similar to how we define gl_source_base_prefix.
                 amsnippet1 = _eliminate_NMD(amsnippet1, automake_subdir)
+                # Replace @LT@, @la@, @lo@, depending on libtool.
+                amsnippet1 = amsnippet1.replace('@LT@', perhapsLT)
+                amsnippet1 = amsnippet1.replace('@la@', libext)
+                amsnippet1 = amsnippet1.replace('@lo@', objext)
                 pattern = re.compile(r'lib_([A-Z]+)', re.M)
                 amsnippet1 = pattern.sub(r'%s_%s_\1' % (libname, libext),
                                          amsnippet1)
@@ -992,9 +998,13 @@ def tests_Makefile_am(self, destfile: str, modules: list[GLModule], moduletable:
 
         if libtool:
             libext = 'la'
+            objext = 'lo'
+            perhapsLT = 'LT'
             eliminate_LDFLAGS = False
         else:  # if not libtool
             libext = 'a'
+            objext = 'o'
+            perhapsLT = ''
             eliminate_LDFLAGS = True
         if for_test:
             # When creating a package for testing: Attempt to provoke failures,
@@ -1034,6 +1044,10 @@ def tests_Makefile_am(self, destfile: str, modules: list[GLModule], moduletable:
                 # Replace NMD, so as to remove redundant "$(MKDIR_P) '.'" invocations.
                 # The logic is similar to how we define gl_source_base_prefix.
                 amsnippet1 = _eliminate_NMD(amsnippet1, False)
+                # Replace @LT@, @la@, @lo@, depending on libtool.
+                amsnippet1 = amsnippet1.replace('@LT@', perhapsLT)
+                amsnippet1 = amsnippet1.replace('@la@', libext)
+                amsnippet1 = amsnippet1.replace('@lo@', objext)
                 pattern = re.compile(r'lib_([A-Z]+)', re.M)
                 amsnippet1 = pattern.sub(r'libtests_a_\1', amsnippet1)
                 amsnippet1 = amsnippet1.replace('$(GNULIB_', '$(' + module_indicator_prefix + '_GNULIB_')
-- 
2.43.0

>From d35085480fc31ed92b20bea4abe8a0216be64363 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sat, 21 Dec 2024 22:59:18 +0100
Subject: [PATCH 2/2] crc-x86_64: Fix compilation error with clang.

* modules/crc-x86_64 (Makefile.am): Declare a separate library
libpclmul.{a,la}.
* lib/crc-x86_64-pclmul.c: Remove the GCC pragmas.
---
 ChangeLog               |  5 +++++
 lib/crc-x86_64-pclmul.c |  4 ----
 modules/crc-x86_64      | 12 +++++++++++-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 02a1a23ba3..70dfe4f0a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2024-12-21  Bruno Haible  <br...@clisp.org>
 
+	crc-x86_64: Fix compilation error with clang.
+	* modules/crc-x86_64 (Makefile.am): Declare a separate library
+	libpclmul.{a,la}.
+	* lib/crc-x86_64-pclmul.c: Remove the GCC pragmas.
+
 	gnulib-tool: Recognize @LT@, @la@, @lo@ tokens in module descriptions.
 	* gnulib-tool.sh (func_emit_lib_Makefile_am): Replace @LT@, @la@, @lo@
 	tokens.
diff --git a/lib/crc-x86_64-pclmul.c b/lib/crc-x86_64-pclmul.c
index edda2081ef..91f361d2ce 100644
--- a/lib/crc-x86_64-pclmul.c
+++ b/lib/crc-x86_64-pclmul.c
@@ -24,8 +24,6 @@
 
 #include <string.h>
 
-#pragma GCC push_options
-#pragma GCC target("pclmul,avx")
 uint32_t
 crc32_update_no_xor_pclmul (uint32_t crc, const void *buf, size_t len)
 {
@@ -204,5 +202,3 @@ crc32_update_no_xor_pclmul (uint32_t crc, const void *buf, size_t len)
 
   return crc;
 }
-
-#pragma GCC pop_options
diff --git a/modules/crc-x86_64 b/modules/crc-x86_64
index 2e4b5bf744..15876991ab 100644
--- a/modules/crc-x86_64
+++ b/modules/crc-x86_64
@@ -15,7 +15,17 @@ AC_REQUIRE([gl_CRC_X86_64_PCLMUL])
 
 Makefile.am:
 if GL_CRC_X86_64_PCLMUL
-lib_SOURCES += crc-x86_64-pclmul.c
+# We need a separate library, in order to compile crc-x86_64-pclmul.c with
+# particular CFLAGS.
+# (Recall that '#pragma GCC target (...)' works only with gcc, not with clang.
+# And the alternative approach of target-specific CFLAGS in 'make' syntax
+# <https://www.gnu.org/software/make/manual/html_node/Target_002dspecific.html>
+# is not portable: it does not work with OpenBSD 'make'.)
+noinst_@LT@LIBRARIES += libpclmul.@la@
+libpclmul_@la@_SOURCES = crc-x86_64-pclmul.c
+libpclmul_@la@_CFLAGS = $(AM_CFLAGS) -mavx -mpclmul
+lib_LIBADD += libpclmul_@la@-crc-x86_64-pclmul.@lo@
+lib_DEPENDENCIES += libpclmul.@la@
 endif
 
 Include:
-- 
2.43.0

Reply via email to