Mac M1编译含x86汇编的C++项目:需改Makefile还是代码?
问题描述
已安装Xcode及所有C/C++库,尝试在Mac M1芯片上编译项目,甚至试过UTM/Ubuntu虚拟机,但均失败。编译时出现汇编约束无效、__builtin_ia32系列内置函数未定义、SSE头文件仅支持x86架构等错误,咨询仅修改Makefile能否解决问题,还是需要修改项目代码?
Makefile代码
default: g++ -O3 -c oldbloom/bloom.cpp -o oldbloom.o g++ -O3 -c bloom/bloom.cpp -o bloom.o # g++ -O3 -c sha256/sha256.c -o sha256.o gcc -O3 -c base58/base58.c -o base58.o gcc -O3 -c rmd160/rmd160.c -o rmd160.o g++ -O3 -c sha3/sha3.c -o sha3.o g++ -O3 -c sha3/keccak.c -o keccak.o gcc -O3 -c xxhash/xxhash.c -o xxhash.o g++ -O3 -c util.c -o util.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/Int.cpp -o Int.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/Point.cpp -o Point.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/SECP256K1.cpp -o SECP256K1.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/IntMod.cpp -o IntMod.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/Random.cpp -o Random.o g++ -m64 -mssse3 -Wno-unused-result -Wno-write-strings -O2 -c secp256k1/IntGroup.cpp -o IntGroup.o g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/ripemd160.o -c hash/ripemd160.cpp g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/sha256.o -c hash/sha256.cpp g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/ripemd160_sse.o -c hash/ripemd160_sse.cpp g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/sha256_sse.o -c hash/sha256_sse.cpp g++ -o keyhunt keyhunt.cpp base58.o rmd160.o hash/ripemd160.o hash/ripemd160_sse.o hash/sha256.o hash/sha256_sse.o bloom.o oldbloom.o xxhash.o util.o Int.o Point.o SECP256K1.o IntMod.o Random.o IntGroup.o sha3.o keccak.o -lm -lpthread rm -r *.o clean: rm keyhunt
编译错误信息
In file included from secp256k1/Int.cpp:18: secp256k1/Int.h:204:27: error: invalid output constraint '=d' in asm __asm__( "mulq %[b];" :"=d"(rhi),"=a"(rlo) :"1"(a),[b]"rm"(b)); ^ secp256k1/Int.h:211:43: error: invalid output constraint '=D' in asm __asm__ ("movq %1,%0;shrdq %3,%2,%0;" : "=D"(c) : "r"(a),"r"(b),"c"(n)); ^ secp256k1/Int.h:218:43: error: invalid output constraint '=D' in asm __asm__ ("movq %1,%0;shldq %3,%2,%0;" : "=D"(c) : "r"(b),"r"(a),"c"(n)); ^ secp256k1/Int.h:234:7: error: use of undeclared identifier '__builtin_ia32_addcarryx_u64' c = _addcarry_u64(c, _umul128(x[1], y, &h), carry, dst + 1); carry = h; ^ secp256k1/Int.h:223:32: note: expanded from macro '_addcarry_u64' #define _addcarry_u64(a,b,c,d) __builtin_ia32_addcarryx_u64(a,b,c,(long long unsigned int*)d); ^ secp256k1/Int.h:235:7: error: use of undeclared identifier '__builtin_ia32_addcarryx_u64' c = _addcarry_u64(c, _umul128(x[2], y, &h), carry, dst + 2); carry = h; ^ secp256k1/Int.h:223:32: note: expanded from macro '_addcarry_u64' #define _addcarry_u64(a,b,c,d) __builtin_ia32_addcarryx_u64(a,b,c,(long long unsigned int*)d); ^ secp256k1/Int.h:236:7: error: use of undeclared identifier '__builtin_ia32_addcarryx_u64' c = _addcarry_u64(c, _umul128(x[3], y, &h), carry, dst + 3); carry = h; ^ secp256k1/Int.h:223:32: note: expanded from macro '_addcarry_u64' #define _addcarry_u64(a,b,c,d) __builtin_ia32_addcarryx_u64(a,b,c,(long long unsigned int*)d); ^ secp256k1/Int.h:237:7: error: use of undeclared identifier '__builtin_ia32_addcarryx_u64' c = _addcarry_u64(c, _umul128(x[4], y, &h), carry, dst + 4); carry = h; ^ secp256k1/Int.h:223:32: note: expanded from macro '_addcarry_u64' #define _addcarry_u64(a,b,c,d) __builtin_ia32_addcarryx_u64(a,b,c,(long long unsigned int*)d); ^ secp256k1/Int.h:253:7: error: use of undeclared identifier '__builtin_ia32_addcarryx_u64' c = _addcarry_u64(c, _umul128(x[1], y, &h), carry, dst + 1); carry = h; ^ secp256k1/Int.h:223:32: note: expanded from macro '_addcarry_u64' #define _addcarry_u64(a,b,c,d) __builtin_ia32_addcarryx_u64(a,b,c,(long long unsigned int*)d); ^ secp256k1/Int.h:254:7: error: use of undeclared identifier '__builtin_ia32_addcarryx_u64' c = _addcarry_u64(c, _umul128(x[2], y, &h), carry, dst + 2); carry = h; ^ secp256k1/Int.h:223:32: note: expanded from macro '_addcarry_u64' #define _addcarry_u64(a,b,c,d) __builtin_ia32_addcarryx_u64(a,b,c,(long long unsigned int*)d); ^ secp256k1/Int.h:255:7: error: use of undeclared identifier '__builtin_ia32_addcarryx_u64' c = _addcarry_u64(c, _umul128(x[3], y, &h), carry, dst + 3); carry = h; ^ secp256k1/Int.h:223:32: note: expanded from macro '_addcarry_u64' #define _addcarry_u64(a,b,c,d) __builtin_ia32_addcarryx_u64(a,b,c,(long long unsigned int*)d); ^ secp256k1/Int.h:262:3: error: use of undeclared identifier '__builtin_ia32_addcarryx_u64' _addcarry_u64(c, 0ULL, carry, dst + (NB64BLOCK - 1)); ^ secp256k1/Int.h:223:32: note: expanded from macro '_addcarry_u64' #define _addcarry_u64(a,b,c,d) __builtin_ia32_addcarryx_u64(a,b,c,(long long unsigned int*)d); ^ In file included from secp256k1/Int.cpp:24: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/emmintrin.h:14:2: error: "This header is only meant to be used on x86 and x64 architecture" #error "This header is only meant to be used on x86 and x64 architecture" ^ In file included from secp256k1/Int.cpp:24: In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/emmintrin.h:17: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/xmmintrin.h:14:2: error: "This header is only meant to be used on x86 and x64 architecture" #error "This header is only meant to be used on x86 and x64 architecture" ^ In file included from secp256k1/Int.cpp:24: In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/emmintrin.h:17: In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/xmmintrin.h:17: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/mmintrin.h:14:2: error: "This header is only meant to be used on x86 and x64 architecture" #error "This header is only meant to be used on x86 and x64 architecture" ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/mmintrin.h:37:5: error: use of undeclared identifier '__builtin_ia32_emms'; did you mean '__builtin_isless'? __builtin_ia32_emms(); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/mmintrin.h:37:5: note: '__builtin_isless' declared here /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/mmintrin.h:37:25: error: too few arguments to function call, expected 2, have 0 __builtin_ia32_emms(); ~~~~~~~~~~~~~~~~~~~~^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/mmintrin.h:54:19: error: use of undeclared identifier '__builtin_ia32_vec_init_v2si' return (__m64)__builtin_ia32_vec_init_v2si(__i, 0); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/mmintrin.h:71:12: error: use of undeclared identifier '__builtin_ia32_vec_ext_v2si' return __builtin_ia32_vec_ext_v2si((__v2si)__m, 0); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/mmintrin.h:133:19: error: use of undeclared identifier '__builtin_ia32_packsswb' return (__m64)__builtin_ia32_packsswb((__v4hi)__m1, (__v4hi)__m2); ^ fatal error: too many errors emitted, stopping now [-ferror-limit=] 20 errors generated.
解答
仅修改Makefile无法解决问题,必须修改项目代码,核心原因如下:
- 架构专属的内联汇编:错误中的
=d、=D是x86架构特有的寄存器约束,M1属于ARM64架构,寄存器命名和约束规则完全不同,这些硬编码的内联汇编无法在ARM平台运行,必须重写为ARM兼容的内联汇编,或者改用纯C/C++逻辑替代。 - x86特有的内置函数:
__builtin_ia32_addcarryx_u64是GCC为x86架构提供的专用内置函数,ARM平台没有对应实现,需要替换为ARM架构的等效内置函数(如__builtin_arm_addc系列),或者用标准C代码手动实现进位加法逻辑。 - SSE指令集依赖:项目引用的
emmintrin.h、xmmintrin.h是x86架构SSE指令集的头文件,ARM平台不支持SSE,而是使用NEON指令集。涉及SSE的优化代码(如hash/ripemd160_sse.cpp、hash/sha256_sse.cpp)需要重写为NEON版本,或者移除SSE优化路径,改用通用实现。
如果UTM/Ubuntu虚拟机编译失败,可能是虚拟机默认采用ARM64架构,可尝试切换到x86_64架构的虚拟机,此时可修改Makefile移除-mssse3等x86特定编译选项,但如果项目硬编码了x86专属实现,仍需修改代码适配。
内容的提问来源于stack exchange,提问作者lepy
相关产品推荐
相关产品推荐

