libgcrypt: ARM64 Builds on macOS fail
Open, NormalPublic

Description

I tried to build libgcrypt on macOS for ARM64 ("Apple Silicon"), using clang (the default compiler shipped with XCode). I cross-compile on x86_64 for arm using --host=aarch64-apple-darwin

The build fails with the following error:

/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..  -I../src -I../src -I/Users/patrick/gnupg22/distarm64/include -Ofast -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk  -arch arm64  -Ofast -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk -MT mpih-add1-asm.lo -MD -MP -MF .deps/mpih-add1-asm.Tpo -c -o mpih-add1-asm.lo mpih-add1-asm.S
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../src -I../src -I/Users/patrick/gnupg22/distarm64/include -Ofast -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk -arch arm64 -Ofast -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk -MT mpih-add1-asm.lo -MD -MP -MF .deps/mpih-add1-asm.Tpo -c mpih-add1-asm.S  -fno-common -DPIC -o .libs/mpih-add1-asm.o
mpih-add1-asm.S:37:1: error: unknown directive
.type _gcry_mpih_add_n,%function
^
mpih-add1-asm.S:71:1: error: unknown directive
.size _gcry_mpih_add_n,.-_gcry_mpih_add_n;
^
make[2]: *** [mpih-add1-asm.lo] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

The build succeeds using --disable-adm but I'm not sure about the negative performance impact.

Details

Version
libgcrypt 1.8.7
patrick created this task.Nov 28 2020, 11:27 AM
werner added a subscriber: werner.

You say that you build using clang but the log shows that you invoke gcc.

Sorry, I forgot to mention that Apple ships a gcc-wrapper for clang. It just accepts gcc command lines parameters and translates them to clang parameters.
Here is the output of gcc --version:

gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.27)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

And the arm64 cross-compiler:

gcc -arch arm64 --version
Apple clang version 12.0.0 (clang-1200.0.32.27)
Target: aarch64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Why the hell do they that? The standard compiler on a system is called cc which may translated to whatever the system installs for it. gcc is a specific implementation with certain properties. Di you try CC=clang to override this?

Yes, I did. Identical result.

gniibe added a subscriber: gniibe.Nov 30 2020, 2:48 AM

ARM64 has been only tested on platforms which support ELF.

While it doesn't looks good (using AMD64 even if it's ARM64), I think this patch should be applied:

diff --git a/cipher/asm-common-aarch64.h b/cipher/asm-common-aarch64.h
index 4ffc1b71..f5029b55 100644
--- a/cipher/asm-common-aarch64.h
+++ b/cipher/asm-common-aarch64.h
@@ -23,7 +23,7 @@
 
 #include <config.h>
 
-#ifdef __ELF__
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
 # define ELF(...) __VA_ARGS__
 #else
 # define ELF(...) /*_*/

HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS is never defined on ARM64 as it depends on "$mpi_cpu_arch" == "x86". Instead I think new check for GCC assembly ELF directives would be needed in configure.ac, similar to HAVE_GCC_ASM_CFI_DIRECTIVES check. Following check should work, but I have not yet tested it:

#
# Check whether GCC assembler supports for ELF directives.
#
AC_CACHE_CHECK([whether GCC assembler supports for ELF directives],
       [gcry_cv_gcc_asm_elf_directives],
       [gcry_cv_gcc_asm_elf_directives=no
        AC_LINK_IFELSE([AC_LANG_PROGRAM( 
          [[__asm__(
                /* Test if ELF directives '.type' and '.size' are supported.  */
                "asmfunc:\n\t"
                ".size asmfunc,.-asmfunc;\n\t"
                ".type asmfunc,STT_FUNC;\n\t"
            );]])],
          [gcry_cv_gcc_asm_elf_directives=yes])])
if test "$gcry_cv_gcc_asm_elf_directives" = "yes" ; then
   AC_DEFINE(HAVE_GCC_ASM_ELF_DIRECTIVES,1,
             [Defined if underlying assembler supports for ELF directives])
fi

Another issue that comes in to mind is that current ARM/ARM64 HW feature detection most likely wont work on MacOS. Thus HW accelerated AES&SHA&GHASH implementation wont be used.

ARM64 has been only tested on platforms which support ELF.

While it doesn't looks good (using AMD64 even if it's ARM64), I think this patch should be applied:

diff --git a/cipher/asm-common-aarch64.h b/cipher/asm-common-aarch64.h
...

I tried to apply the patch on libgcrypt-1.8.7, but there is no file cipher/asm-common-aarch64.h.

The patch for configure.ac at least doesn't fail.

AArch64 clang support was added to 'master' on 2018-03-28. One would need to backport commits 8ee38806245ca8452051b1a245f44082323f37f6...9b58e4a03ba3aeff7bae3f40da706977870c9649 to 1.8 branch.

We should not do this.

OK, then we'll have to live with --disable-asm until the next major version is released, or switch to gcc.

werner triaged this task as Normal priority.Tue, Jan 5, 9:18 AM