我已经下载了最新的libgcrypt&来自https://www.gnupg.org/download/index.html的libgpg错误库。我已经使用./configure --enable-static --disable-shared成功构建了(命令行)两个库。制作在我的Mac上安装make(Mavericks w / OSX 10.10和最新的Xcode 6.1)。
我可以从我正在构建的OS X客户端应用程序链接到这些新库。到现在为止还挺好。刚刚好。但是,我还需要使用相同的源代码构建iOS客户端。
问题:
1)对于我需要为(模拟器,Mac和iOS)构建通用静态库所需的库的命令行构建序列有哪些修改? 2)或者我是否需要为iOS构建单独的静态库?如果是这样,那么,我需要使用什么命令行魔法才能完成目标架构?
答案 0 :(得分:12)
请注意,无法构建适用于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
我只是将该脚本放在一起并验证它是否有效(对于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
答案 1 :(得分:1)
Jeremy给出了一个很好的答案,但我想补充一些东西并提供我的两分钱。
#!/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
标志。如果您的-arch
或-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。