交叉编译到静态库(libgcrypt)以在iOS上使用

我从https://www.gnupg.org/download/index.html下载了最新的libgcrypt和libgpg错误库。 我已经使用./configure –enable-static –disable-shared成功构建了(命令行)两个库。 制作 在我的Mac上安装make(Mavericks w / OSX 10.10和最新的Xcode 6.1)。

我可以从我正在构建的OS X客户端应用程序链接到这些新的libs。 到现在为止还挺好。 刚刚好。 但是,我还需要使用相同的源代码构建iOS客户端。

问题:

1)对于(模拟器,Mac和iOS)构建通用静态库所需的库的命令行构建序列有哪些修改? 2)或者我是否需要为iOS构建单独的静态库? 如果是这样,那么,我需要用什么命令行魔法来完成目标架构?

请注意,无法构建适用于iOS模拟器和macOS的通用库。 iOS / Intel和macOS / Intel在C运行时库(Libc)之上不兼容ABI。 这个答案用于向您展示如何为iOS目标交叉编译基于autoconf的项目,并且您可以轻松地将生成的静态存档整合在一起。

你会想做这样的事情:

#!/bin/bash -e -x OPT_FLAGS="-Os -g3" MAKE_JOBS=16 dobuild() { export CC="$(xcrun -find -sdk ${SDK} cc)" export CXX="$(xcrun -find -sdk ${SDK} cxx)" export CPP="$(xcrun -find -sdk ${SDK} cpp)" export CFLAGS="${HOST_FLAGS} ${OPT_FLAGS}" export CXXFLAGS="${HOST_FLAGS} ${OPT_FLAGS}" export LDFLAGS="${HOST_FLAGS}" ./configure --host=${CHOST} --prefix=${PREFIX} --enable-static --disable-shared make clean make -j${MAKE_JOBS} make install } SDK="iphoneos" ARCH_FLAGS="-arch armv7" HOST_FLAGS="${ARCH_FLAGS} -miphoneos-version-min=8.0 -isysroot $(xcrun -sdk ${SDK} --show-sdk-path)" CHOST="arm-apple-darwin" PREFIX="${HOME}/DEVICE_ARM" dobuild SDK="iphoneos" ARCH_FLAGS="-arch arm64" HOST_FLAGS="${ARCH_FLAGS} -miphoneos-version-min=8.0 -isysroot $(xcrun -sdk ${SDK} --show-sdk-path)" CHOST="arm-apple-darwin" PREFIX="${HOME}/DEVICE_ARM64" dobuild SDK="iphonesimulator" ARCH_FLAGS="-arch i386" HOST_FLAGS="${ARCH_FLAGS} -mios-simulator-version-min=8.0 -isysroot $(xcrun -sdk ${SDK} --show-sdk-path)" CHOST="i386-apple-darwin" PREFIX="${HOME}/SIM_i386" dobuild SDK="iphonesimulator" ARCH_FLAGS="-arch x86_64" HOST_FLAGS="${ARCH_FLAGS} -mios-simulator-version-min=8.0 -isysroot $(xcrun -sdk ${SDK} --show-sdk-path)" CHOST="x86_64-apple-darwin" PREFIX="${HOME}/SIM_x86_64" dobuild 

我只是将该脚本放在一起并validation它是否适用于Pixman(添加了–disable-libpng和跳过测试)。 您可能需要为libgcrypt自定义它,但它用于显示为iOS构建基于autoconf / automake / glibtool的项目的一般模式。

构建完成后,您将获得〜/ {DEVICE_ARM {,64},SIM_ {i386,x86_64}}中的内容,您可以将静态库组合在一起,也可以在项目中使用所有这些内容(链接器将发出有关的警告)缺少你可以忽略的“其他”档案的片段。

 lipo -create -output lib.a DEVICE_ARM/lib/lib.a DEVICE_ARM64/lib/lib.a SIM_i386/lib/lib.a SIM_x86_64/lib/lib.a 

杰里米给出了一个很好的答案,但我想补充一些东西并提供我的两分钱。

更新的脚本

 #!/bin/bash OPT_FLAGS="-O3 -g3" MAKE_JOBS=8 dobuild() { export CC CC=$(xcrun --find --sdk "${SDK}" gcc) export CXX CXX=$(xcrun --find --sdk "${SDK}" g++) export CPP CPP=$(xcrun --find --sdk "${SDK}" cpp) export CFLAGS CFLAGS="${HOST_FLAGS} ${OPT_FLAGS}" export CXXFLAGS CXXFLAGS="${HOST_FLAGS} ${OPT_FLAGS}" export LDFLAGS LDFLAGS="${HOST_FLAGS}" ./configure --host="${CHOST}" --prefix="${PREFIX}" --enable-static make clean make -j"${MAKE_JOBS}" make install } SDK="iphoneos" ARCH_FLAGS="-arch armv7 -arch armv7s -arch arm64" HOST_FLAGS="${ARCH_FLAGS} -miphoneos-version-min=8.0 -isysroot $(xcrun --sdk ${SDK} --show-sdk-path)" CHOST="arm-apple-darwin" PREFIX="${HOME}/DEVICE_ARM" dobuild SDK="iphonesimulator" ARCH_FLAGS="-arch x86_64" HOST_FLAGS="${ARCH_FLAGS} -mios-simulator-version-min=8.0 -isysroot $(xcrun --sdk ${SDK} --show-sdk-path)" CHOST="x86_64-apple-darwin" PREFIX="${HOME}/SIM_x86" dobuild 

iOS工具链由SDK分开,iphonesimulator有一个单独的SDK,macos,tvos,当然还有iphoneos。 对于每个SDK,您需要一次编译。 您可以将iphonesimulator和iphoneos输出整合到一个库中,因为它们包含不同的体系结构,但实际上它们不是使用相同的SDK编译的。 我建议不要使用混合SDK的超级二进制文件。

我为什么要这样做?

如果您正在编译库并需要它,那是因为库使用autoconf,或者在Boost和OpenSSL的情况下使用其他自定义构建系统。 编译SDK的关键是正确的clang-sysroot-miphoneos-ver-min-arch标志。 如果你得到-sysroot-sysroot标志错误,你会看到#error Unsupported architecture错误。

删除--disable-shared标志

即使我打算使用静态库,我也喜欢离开共享库的生成。 这通常意味着您将使用位置独立代码(-fPIC)进行编译,因此如果您决定将此库包含在共享库中,那么您就可以了。 此外,与未链接但已归档的静态库不同,共享库的链接通常会暴露丢失的对象。

线上有多种架构

你可以在行上传递多个-arch标志,你将获得FAT二进制文件。 这样可以节省编译过程中的麻烦和时间。

 $ lipo -info libwhatever.a Architectures in the fat file: libwhatver.a are: i386 x86_64 

删除体系结构

老实说,你需要i386支持吗? 如果您没有定位该设备,则不要包含该体系结构。 如果主机系统在Lion之前运行操作系统,则只需要i386。