哇——这个问题包含了很多问题!让我们尝试一个一个地解决它们:
是否会使用此处的设置(SDKROOT 和 CXXFLGS)?
不,您已经成功创建了 makefile 变量,但它们不会被构建目标中的 xcodebuild 命令拾取——您需要将这些值设置为 xcodebuild 命令上的附加构建参数。从 xcodebuild 的手册页中,我们看到构建配置覆盖的这种分配格式已经[setting=value ...]
从完整的命令格式中提炼出来:
xcodebuild [-project projectname] -scheme schemename [-configuration configurationname] [-sdk [sdkfullpath | sdkname]] [buildaction ...] [setting=value ...] [-userdefault=value ...]
这意味着您必须在 xcodebuild 命令中以键值样式格式设置构建设置。重要的是要注意构建设置具有层次结构——一些由 SDK 定义,然后可以在项目级别覆盖,可以在目标级别进一步覆盖,然后可以由 xcodebuild 设置部分覆盖,并且可以通过使用 xcodebuild 特定的-xcconfig file
.
那只是……太棒了……有这么多地方可以注入构建设置间接,我们应该如何进行这项工作?
这是您作为项目设计者必须开始决定您的代码、构建产品和框架将如何被他人使用、重用甚至滥用的地方。构建设置越共享或通用,它的配置就应该越高,这样它将适用于最广泛的目标集。例如,SDKROOT 就是这样一种构建设置,可能会在项目级构建设置中设置,因为该项目的消费者很可能希望使用与您相同的 SDK 来构建或使用这些框架。当然,您必须决定是否应该对所有目标设置所谓的“全局”,并仔细提升/降级您的构建配置。由于您的源问题中没有太多关于您的应用程序/框架/用例的详细信息,SO 社区能够提供的具体指导很少。相反,我将向您指出最佳实践的方向,并留给您将这些最佳实践应用于您的情况。
现在,回到 makefile...如果您要直接从终端运行此构建,并应用这些自定义命令行设置,您的 xcodebuild 命令将如下所示:
xcodebuild -project Testing.xcodeproj -target 测试 SDKROOT='/Developer/SDKs/MacOSX10.5.sdk' ARCHS='i386 x86_64' CXXFLGS='-I/Users/XXYY/dev/Frameworks/Headers -DUNIX'
运行时,xcodebuild 命令的前几行输出如下所示:
从命令行构建设置:
ARCHS = i386 x86_64
CXXFLGS = -I/Users/XXYY/dev/Frameworks/Headers -DUNIX
SDKROOT = /Developer/SDKs/MacOSX10.5.sdk
然后可以将该命令移植到您的 make 文件中,只需进行相对较少的更改:
xcodebuild -project Testing.xcodeproj -target 测试 SDKROOT=${SDKROOT} ARCHS=${ARCHS} CXXFLGS=${CXXFLGS}
${FOO}
符号是 makefile 变量替换语法——继续将新的 xcodebuild 行粘贴到你的 makefile 中,然后修改变量的值,最后调用 make 。您将看到与以前相同的前几行 xcodebuild 输出,它们将反映您对 makefile 变量所做的更改。
恭喜!您现在已经将您的 makefile 变量传递给 Xcodebuild!
一个潜在的陷阱:您的 SDKROOT 变量似乎使用老式 /Developer 文件夹作为其 SDK 参考。目前尚不清楚您是否打算从该目录针对较旧的 10.5 SDK 进行构建,但我敢猜测这只是 Mac App Store 之前的 Xcode 版本的遗留物。除非您的项目对 10.5 有特定依赖关系,否则请考虑将您的 SDKROOT 路径升级到较新位置的更现代的 SDK:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
然后你会转向一系列关于框架的问题以及让其他人可以访问它们的愿望。
我怀疑您真正在做的是制作一系列应用程序级框架,您希望在他们自己的项目中提供给其他人使用。
考虑机器安全
如果是这种情况,那么将那些已编译的框架安装到系统或用户框架库可能不是您想要做的。首先,/Library/Frameworks 文件夹要求应用程序对机器具有 root 访问权限,这当然会给机器带来不小的安全风险。用户的 Frameworks 文件夹(~/Library/Frameworks)只是稍微安全一点,但它也是一个不常见的用例,默认情况下不存在这样的文件夹!实际上,将框架推广给整个系统或整个用户的情况相对较少。
相反,由于您实际上只是在寻找有保证的已知位置,因此您可能希望将构建产品复制到项目目录本身的文件夹中。然后,无论您的用户将项目文件夹复制到何处,对主项目文件夹的子文件夹的相对引用将始终正确!
自然,有两种选择:
- 在末尾添加一个 Copy Files 构建阶段,并将构建的产品从标准构建产品目录复制到主项目文件夹的已知子文件夹。和以前一样,您可以将项目引用更新为相对于项目的根目录。
- 将 DSTROOT 设置为 ${SRCROOT},将 INSTALL_PATH 设置为项目文件夹内的命名目录,并将 DEPLOYMENT_LOCATION 设置为 1。这会将您的框架“安装”到项目中的这个已知路径,您可以设置所有其他标题和框架搜索路径相对于这个已知位置。
根据您项目的需求,从长远来看,这些选项之一可能会更容易维护——哪一个将完全取决于您的项目以及您预计用户将如何使用您的框架。有一件事是绝对肯定的,除非你绝对需要你的框架的 root 访问权限,否则最好避免一起使用那些 Library/Frameworks 目录。
希望这能让您指出正确的方向,如果您有任何后续问题,请在此答案末尾发表评论,我会看看我是否可以澄清、详细说明等。