OS X 上的体系结构 x86_64 的未定义符号与 fat 库
Undefined symbols for architecture x86_64 on OS X with fat library
我自己从源代码构建了 libcrypto.a
和 libssl.a
,将 darwin64-x86_64-cc
(对于 64 位)和 darwin-i386-cc
(对于 32 位)指定为 OpenSSL
的配置脚本。
使用 lipo
创建胖库并将它们作为依赖项添加到我的 Xcode
项目中。
但是,我遇到了一个未定义的符号错误:
undefined symbols for architecture x86_64:
"_OPENSSL_ia32cap_P", referenced from:
_AES_cbc_encrypt in libcrypto.a(aes-x86_64.o)
ld: symbol(s) not found for architecture x86_64
注意: 使用相同的技术对 iOS 效果很好。
lipo -detailed_info libcrypto.a
揭示:
Fat header in: libcrypto.a
fat_magic 0xcafebabe
nfat_arch 2
architecture i386
cputype CPU_TYPE_I386
cpusubtype CPU_SUBTYPE_I386_ALL
offset 48
size 2700624
align 2^2 (4)
architecture x86_64
cputype CPU_TYPE_X86_64
cpusubtype CPU_SUBTYPE_X86_64_ALL
offset 2700672
size 3938432
align 2^2 (4)
在静态库的情况下,它看起来是 x64 代码生成器中的错误。
最简单的非补丁 openssl 更改解决方法是在代码中的某处添加对 OPENSSL_cleanse
的引用,即使未使用它也是如此。这将修复 link 时间参考。
实际发生的是该符号在某些汇编代码中被引用。
汇编代码只是说 _OPENSSL_ia32cap_P
是一个外部符号,而没有使用交叉 link 来声明它需要被 link 编辑。这适用于 libcrypto.dylib
因为引用在生成.dylib
文件时被解析;然而,在 .a
的情况下,引用永远不会被解析,因为实际包含该符号的唯一代码是 x86_64cpuid.o
,如果您使用它提供的任何例程,它只会被 linked .o
.
此文件中的符号包括 OPENSSL_cleanse
,因此如果您引用此例程,link 有效。
我偶然发现了同样的 linker 错误,我也尝试添加行 extern int OPENSSL_cleanse(void *ptr, size_t len);
但没有成功。
最终对我有用的是在代码文件的任何位置添加以下行:
uint32_t OPENSSL_ia32cap_P[4] = { 0 };
此外,我使用了以下link作为参考:https://boringssl.googlesource.com/boringssl/+/517073cd4b/crypto/cpu-intel.c#76
我自己从源代码构建了 libcrypto.a
和 libssl.a
,将 darwin64-x86_64-cc
(对于 64 位)和 darwin-i386-cc
(对于 32 位)指定为 OpenSSL
的配置脚本。
使用 lipo
创建胖库并将它们作为依赖项添加到我的 Xcode
项目中。
但是,我遇到了一个未定义的符号错误:
undefined symbols for architecture x86_64:
"_OPENSSL_ia32cap_P", referenced from:
_AES_cbc_encrypt in libcrypto.a(aes-x86_64.o)
ld: symbol(s) not found for architecture x86_64
注意: 使用相同的技术对 iOS 效果很好。
lipo -detailed_info libcrypto.a
揭示:
Fat header in: libcrypto.a
fat_magic 0xcafebabe
nfat_arch 2
architecture i386
cputype CPU_TYPE_I386
cpusubtype CPU_SUBTYPE_I386_ALL
offset 48
size 2700624
align 2^2 (4)
architecture x86_64
cputype CPU_TYPE_X86_64
cpusubtype CPU_SUBTYPE_X86_64_ALL
offset 2700672
size 3938432
align 2^2 (4)
在静态库的情况下,它看起来是 x64 代码生成器中的错误。
最简单的非补丁 openssl 更改解决方法是在代码中的某处添加对 OPENSSL_cleanse
的引用,即使未使用它也是如此。这将修复 link 时间参考。
实际发生的是该符号在某些汇编代码中被引用。
汇编代码只是说 _OPENSSL_ia32cap_P
是一个外部符号,而没有使用交叉 link 来声明它需要被 link 编辑。这适用于 libcrypto.dylib
因为引用在生成.dylib
文件时被解析;然而,在 .a
的情况下,引用永远不会被解析,因为实际包含该符号的唯一代码是 x86_64cpuid.o
,如果您使用它提供的任何例程,它只会被 linked .o
.
此文件中的符号包括 OPENSSL_cleanse
,因此如果您引用此例程,link 有效。
我偶然发现了同样的 linker 错误,我也尝试添加行 extern int OPENSSL_cleanse(void *ptr, size_t len);
但没有成功。
最终对我有用的是在代码文件的任何位置添加以下行:
uint32_t OPENSSL_ia32cap_P[4] = { 0 };
此外,我使用了以下link作为参考:https://boringssl.googlesource.com/boringssl/+/517073cd4b/crypto/cpu-intel.c#76