问题描述
我正在尝试为我们的Xcode交叉编译设置CI。交叉编译会同时测试ARMv7和ARMv8。事情看起来不错,除了需要链接到ARMv8:
clang ++ -DNDEBUG -g2- O3 -fPIC -pipe -Wall -miphoneos-version-min = 7 -arch arm64 \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2 .sdk \
-stdlib = libc ++ -c cryptlib.cpp
clang ++ -DNDEBUG -g2 -O3 -fPIC -pipe -Wall -miphoneos-version-min = 7 -arch arm64 \
-isysroot /应用程序/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk \
-stdlib = libc ++ -c cpu.cpp
.. 。
clang ++ -o cryptest.exe -DNDEBUG -g2 -O3 -fPIC -pipe -Wall -miphoneos-version-min = 7 -arch arm64 \
-isysroot / Applications / Xcode .app / Contents / Developer / Platforms / iPhoneOS.platform / Developer / SDKs / iPhoneOS10.2.sdk \
-stdlib = libc ++ test.o bench1.o bench2.o ... ./libcryptopp.a
体系结构arm64的未定义符号:
CryptoP P :: CRC32_Update_ARMV8(unsigned char const *,unsigned long,unsigned int&),引用自:$ crypt $:$ CRC $:$ CRC32 :: Update(unsigned char const *,unsigned long)在libcryptopp.a中(crc.o)
CryptoPP :: CRC32C_Update_ARMV8(unsigned char const *,unsigned long,unsigned int&),引用自:
CryptoPP :: CRC32C ::在libcryptopp.a(crc.o)
ld中更新(unsigned char const *,unsigned long)
ld:找不到体系结构arm64
的符号clang:错误:链接器命令失败,退出代码为1(使用-v查看调用)
make:*** [cryptest.exe]错误1
我们显然没有运行输出工件 cryptest.exe
。我们只是编译并链接到测试对象。
该代码在LLVM Clang下进行了很好的测试。
全部ARMv8 / Aarch64机器具有CRC-32和CRC-32C;但是Crypto扩展名是可选的。该错误没有太大意义。
Clang是否缺少ARMv8 / Aarch64的CRC32?
下面是导致错误的代码。
#如果已定义(__ARM_FEATURE_CRC32)
void CRC32_Update_ARMV8(const uint8_t * s,size_t n,uint32_t& c)
{
for(;!IsAligned< uint32_t>(s)&& n> 0; s ++ ,n--)
c = __crc32b(c,* s);
for(; n> 4; s + = 4,n- = 4)
c = __crc32w(c,* s);
for(; n> 0; s ++,n--)
c = __crc32b(c,* s);
}
#endif
在Xcode 8.3.3下,我在__crc32 *()处遇到了编译错误。然后我添加了命令行开关
-march = armv8-a + crc
位于链接,则代码可以很好地编译。我使用iphone7 + / iOS10.3.1进行了测试,并且可以正常工作。
根据(ARM®体系结构参考手册
ARMv8,适用于ARMv8-架构配置文件 DDI0487B_a_armv8_arm.pdf:第A1-58页),crc32指令对于v8是可选的,对于v8.1是必需的。当我在iphone6 + / iOS9.3.3上运行相同程序时,它在__crc32 *()崩溃。我还使用内联汇编器对其进行了验证。因此,为避免崩溃,必须进行某种运行时检查。我还不完全了解,但是作为最后的手段,我们可以使用模型名称。
I'm attempting to set-up CI for our Xcode cross-compiles. The cross-compiles test both ARMv7 and ARMv8. Things look good except when it comes time to link for ARMv8:
clang++ -DNDEBUG -g2 -O3 -fPIC -pipe -Wall -miphoneos-version-min=7 -arch arm64 \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk \
-stdlib=libc++ -c cryptlib.cpp
clang++ -DNDEBUG -g2 -O3 -fPIC -pipe -Wall -miphoneos-version-min=7 -arch arm64 \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk \
-stdlib=libc++ -c cpu.cpp
...
clang++ -o cryptest.exe -DNDEBUG -g2 -O3 -fPIC -pipe -Wall -miphoneos-version-min=7 -arch arm64 \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk \
-stdlib=libc++ test.o bench1.o bench2.o ... ./libcryptopp.a
Undefined symbols for architecture arm64:
"CryptoPP::CRC32_Update_ARMV8(unsigned char const*, unsigned long, unsigned int&)", referenced from:
CryptoPP::CRC32::Update(unsigned char const*, unsigned long) in libcryptopp.a(crc.o)
"CryptoPP::CRC32C_Update_ARMV8(unsigned char const*, unsigned long, unsigned int&)", referenced from:
CryptoPP::CRC32C::Update(unsigned char const*, unsigned long) in libcryptopp.a(crc.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [cryptest.exe] Error 1
We obviously don't run the output artifact cryptest.exe
. We just compile and link to test things.
The code has been testing fine under LLVM Clang.
All ARMv8/Aarch64 machines have CRC-32 and CRC-32C; but the Crypto extensions are optional. The error does not make much sense.
Does Clang lack CRC32 for ARMv8/Aarch64?
Below is the code that's causing the errors.
#if defined(__ARM_FEATURE_CRC32)
void CRC32_Update_ARMV8(const uint8_t *s, size_t n, uint32_t& c)
{
for(; !IsAligned<uint32_t>(s) && n > 0; s++, n--)
c = __crc32b(c, *s);
for(; n > 4; s+=4, n-=4)
c = __crc32w(c, *s);
for(; n > 0; s++, n--)
c = __crc32b(c, *s);
}
#endif
Under Xcode 8.3.3, I came across the compile error at __crc32*(). Then I added the command line switch
-march=armv8-a+crc
as found at this link, then the code compiles well. I tested with iphone7+/iOS10.3.1 and it's working.
Note according to ARM's document ("ARM® Architecture Reference ManualARMv8, for ARMv8-A architecture profile" DDI0487B_a_armv8_arm.pdf: page A1-58), crc32 instructions are optional for v8 and mandatory for v8.1. When I ran the same program on iphone6+/iOS9.3.3, it crashed at __crc32*(). I also verified it with inline assembler. To avoid the crash, therefore, some kind of run-time check is necessary. I don't fully understand how, but as a last resort, we could use the model names.
这篇关于Clang是否缺少针对ARMv8 / Aarch64的CRC32?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!