18

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

有人可以准确解释如何为 armv6 和 armv7 构建,然后他们使用 lipo 将这些库合并到一个 fat 文件中吗?

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

4

4 回答 4

12

这是我发现的一个很好的解决方案:支持 iOS 5 和 Arm64 的静态库

编辑:

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

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

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',建议设置 build 和 product dirs 以使事情更清楚,请查看 Build Setting Reference 了解更多详细信息此标志的含义。

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 is not a valid arch”。为避免这种情况,只需添加 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


这是帖子的链接:支持 iOS 5 和 Arm64 的静态库

所有学分都归于 Diogo Tridapalli。

于 2013-12-11T10:36:50.513 回答
8

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

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

于 2010-06-11T06:57:02.600 回答
3

在重新加入之前似乎不需要从 fat 库中提取(如 jamie 的回答中所述)。我正在使用来自苹果的最终 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 现在必须能够检测 fat 库中的架构。

于 2010-06-24T13:38:52.663 回答
2

确保将构建设置设置为Valid Architectures: armv6 armv7Architectures: Optimized (armv6 armv7)。这应该会产生针对 v6 和 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 
于 2010-05-08T08:35:36.393 回答