用osxcross编译OpenSSL后MacOS运行报错及架构库存放问题咨询
使用osxcross编译OpenSSL并在MacOS运行的问题
问题背景
- 已成功编译安装OpenSSL 3.1.4,库文件存放在
$OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib/arm64目录,编译命令如下:
CC=arm64-apple-darwin23-clang \ RANLIB=arm64-apple-darwin23-ranlib \ AR=arm64-apple-darwin23-ar \ ./Configure darwin64-arm64 --libdir=lib/arm64 --prefix=$OSXCROSS_ROOT/target/x86_64-apple-darwin23 \ && make -j23 && make install_sw
- 编译测试应用的命令:
arm64-apple-darwin23-clang++ -Wl,-rpath,'$ORIGIN' \ -I $OSXCROSS_ROOT/target/x86_64-apple-darwin23/include \ -L $OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib/arm64 main.cpp \ -l crypto -l ssl
- 将二进制文件
a.out与OpenSSL的.dylib文件放在同一目录运行时,出现报错:
dyld[768]: Library not loaded: /home/saleem/software/osxcross/target/x86_64-apple-darwin23/lib/arm64/libcrypto.3.dylib Referenced from: <04632F08-9238-3EF3-B3A5-29719B88CD42> /Users/saleem/Desktop/test/a.out Reason: tried: '/home/saleem/software/osxcross/target/x86_64-apple-darwin23/lib/arm64/libcrypto.3.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/home/saleem/software/osxcross/target/x86_64-apple-darwin23/lib/arm64/libcrypto.3.dylib' (no such file), '/home/saleem/software/osxcross/target/x86_64-apple-darwin23/lib/arm64/libcrypto.3.dylib' (no such file) zsh: abort ./a.out
问题1:运行时库找不到的解决方法
MacOS动态库加载时,会优先使用编译时记录的库绝对路径(即install_name),即使设置了rpath为$ORIGIN也无效。解决步骤如下:
1. 查看库的当前install_name
在编译机器或Mac上执行:
otool -D libcrypto.3.dylib otool -D libssl.3.dylib
输出会显示编译机器上的绝对路径,比如/home/saleem/software/osxcross/target/x86_64-apple-darwin23/lib/arm64/libcrypto.3.dylib。
2. 修改库的install_name为相对路径
使用install_name_tool修改库的标识及依赖路径:
# 修改libcrypto的自身标识 install_name_tool -id "@rpath/libcrypto.3.dylib" libcrypto.3.dylib # 修改libssl的自身标识,并更新它对libcrypto的依赖路径 install_name_tool -id "@rpath/libssl.3.dylib" -change "/home/saleem/software/osxcross/target/x86_64-apple-darwin23/lib/arm64/libcrypto.3.dylib" "@rpath/libcrypto.3.dylib" libssl.3.dylib
3. 验证修改结果
再次执行otool确认:
otool -D libcrypto.3.dylib otool -L libssl.3.dylib
确保libcrypto的标识为@rpath/libcrypto.3.dylib,libssl中对libcrypto的依赖路径也变为@rpath/libcrypto.3.dylib。
4. 验证运行
将修改后的库与a.out放在同一目录,直接运行即可。若仍有问题,可临时设置环境变量验证:
DYLD_LIBRARY_PATH=. ./a.out
问题2:多架构库目录结构的优化方案
当前将arm64和x86_64库分别放在lib/arm64和lib/x86_64的方式是可行的,但有更优方案:
1. 合并为通用二进制(Fat Binary)
MacOS支持将不同架构的库合并为单个文件,编译应用时无需区分架构目录,运行时自动适配。合并命令:
# 合并libcrypto lipo -create $OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib/arm64/libcrypto.3.dylib $OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib/x86_64/libcrypto.3.dylib -output $OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib/libcrypto.3.dylib # 合并libssl lipo -create $OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib/arm64/libssl.3.dylib $OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib/x86_64/libssl.3.dylib -output $OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib/libssl.3.dylib # 更新软链接 ln -sf libcrypto.3.dylib $OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib/libcrypto.dylib ln -sf libssl.3.dylib $OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib/libssl.dylib
之后编译应用时直接使用-L $OSXCROSS_ROOT/target/x86_64-apple-darwin23/lib即可,无需指定架构子目录,生成的应用可同时在arm64和x86_64 Mac上运行。
2. 分目录+自动化编译脚本
若不想合并,可通过变量控制编译流程,提升维护性:
# 定义目标架构 ARCH=arm64 # 适配编译工具链 CC=${ARCH}-apple-darwin23-clang RANLIB=${ARCH}-apple-darwin23-ranlib AR=${ARCH}-apple-darwin23-ar # 编译OpenSSL ./Configure darwin64-${ARCH} --libdir=lib/${ARCH} --prefix=$OSXCROSS_ROOT/target/x86_64-apple-darwin23 \ && make -j23 && make install_sw
编译应用时同样用ARCH变量指定-L路径,切换架构只需修改ARCH值即可。
内容的提问来源于stack exchange,提问作者Saleem gagguturu
相关产品推荐
相关产品推荐

