Building a C library (GMP) for arm64 iOS

2019-06-23 04:20发布

问题:

I'm trying to build a C library (GMP 6.0.0) for arm64 for use on iOS. I'm running the configure script with the invocation below (compiler is as found using xcrun --find).

./configure \
CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" \
CPP="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -E" \
CPPFLAGS="-target arm64-apple-darwin -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/ -miphoneos-version-min=7.0" \
--host=aarch64-apple-darwin

However this fails at the following line ("long long reliability test 1"):

checking compiler /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -O2 -pedantic  -target arm64-apple-darwin -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/ -miphoneos-version-min=7.0... no, long long reliability test 1
configure: error: could not find a working compiler, see config.log for details

Full config.log available here. It shows multiple warning and errors for the long long reliability test compile, including the following:

conftest.c:9:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
f(){static const struct{t1 n;t1 src[9];t1 want[9];}d[]={{1,{0},{1}},};t1 got[9];int i;
^
conftest.c:10:44: error: implicit declaration of function 'h' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
for(i=0;i<1;i++){if(e(got,got,9,d[i].n)==0)h();g(i,d[i].src,d[i].n,got,d[i].want,9);if(d[i].n)h();}}
                                           ^
conftest.c:10:48: error: implicit declaration of function 'g' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
for(i=0;i<1;i++){if(e(got,got,9,d[i].n)==0)h();g(i,d[i].src,d[i].n,got,d[i].want,9);if(d[i].n)h();}}
                                               ^
conftest.c:10:100: warning: control reaches end of non-void function [-Wreturn-type]
for(i=0;i<1;i++){if(e(got,got,9,d[i].n)==0)h();g(i,d[i].src,d[i].n,got,d[i].want,9);if(d[i].n)h();}}
                                                                                                   ^

Using --host=none it works fine, but I'd really like to figure out how to build it with assembly optimized for arm64.

My system is x86_64-apple-darwin13.1.0 (or coreisbr-apple-darwin13.1.0 according to config.guess), an early '11 Core i7 MBP running OS X v10.9.2. I'm using Xcode 5.1 (5B130a).

Any help appreciated.

EDIT 1

Compiling for ARMv7 passes configure, but fails on make (full configure/make output here), apparently while compiling some assembly:

tmp-dive_1.s:165:18: error: unexpected token in '.section' directive
 .section .rodata
                 ^

EDIT 2

@MarcGlisse: By forcing clang to ignore the errors as suggested (-Wno-...) arm64 passes configure, but then fails on make (full output here):

tmp-mul_1.s:59:2: error: unrecognized instruction mnemonic
 bcc Lfi1
 ^
tmp-mul_1.s:60:2: error: unrecognized instruction mnemonic
 beq Lfi2
 ^

As a side note: these commits, I assume intended to remove the need for suppressing the error, don't seem to work i.e. I get the same error when removing the supression.

For armv7, using these commits as suggested fixes the .section error, but make fails later on with the following (full output here):

tmp-mode1o.s:64:2: error: unknown directive
 .protected ___gmp_binvert_limb_table
 ^

EDIT 3

Using the suggested edits, armv7, armv7s, i386 and x86_64 now all compile with assembly!

For arm64 the edits get it past the previous error, but now gives several errors about an invalid input constraint 'rZ', all in the same file (full output here):

divrem_1.c:237:5: error: invalid input constraint 'rZ' in asm
                  udiv_qrnnd_preinv (*qp, r, r, nshift, d, dinv);
                  ^
../gmp-impl.h:3062:2: note: expanded from macro 'udiv_qrnnd_preinv'
        add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl));                \
        ^
../longlong.h:551:7: note: expanded from macro 'add_ssaaaa'
           : "rZ" (ah), "rZ" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC)

EDIT 4

After commenting out add_ssaaaa and sub_ddmmss in longlong.h and editing some more assembly instructions in gcd_1.asm (blo to b.lo etc.), it now fails with several of the following errors (full output here):

tmp-invert_limb.s:75:22: error: immediate value expected for shifter operand
 add x1, x1, x2, lsr 1
                     ^
tmp-invert_limb.s:75:22: error: invalid operand for instruction
 add x1, x1, x2, lsr 1
                     ^

I'll post a total diff later.

EDIT 5

Ok, that gets us another step further, but it now hits into (full output here):

tmp-invert_limb.s:52:2: error: ADR/ADRP relocations must be GOT relative
 adrp x1, approx_tab
 ^

If this keeps going it might be better to continue this via email.

回答1:

Copyright issues aside...

GMP may not be compatible with Apple's proprietary CPU, and may not be compatible with Clang/LLVM. Being a GNU project it is probably more thoroughly tested with GCC on non-proprietary chipsets.

A quick search shows historically at least there have been issues compiling GMP with clang.

You really should email the GMP community and ask for help on this one.