我的桌面应用程序依赖于Crypto ++库。首先,我尝试从Brew安装Crypto ++并链接到我的应用程序。当我尝试将应用程序运行到较旧的mac(使用较旧的cpu,我认为没有AESNI指令)时,第一个错误已经到了。它崩溃了:
Crashed Thread: 56
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Illegal instruction: 4
Termination Reason: Namespace SIGNAL, Code 0x4
Terminating Process: exc handler [0]
之后我用较旧的mac编译了crytpo ++。到目前为止一切都很好。但是最近我遇到了同样的错误,甚至更老的cpu。
基本上问题是:有没有办法编译Crypto ++所以部署的lib会跨平台?
答案 0 :(得分:1)
...问题是:有没有办法编译crypto ++所以部署的lib会跨平台?
是的,但仅限于处理器系列。
问题可能是使用较新的指令,但不是AES。我怀疑它有三个原因。
首先,makefile在构建时添加-march=native
。这将为您提供正在构建的计算机的所有CPU功能。
其次,较新的指令可能来自SSE4,AVX或BMI,因为你在较新的Mac上编译;而对于Core2 Duo,你的旧版Mac只能处理SSE4。
第三,AES在运行时受到保护,因此如果CPU缺少AESNI,则不会执行这些特定的机器指令。但是,编译器可能发出的其他指令(如AVX或BMI)不受保护。
这是我的OS X测试环境:
根据上面的列表,如果我在MacBook Pro(SSE 4.1,SSE 4.2,AESNI,RDRAND,AVX)上为MacBook(SSE 4.1)编译,那么我需要将目标机器限制为SSE 4.1。否则,Clang肯定会发出较旧的MacBook无法处理的指令。
在Crypto ++中限制目标机器:
git clone https://github.com/weidai11/cryptopp.git
cd cryptopp
export CXXFLAGS="-DNDEBUG -g2 -O2 -DDISABLE_NATIVE_ARCH=1 -msse2 -msse3 -mssse3 -msse4.1"
make -j 4
-DDISABLE_NATIVE_ARCH
是一个相对较新的补充。我不相信它在Crypto ++ 5.6.5中。你需要掌握它,它将在即将到来的Crypto ++ 6.0中。
如果您需要删除添加-march=native
的makefile代码,那么不难找到。打开GNUmakefile
,并在第200行周围删除此块:
# BEGIN_NATIVE_ARCH
# Guard use of -march=native (or -m{32|64} on some platforms)
# Don't add anything if -march=XXX or -mtune=XXX is specified
ifeq ($(DISABLE_NATIVE_ARCH),0)
ifeq ($(findstring -march,$(CXXFLAGS)),)
ifeq ($(findstring -mtune,$(CXXFLAGS)),)
ifeq ($(GCC42_OR_LATER)$(IS_NETBSD),10)
CXXFLAGS += -march=native
else ifneq ($(CLANG_COMPILER)$(INTEL_COMPILER),00)
CXXFLAGS += -march=native
else
# GCC 3.3 and "unknown option -march="
# Ubuntu GCC 4.1 compiler crash with -march=native
# NetBSD GCC 4.8 compiler and "bad value (native) for -march= switch"
# Sun compiler is handled below
ifeq ($(SUN_COMPILER)$(IS_X64),01)
CXXFLAGS += -m64
else ifeq ($(SUN_COMPILER)$(IS_X86),01)
CXXFLAGS += -m32
endif # X86/X32/X64
endif
endif # -mtune
endif # -march
endif # DISABLE_NATIVE_ARCH
# END_NATIVE_ARCH
之后,您应该能够在两台计算机上运行二进制文件。
GNUmakefile是一种怪物。这里有很多东西。我们在Crypto ++ wiki的GNUmakefile上记录了它。
您还可以使用-mtune
限制要编译的机器。例如:
$ export CXXFLAGS="-DNDEBUG -g2 -O2 -mtune=core2"
$ make -j 3
g++ -DNDEBUG -g2 -O2 -mtune=core2 -fPIC -pipe -c cryptlib.cpp
g++ -DNDEBUG -g2 -O2 -mtune=core2 -fPIC -pipe -c cpu.cpp
g++ -DNDEBUG -g2 -O2 -mtune=core2 -fPIC -pipe -c integer.cpp
...
首先,我尝试从Brew安装Crypto ++并链接到我的应用程序......
我不使用Brew,因此我不知道在使用它时如何设置CXXFLAGS
。希望其中一位Homebrew人员能提供一些有关它的信息。
也许Build and install Brew apps that are x86_64 instead of i386?和Using Homebrew with alternate GCC会有所帮助。
您也可以在x86_64机器上进行编译,然后尝试在i386机器上运行它。如果是这种情况,则可能无效。
您可以使用以下内容构建胖库,它可以在两台计算机上运行。请注意添加-arch x86_64 -arch i386
。
export CXXFLAGS="-DNDEBUG -g2 -O2 -DDISABLE_NATIVE_ARCH=1 -arch x86_64 -arch i386 -msse2 -msse3 -mssse3 -msse4.1"
make -j 4
您可能也对Crypto ++ wiki上的iOS (Command Line)感兴趣。它详细介绍了iOS环境下的胖二进制文件。相同的概念适用于OS X.
如果遇到-msse4.1
或-msse4.2
的编译错误,则可能需要-msse4_1
或-msse4_2
。不同的编译器接受(或期望)稍微不同的语法。
为了使用Linux进行比较,下面是Core2 Duo和第三代Core i5之间的CPU功能差异。请注意,Core i5具有SSE4.2和AVX,而Core2 Duo则没有。 AVX煞费苦心,编译器积极地使用指令集。
在OS X上,您想要运行sysctl machdep.cpu.features
。我从2010年初开始为旧款MacBook展示了它。
Core i5 :
$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 58
model name : Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz
...
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca
cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc
rep_good nopl xtopology nonstop_tsc cpuid pni pclmulqdq ssse3 cx16 sse4_1
sse4_2 x2apic popcnt aes xsave avx rdrand hypervisor lahf_lm
Core2 Duo :
$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Duo CPU T6500 @ 2.10GHz
...
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca
cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm
constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64
monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm
Core Duo(MacBook) :
$ sudo sysctl machdep.cpu.features
machdep.cpu.features: FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE
MCA CMOV PAT PSE36 CLFSH DS ACPI MMX FXSR SSE SSE2 SS HTT TM PBE SSE3 DTES64
MON DSCPL VMX SMX EST TM2 SSSE3 CX16 TPR PDCM SSE4.1