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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
+
+ 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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
+ 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