我如何为armv6,armv7和i386编译静态库(fat)

时间:2010-05-08 08:18:26

标签: iphone xcode static-libraries universal-binary fat-binaries

我知道这个问题已多次提出,但我的目标与我在网上搜索的内容略有不同。具体来说,我已经能够为iPhone构建一个静态库,但我能够构建的最终胖文件只包含arm和i386架构(我不确定arm指的是:是v6还是v7?)。我无法专门为armv6和armv7编译,他们使用lipo合并两个架构。 lipo工具抱怨armv6和armv7库中都存在相同的架构(arm,而不是armv6或armv7)。

有人可以解释如何构建armv6和armv7,并使用lipo将这些库合并到一个胖文件中吗?

编辑:我需要构建不使用Xcode,而是直接编译传统的unix库。

4 个答案:

答案 0 :(得分:11)

我找到了一个很好的解决方案:Static Libs With Support to iOS 5 and Arm64

编辑:

解决方案是构建不同的体系结构,然后使用lipo通过命令行(或Rakefile)绑定它们。

首先用arm使用xcodebuild构建二进制文件:

xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphoneos7.0' clean build ARCHS='armv7 armv7s' IPHONEOS_DEPLOYMENT_TARGET='5.0' TARGET_BUILD_DIR='./build-arm' BUILT_PRODUCTS_DIR='./build-arm'

请注意,您必须设置IPHONEOS_DEPLOYMENT_TARGET ='5.0'和ARCHS ='armv7 armv7s',建议设置构建和产品目录以使事情更加清晰,请查看构建设置参考以获取此标志的更多详细信息

arm64的下一个版本:

xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphoneos7.0' clean build ARCHS='arm64' IPHONEOS_DEPLOYMENT_TARGET='7.0' TARGET_BUILD_DIR='./build-arm64' BUILT_PRODUCTS_DIR='./build-arm64'

注意ARCHS和IPHONEOS_DEPLOYMENT_TARGET的区别。我们还需要为模拟器构建,在这种情况下,我们必须将sdk更改为iphonesimulator7.0并首先为i386构建两个步骤:

xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphonesimulator7.0' clean build ARCHS='i386' IPHONEOS_DEPLOYMENT_TARGET='5.0' TARGET_BUILD_DIR='./build-i386' BUILT_PRODUCTS_DIR='./build-i386'

现在是棘手的部分!如果您只是根据Xcode设置将ARCHS更改为x86_86,则会出现如下错误:“x86_64不是有效的拱形”。为避免这种情况,只需添加VALID_ARCHS ='x86_64':

xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphonesimulator7.0' clean build ARCHS='x86_64' VALID_ARCHS='x86_64' IPHONEOS_DEPLOYMENT_TARGET='7.0' TARGET_BUILD_DIR='./build-x86_64' BUILT_PRODUCTS_DIR='./build-x86_64'

最后,我们只需要创建一个包含所有5种体系结构的胖二进制文件:

lipo -create './build-arm/libStaticLibDemo.a' './build-arm64/libStaticLibDemo.a' './build-i386/libStaticLibDemo.a' './build-x86_64/libStaticLibDemo.a' -output 'libStaticLibDemo.a'

作者创建了一个这样的工作示例,你可以得到它:https://github.com/diogot/StaticLibDemo


以下是该帖子的链接:Static Libs With Support to iOS 5 and Arm64

所有学分归Diogo Tridapalli所有。

答案 1 :(得分:7)

只需使用libtool将两个arm6和arm7版本链接在一起 - 这就是XCode所做的事情。但是,如果您尝试将这些静态库组合到新的超级库中,则会遇到问题。如果您需要这样做,请阅读this

如果你已经这样做了,那就是为什么lipo抱怨你的“armv6”库包含armv6和armv7。我的帖子有一个修复程序,因为你不使用XCode可能会更容易,但基本上你使用lipo -extract来确保你有一个瘦的armv6库和一个瘦的armv7库,然后再继续。

答案 2 :(得分:2)

确保将您的构建设置设置为Valid Architectures: armv6 armv7Architectures: Optimized (armv6 armv7)。这应该导致二进制优化v6和amp; V7。如果您不确定它是否成功,只需设置Architectures: Standard (armv6)并比较文件大小。优化应该产生两倍的大小(当我记得正确的时候)。

您也可以在二进制文件上使用lipo -info来查看所有包含的架构。

在我的应用程序的分发版本上运行它给了我:

ullrich ~/Code/.../build/Distribution-iphoneos/My.app (streaming)$ lipo -info My
Architectures in the fat file: My are: armv6 armv7 

答案 3 :(得分:2)

似乎没有必要在重新加入之前从胖库中提取(如jamie的回答中所述)。我正在使用apple的最终4.0 SDK,它似乎默认创建了胖armv6 / armv7库。

我之前就是这样指定输入库的架构:

$DEVROOT/usr/bin/lipo -arch arm $PROJECT_DIR/buildlib/Release-iphoneos/lib.a -arch i386 $PROJECT_DIR/buildlib/Release-iphonesimulator/lib.a -create -output $PROJECT_DIR/buildlib/lib.a

这在以后的SDK上失败了,但从(现在胖)arm lib中删除架构可以正常工作:

$DEVROOT/usr/bin/lipo $PROJECT_DIR/buildlib/Release-iphoneos/lib.a -arch i386 $PROJECT_DIR/buildlib/Release-iphonesimulator/lib.a -create -output $PROJECT_DIR/buildlib/lib.a

Lipo现在必须能够检测胖库中的架构。