3

我有一个使用 xcodebuild 构建 Xcode 项目的 makefile。我的问题是

是makefile中的设置(使用xcodebuild)还是在调用makefile来构建项目时要使用的Xcode项目中的设置?

例如,如果我在 makefile 中有一些设置,例如:

SDKROOT =/Developer/SDKs/MacOSX10.5.sdk ARCHS="i386 x86_64"
CXXFLGS =-I/Users/XXYY/dev/Frameworks/Headers -DUNIX   (just an example to show where to check header files, this is different from what is set in the Xcode project)

target:
       xcodebuild build -target $@ -configuration Release 


 ... ...

是否会使用此处的设置(SDKROOT 和 CXXFLGS)?

如果答案是肯定的,那么我可以设置我的 Xcode 项目(称为项目 A)以链接到我自己放在 $(HOME)/Library/Frameworks 中的一些框架,然后将其发送给用户。

同时,当我构建这个项目A时,我可以将它设置为链接到与我在makefile中构建项目A同时构建的框架。

这样,当用户打开我的项目 A 时,框架将链接到他们的 $HOME/Library/Frameworks。(框架会被要求复制到那里)

或者也许我可以问当我尝试发布一个项目(使用我自己的框架)时,如何为我自己的框架设置搜索路径?makefile 中的过程将是:首先构建我的框架,然后是我的项目(显然,我的项目将链接到框架的新构建)。

如果我将框架的路径设置为链接到 myframeworkfolder/build/Release/ * .frameworks,则在将项目复制给其他用户时需要重置此路径。如果我将框架的路径设置为链接到,例如,/Library/Frameworks,那么其他用户不需要更改路径。任何人都有建议我应该怎么做?或者我应该将我的框架的路径设置为/Library/Frameworks,然后当我完成构建框架时,将其复制到/Library/Frameworks,然后构建我的项目。这是正确的方法吗?

谢谢。

4

1 回答 1

5

哇——这个问题包含了很多问题!让我们尝试一个一个地解决它们:

是否会使用此处的设置(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)只是稍微安全一点,但它也是一个不常见的用例,默认情况下不存在这样的文件夹!实际上,将框架推广给整个系统或整个用户的情况相对较少。

相反,由于您实际上只是在寻找有保证的已知位置,因此您可能希望将构建产品复制到项目目录本身的文件夹中。然后,无论您的用户将项目文件夹复制到何处,对主项目文件夹的子文件夹的相对引用将始终正确!

自然,有两种选择:

  1. 在末尾添加一个 Copy Files 构建阶段,并将构建的产品从标准构建产品目录复制到主项目文件夹的已知子文件夹。和以前一样,您可以将项目引用更新为相对于项目的根目录。
  2. 将 DSTROOT 设置为 ${SRCROOT},将 INSTALL_PATH 设置为项目文件夹内的命名目录,并将 DEPLOYMENT_LOCATION 设置为 1。这会将您的框架“安装”到项目中的这个已知路径,您可以设置所有其他标题和框架搜索路径相对于这个已知位置。

根据您项目的需求,从长远来看,这些选项之一可能会更容易维护——哪一个将完全取决于您的项目以及您预计用户将如何使用您的框架。有一件事是绝对肯定的,除非你绝对需要你的框架的 root 访问权限,否则最好避免一起使用那些 Library/Frameworks 目录。

希望这能让您指出正确的方向,如果您有任何后续问题,请在此答案末尾发表评论,我会看看我是否可以澄清、详细说明等。

于 2013-08-10T23:49:13.783 回答