如何使用启用了位码的xcode构建静态库?


88

Xcode 7引入了Bitcode,这是一种LLVM中间二进制文件,这意味着Apple的服务器无需我的参与即可针对不同的体系结构重新编译我的应用程序。

在Lookback上,我随我们的库一起分发了一个静态归档框架。似乎,当您使用除“构建和存档”之外的任何内容进行构建时,位代码实际上并没有释放到我的库中,并且任何在其应用程序中与我的库进行链接并尝试执行启用了位代码的构建和存档的人都将获得其中之一。两个警告:

  • ld: 'Lookback(Lookback.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. (如果lib是用Xcode 6构建的)
  • ld: warning: full bitcode bundle could not be generated because 'Lookback(Lookback.o)' was built only with bitcode marker. The library must be generated from Xcode archive build with bitcode enabled (Xcode setting ENABLE_BITCODE) (如果lib是使用Xcode 7和正常的xcodebuild构建的)

我有一个构建脚本,可以构建设备+模拟器通用二进制文件,因此无法使用Build&Archive,而是xcodebuild从脚本的命令行运行。我如何才能xcodebuild生成适当的启用了位码的库?


嗨@nevyn我试图让您的SDK在使用位码的应用中进行编译。有办法吗?
Stoff81

@ Stoff81抱歉,我正在研究它。我需要首先让我的所有依赖项与Bitcode一起工作,这需要大量工作。
nevyn

Answers:


137

位代码是一种编译时功能(不是链接时功能),这意味着每个.o文件在使用位代码构建时都应包含一个称为__bitcode的额外部分。您可以通过运行来确认您的二进制文件是否与位码兼容otool -l (my .o or .a file) | grep __LLVM

正常构建时,Xcode将构建标志添加-fembed-bitcode-marker到任何clang调用中。这似乎是某种“如果启用了位代码,这就是位代码的去向”,实际上并没有启用位代码。

当您“构建并存档”时,此标志将替换为-fembed-bitcode,实际上确实会构建启用了位码的二进制文件。

似乎有两种xcodebuild使用方式-fembed-bitcode

  • 使用“存档”操作,xcodebuild -target LookbackSDK archive而不是中的xcodebuild -target LookbackSDK build。将二进制文件放入Xcode Organizer而不是build/文件夹中具有副作用,尽管您可以通过使用-exportArchive -archivePath ./build(感谢@JensAyton)来解决此问题。
  • 通过将其他C标志添加到来强制使用标志OTHER_CFLAGS="-fembed-bitcode"。您的xcodebuild调用看起来像xcodebuild OTHER_CFLAGS="-fembed-bitcode" -target LookbackSDK build

后者是我选择让我没有改变我的编译系统,但它会为每个文件警告,现在既然都-fembed-bitcode-marker-fembed-bitcode被发送到铛。幸运的是后者赢了,生成了一个启用了位码的库!

资源资源


9
FWIW,您也可以-fembed-bitcode-marker通过添加来摆脱有关被忽略的警告-Qunused-arguments
mstorsjo 2015年

哪个exportFormat用于框架的xcodebuild?似乎仅定义了“ ipa”,“ pkg”和“ app”(developer.apple.com/library/mac/documentation/Darwin/Reference/…)。
FabianKöbel2015年

@nevyn Still仍无法构建具有自定义框架文件的主应用程序,该文件又包含带有上述标志的构建脚本。
ravoorinandan

otool -l(我的.o或.a文件)。您是说otool -l(我的.o还是.a文件)| grep __bitcode?
Mike M

1
@MikeM实际上不是otool -l myfile.o | grep __LLVM,因为即使其中仅存在位码标记而不是实际位码,也会有一个__bitcode段。
nevyn

40

使用Xcode 8,我无法OTHER_CFLAGS="-fembed-bitcode"工作。was built without full bitcode. All frameworks and dylibs for bitcode must be generated from Xcode Archive or Install build在尝试创建包含静态框架的应用程序的“存档”构建时,我经常遇到类似情况。

我真正想要的是:

BITCODE_GENERATION_MODE=bitcode

我实际上是在聚合目标内部使用运行脚本,完整的xcodebuild行如下所示(仅供参考):

xcodebuild BITCODE_GENERATION_MODE=bitcode OTHER_CFLAGS="-fembed-bitcode" -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build


2
+1,该BITCODE_GENERATION_MODE=bitcode方法似乎也是首选方法,正如该答案中所建议的那样。
威廉·丹尼斯

这也解决了我的问题,而默认答案不再存在。
堪察加州

救生员!谢谢!
vidalbenjoe19年

17

添加对静态库的位码支持后,它将与Xcode 6不兼容。该应用程序将不会存档。

我想清楚地提到比特码的设置,因为@nevyn的答案使我有些困惑。

转到“构建设置”,搜索“自定义编译器标志”。添加-fembed-bitcode。这将使用位码构建您的lib。


6

在Build Settings-> Other C标志上选择项目,将Debug设置为-fembed-bitcode-marker并将Release设置为-fembed-bitcode

在“构建设置”上,单击顶部的+号以添加名称为BITCODE_GENERATION_MODE的用户定义的构建设置,然后将“调试”设置为标记,将“释放”设置为位码。

将架构编辑为Release,然后单击所需的库。一个文件并获取构建路径。获取库表单Release文件夹。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.