在 Xcode 4 工作区中,如何级联构建设置和构建设置?子项目的配置
概述
我正在使用静态库和 Xcode 4 工作区来实现 iOS 开发中的模块化,这是一种越来越常见的技术。例如,我可能有一个包含应用程序项目和库项目的工作区,如下所示1:
然后,您将有一个方案来构建这些内容,如下所示:
我想做的事让“应用程序构建”控制它启动的“库构建”,至少有几种方式:
将应用程序配置(例如调试、AdHoc)映射到任意库配置
传递 -D 定义的某些子集,和/或为库构建指定这些配置。
我将在各自的部分中讨论这些内容,但值得做一些澄清。
澄清
我在这里使用应用程序/库作为您可能拥有的任何超级项目/子项目关系的简单代理。
据我所知,Xcode 3 风格的嵌入式子项目在 Xcode 4 中的工作方式似乎与工作区“同级”没有任何不同。我很乐意在这一点上犯错。
我知道我可以通过“运行构建脚本”构建阶段和 xcodebuild 做几乎任何事情。但我尝试在此处的系统内工作,其中依赖项在方案中指定,否则有些松散耦合。
该库的存在不仅仅用于此项目,因此您不能随意加载特定于该应用程序构建的垃圾,或引用任何特定于该应用程序或工作区的内容。对于一般情况,这排除了在应用程序项目中包含静态 .xcconfig 作为将构建信息从应用程序传递到库的方式。
在工作区之外构建库会牺牲太多,而不是一个选项。
配置映射
据我了解,构建特定的应用程序配置将:
- 如果库中存在同名配置,它将使用该配置构建库。
- 否则,它将构建库的活动配置,如库的项目文件中指定的那样。
据我所知,在不诉诸上述运行构建脚本黑客的情况下,这就是人们对子项目构建配置的控制范围。请告诉我不同的。
理想情况下,我能够指定(大概在方案中):
AppConfigA -> LibConfig1
AppConfigB -> LibConfig2
While Debug、AdHoc 和 &发布可能是某些人曾经使用的唯一配置,复杂的项目通常会超出它的范围。
定义
我还没有找到将 -D 定义从应用程序构建传递到库的方法,而无需求助于 xcodebuild,它可以采用 .xcconfig 文件等。
可以在库构建运行构建脚本阶段访问应用程序的构建设置。然而,这样做会在库中引入对 App 项目的依赖,这是有充分理由被禁止的(参见澄清)。但即便如此,我还没有找到一种方法来使用这些设置来直接控制库的构建(很多2)。
太疯狂了,它可能......
我在编写本文时想到的一个方案是:
库将其构建配置基于其自己项目中的空(虚拟)
LibraryExternals.xcconfig
文件.清理库会删除该文件。如果该库尚不存在,则该库的独立构建将创建一个空库。
该文件被应用程序构建运行构建脚本阶段覆盖,并包含应用程序想要与库构建通信的任何内容。
看起来有点复杂,但我现在正在寻找任何东西。如果没有更好的结果,我会推动这个答案。
1 显示的应用程序是 Max OS X。我发现命令行应用程序可以简化测试。同样适用。
2 参见。 Info.plist预处理,这是我在这次调查中了解到的。
Overview
I'm using static libraries and Xcode 4 workspaces to effect modularity in iOS development, an increasingly common technique. For example, I might have a workspace which contains an App project, and a Library project, like so1:
You would then have a scheme to build these that looked something like this:
What I would like to do is have the "App build" control the "Library build" it initiates, in at least a couple of ways:
Map App configurations (e.g. Debug, AdHoc) to arbitrary Library configurations
Passing through some subset of -D defines, and/or specifying these for the library build.
I'll deal with each of these in their own section, but it's worth making a few clarifications.
Clarifications
I'm using App/Library here as an easy proxy for any Superproject/Subproject relationship you may have.
From what I've seen, Xcode 3 style embedded subprojects don't seem to work any differently in Xcode 4 than workspace "peers". I'd love to be wrong about this.
I know I could do almost anything with a "Run Build Script" build phase, and xcodebuild. But I'm trying to work within the system here, where the dependencies are specified in the scheme, and otherwise somewhat loosely coupled.
The Library exists to be used in more than just this project, and so you cannot arbitrarily load it up with junk specific to this App's build, or reference anything particular to the App or Workspace. For the general case, this rules out including static .xcconfig from the App project as a way to convey build information from the App to the Library.
Building the Library outside the workspace sacrifices too much, not an option.
Configuration Mapping
As I understand it, building a particular App configuration will:
- If a configuration exists in the Library of the same name, it will build the Library using that.
- Otherwise, it will build the active configuration of the Library, as specified in the Library's project file.
To my knowledge, without resorting to the aforementioned run-build-script hack, that is the extent of the control one has over subproject build configurations. Please tell me different.
Ideally, I would be able to specify (in the scheme, presumably):
AppConfigA -> LibConfig1
AppConfigB -> LibConfig2
While Debug, AdHoc, & Release may be the only configurations some ever use, complex projects often outgrow that.
Defines
I've not yet found way to pass -D defines from the App build to the Library, without resorting to xcodebuild, which can take, e.g., an .xcconfig file.
The App's build settings can be accessed in Library build run-build-script phase. However, doing that introduces a dependency in the Library on the App project, which for good reason is verboten (cf. Clarifications). But even then, I haven't found a way to use those settings to directly control the Library's build (much2).
So crazy it just might...
One scheme I came up with while writing this would be:
The Library bases it's build configurations on an empty (dummy)
LibraryExternals.xcconfig
file within it's own project.A clean of Library deletes that file. A standalone build of the Library will create an empty one if it does not already exist.
That file is overwritten by an App Build run-build-script phase, and contains anything the app wants to communicate to the Library build.
Seems kind of complicated, but I'm looking for anything right now. I'll push this to an answer if nothing better comes along.
1 Apps shown are Max OS X. I find command line apps make for simpler tests. Same applies.
2 Cf. Info.plist preprocessing, which I learned about during this investigation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您修改项目结构以使用具有多个目标的单个项目,则每个目标的构建设置将自动从该项目继承。从那里,您可以修改您想要不同的设置,或者选择单个设置并按删除键将其设置为项目指定的默认值。
If you modify your project structure to use a single project with multiple targets then each target's build settings will automatically inherit from the project. From there, you can modify ones that you want to be different, or select an individual setting and press the delete key to set it to the default specified by the project.