Xcode 自定义构建配置导致“未找到库/文件”对于静态库
我有一个工作区,其中有一个项目与另一个项目(也在工作区中)中的静态库链接。这是 Kobold2D 中的一个问题,我无法解决,尽管我了解原因,我想这是与此类似问题。
项目目标和静态库目标都具有调试和发布构建配置。一切都很好。
现在有人在项目中添加了一个新的构建配置,并将其命名为Ad-Hoc。现在项目的目标构建了Ad-Hoc配置,但是静态库没有这样的配置。显然,他们随后默认构建发布配置。
最后,当链接器应该将所有内容放在一起时,它会失败:
ld: library not found for -lbox2d-ios
Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang++ failed with exit code 1
对于通过 -force_load $(BUILT_PRODUCTS_DIR)/libSomeLib.a 强制加载的库,错误类似,但显示“找不到文件” 。我应该注意到,库“libbox2d-ios.a”位于“将二进制文件与库链接”构建阶段列表中。
显然,问题在于链接器假设库位于 BUILT_PRODUCTS_DIR 的 Ad-Hoc-iphoneos 文件夹中,而实际上它们位于 Release-iphoneos 文件夹中,因为它们没有临时构建配置。
我怎样才能打链接器的脸并告诉他将库放在它们所在的位置?最好我正在寻找适用于这两种情况的解决方案,即库添加了标准方式(将二进制文件与库构建阶段链接)和需要额外 -force_load 才能工作的库。
我希望有某种方法可以:
- 强制将库放置在应用程序目标的构建配置文件夹中
- 运行后编译&将每个库复制到构建配置文件夹的预链接脚本
- 指定库的相对路径
- 使用 $BUILT_PRODUCTS_DIR 之外的不同宏来执行 -force_load
- 链接器标志,如 -WTFmake-all-problems-go-away
对不起,但是我不得不说……啊啊!:)
I have a workspace with a project which links with the static libraries in another project (which is also in the workspace). It's a problem in Kobold2D I haven't been able to resolve, even though I understand the cause, and I suppose it's similar to this question.
The project targets and the static library targets all have the Debug and Release build configurations. All is well.
Now someone adds a new build configuration in the project and names it Ad-Hoc for example. Now the project's target builds the Ad-Hoc configuration, however the static libraries have no such configuration. Apparently they then default to building the Release configuration.
At the end, when the linker is supposed to bring everything together, it fails:
ld: library not found for -lbox2d-ios
Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang++ failed with exit code 1
For forcibly loaded libraries via -force_load $(BUILT_PRODUCTS_DIR)/libSomeLib.a
the error is similar but says "file not found". I should note that the library "libbox2d-ios.a" is in the "link binary with libraries" build phase list.
Obviously the problem is that the linker is assuming that the libraries are in the Ad-Hoc-iphoneos folder in the BUILT_PRODUCTS_DIR while they are actually in the Release-iphoneos folder because they have no Ad-Hoc build configuration.
How can I slap the linker in the face and tell him to get the libraries where they are? Preferably I'm looking for a solution that works for both cases, ie libraries added the standard way (link binary with libraries build phase) and libraries that need an additional -force_load to work.
I'm hoping that there's some way to:
- force libraries to be placed in the build configuration folder of the app's target
- run a post-compile & pre-link script that copies each library to the build configuration folder
- specify a relative path to the libraries
- use a different macro other than $BUILT_PRODUCTS_DIR for -force_load
- a linker flag like -WTFmake-all-problems-go-away
Excuse me, but I have to say this … ARGH! :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
正如类似问题iOS 静态库作为具有自定义构建配置的项目的子项目?,修复方法是添加此行
$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)
到目标的
框架搜索路径
、标头搜索路径
和/或库搜索路径
As said in similar question iOS Static Library as a Subproject of a Project That Has Custom Build Configurations?, the fix is to add this line
$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)
to your target's
Framework Search Paths
,Header Search Paths
and/orLibrary Search Paths
这是对我有用的东西。
在具有 Adhoc 构建配置的项目中,覆盖 Adhoc 构建配置的“每配置构建产品路径”(CONFIGURATION_BUILD_DIR) 和“每配置中间构建文件路径”(CONFIGURATION_TEMP_DIR),以使用与发布配置相同的文件夹。
现在,当您进行 Adhoc 构建时,Xcode 会将 libFoo.a 和 Bar.app 放入 Release-iphoneos 文件夹中。链接器会很高兴,您可以像往常一样使用 -force_load $(BUILT_PRODUCTS_DIR)/libFoo.a 。
或者,您可以将 Release-iphoneos 文件夹添加到 Adhoc 构建配置的库搜索路径中:
但是,您必须为每个构建配置设置不同的 -force_load :
Here's something that works for me.
In the project with the Adhoc build configuration, override the "Per-configuration Build Products Path" (CONFIGURATION_BUILD_DIR) and "Per-configuration Intermediate Build Files Path" (CONFIGURATION_TEMP_DIR) for the Adhoc build configuration to use the same folder as the release configuration.
Now when you do an Adhoc build, Xcode will put libFoo.a and Bar.app in the Release-iphoneos folder. The linker will be happy and you can use -force_load $(BUILT_PRODUCTS_DIR)/libFoo.a as usual.
Alternatively, you can add the Release-iphoneos folder to the library search paths for the Adhoc build configuration:
But then you'll have to set a different -force_load for each build configuration:
我在使用 CocoaPods 时遇到了类似的问题,并尝试拥有多个 Adhoc(或 Enterprise 或 Beta)配置。
下面是似乎有效的方法(假设两个项目都位于同一个 xcworkspace 中):
将
subproject
生成的库添加到mainproject
链接二进制文件中。由于
子项目
不知道配置Adhoc
,Xcode将使用Release
配置作为后备(或者可能是第一个配置)构建它时。链接器会抱怨,因为它找不到库…好吧,让我们处理这个。
在目标依赖项阶段之后将运行脚本构建阶段添加到
主项目
。输入此脚本:这将复制由
subproject
Release
构建(构建mainproject
时发生)生成的库到Adhoc
build 目录,以便链接器找到该 lib。我们应该可以出发了!是的!I have a similar problem using CocoaPods and trying to have more than one Adhoc (or Enterprise, or Beta) configurations.
Here is what seems to work (let's say that both projects are lying in the same xcworkspace):
Add the
subproject
generated lib to themainproject
Link Binary with Libraries.As the configuration
Adhoc
is not known by thesubproject
, Xcode will use theRelease
config as a fallback (or maybe the first config of the list) when building it.The linker will complain because it cannot find the lib… ok, let's handle this one.
Add a Run Script build phase to the
mainproject
, right after the Target Dependencies phase. Enter this script:This will copy the lib generated by the
subproject
Release
build (which will happen whenmainproject
is built) in theAdhoc
build directory, so that the linker will find the lib. And we should be good to go! Yeah!不幸的是,我还没有找到办法做到这一点。我能找到的最好的解决方法是添加新目标而不是新的构建配置。例如,在我的一个项目中,我只有发布和调试配置,但我有额外的目标,称为“MyProject - 应用商店”和“MyProject - ad hoc”。当然,这只有在您能够控制项目文件的情况下才可能实现。
存在重复的目标是非常烦人的,因为您可以将文件添加到一个目标,却忘记将它们添加到其他目标,并且在尝试构建它之前您不会知道。但它确实构建了,这是一个胜利(无论如何使用 xcode)。
我不久前问过一个类似的问题: 使用静态库在 ios 项目中设置构建配置以在 xcode 4 中创建存档的正确方法是什么?
I have not found a way to do this, unfortunately. The best workaround I can find is to add new targets rather than new build configurations. So for example in one of my projects I have only Release and Debug configurations, but I have extra targets called "MyProject - app store" and "MyProject - ad hoc". This will only be possible if you have control of the project file, of course.
Having duplicated targets sitting around is annoying in the extreme because you can add files to one target and forget to add them to the others, and you won't know until you try and build it. But it does build, which is a win (with xcode anyhow).
A similar question I asked a while ago: What is the correct way to set build configurations in an ios project using static libraries for creating an archive in xcode 4?
我的框架是使用我的应用程序项目中的另一个 SDK 项目构建的。首先,我有一个“调试”和“发布”,然后添加一个新的“TestFlight”配置。我无法用新的存档。我最终在 SDK 项目中添加了一个同名的新构建配置。换句话说,我最终将“TestFlight”配置添加到我的应用程序和 SDK 项目中。现在存档可以工作了。
我不确定这是否是最好的方法。但现在对我来说看起来足够干净了。 :)
哦,对于 Cocoapods,复制配置后,如果立即运行
pod install
,您将收到此黄色警告:您必须转到项目、“信息”选项卡、“配置”部分,选择刚刚创建的新配置,然后设置首先将所有目标的“Pods.release”设置为“None”。之后,您可以安全地运行
pod install
。My framework is built using another SDK project inside my app project. First I have a "Debug" and "Release", then I add a new "TestFlight" configuration. I can't archive with that new one. I ended up adding a new build configuration with the same name in the SDK project. In other words, I ended up adding "TestFlight" configuration to BOTH my app and SDK projects. Now Archive works.
I'm not sure if it's the best way to do it. But it looks clean enough to me for now. :)
Oh, and for Cocoapods, after you duplicate the configuration, if you run
pod install
right away you will get this yellow warning:You have to go to the Project, "Info" tab, "Configurations" section, select the new configuration you just created, and set "Pods.release" of all targets to "None" first. After that, you can run
pod install
safely.您可以在运行 xcodebuild 之前添加 CONFIGURATION_BUILD_DIR=/Some/Shared/Dir。例如:
You could add CONFIGURATION_BUILD_DIR=/Some/Shared/Dir before running xcodebuild. For example:
通常我有一个
AppStore
方案(映射到我的AppStore
配置)。我遇到的一件事是,这个区分大小写的问题使得 Cocoapods 在
Release-iphonesimulator
中为Pods.build
生成一个构建文件夹(作为后备),而不是AppStore-iphonesimulator
。我想当我链接方案和配置时我错过了点击,只有删除它并重新添加才让我明白出了什么问题。检查差异。
我使用的是 cocoapods 0.38.2,所以这显然是用户配置错误,而不是Cocoapods 问题已于 0.34 解决
Usually I have an
AppStore
scheme (mapped to myAppStore
config).One thing that happened to me, was this case sensitive issue that was making Cocoapods to generate a build folder for
Pods.build
insideRelease-iphonesimulator
(as a fallback) instead ofAppStore-iphonesimulator
.I guess I miss-clicked when I linked the scheme and config and only removing it and re-adding made me understand what went wrong. Check the diff.
I was using cocoapods 0.38.2, so this was clearly a user mis-configuration and not a Cocoapods issue that was resolved on 0.34