将项目中的标头包含到静态库中

Posted

技术标签:

【中文标题】将项目中的标头包含到静态库中【英文标题】:including a header from a project into a static library 【发布时间】:2013-04-13 21:06:19 【问题描述】:

我的项目中有一个子项目(静态库)。

由于这个静态库可能被一堆应用程序使用,我的项目中有这个 config.h 文件,其中包含应用程序配置。静态库必须读取它。

问题在于添加

#import "config.h" 

上静态库失败,因为找不到文件。

我可以在搜索标题上添加一个到我的项目根目录的绝对路径,但我想让它不被硬编码,因为这个静态库将被其他项目使用。另一个问题是我不能使用像 ../.. 这样的相对链接,例如,因为静态库在另一个卷上。

在静态库的搜索路径中包含 $(SRCROOT) 将为我提供该库的根目录,而不是使用它的项目的根目录,这就是我想要的。

我该如何解决?

请注意我的问题。我在一个项目使用的静态库中。 Config.h 在项目中。我想在我的静态库中导入那个 config.h。

如果有简单的方法,请告诉我。

我已将示例项目上传到 herehere,因此您可以看到我的痛苦。

谢谢

【问题讨论】:

【参考方案1】:

一种方法,有点骇人听闻,是将 Run Script 添加到每个 App 的 Build Phase 作为第一项,并将其复制 Config.h 到一些已知的地方 - /tmp/Config.h,你的包含的库会在那里寻找它。由于文件在每次构建时都会被复制,所以它总是正确的。

EDIT1:不太漂亮,但您可以在库中的 Dependencies 下添加一个 Run Build Script。只需添加一个并保留复选框设置以显示环境变量。你可以看到这一套:

FILE_LIST=/Volumes/Data/Users/dhoerl/Library/Developer/Xcode/DerivedData/MyProject-fdzaatzqtmrnzubseakedvxmsgul/Build/Intermediates/MyStaticLibrary.build/Debug-iphoneos/MyStaticLibrary.build/Objects/LinkFileList

你可以看到其中有几个以当前项目文件夹为前缀:

/Volumes/Data/Users/dhoerl/Library/Developer/Xcode/DerivedData/MyProject-

您可以在那里编写一些脚本来获取前缀,然后附加本地 Config.h 文件路径,现在您有了 Config.h 标头的完全限定路径,然后您可以将其复制到图书馆。我将在 xcode 论坛上发帖,因为可能有更好的解决方案 - 曾经在 Xcode 3 中。如果我得到任何实质性的回复,我会更新这个。

EDIT2:试试这个: 1)点击库,点击构建阶段,通过点击右下角的“+”按钮添加一个运行脚本构建阶段

2) 将其拖动到列表中的第二项(在目标依赖项下方)

3) 将 Shell 更改为“/bin/ksh”

4) 在编辑后将其粘贴到正确的文件/路径中:

# Get the Project Name (assumes upper/lower/numbers only in name)
PROJ=$(echo $BUILD_DIR | sed -En -e 's/(\/.*\/)([A-Za-z0-9]+)-([a-z]+\/Build\/Products)/\2/p')
# Use this variable to construct a full path
FULL_PATH="/Volumes/Data/Users/dhoerl/Downloads/nightmare/"$PROJ"/"$PROJ"/HelloWorldLayer.h"
echo FULL_PATH equals $FULL_PATH
# Make Sure MyStaticLibrary is correct
echo PROJ_DIR equals "$PROJECT_DIR/MyStaticLibrary"
cp -f "$FULL_PATH" "$PROJECT_DIR/MyStaticLibrary"

5) 这假设您将库放在您想要的任何位置,但每个 App 项目必须具有相同的父文件夹(没有太大限制 - 我过去所做的)。

PS:当我做这种事情时,我通常不包含应用程序的实际文件,而是为一个没有在库中实例化的类创建一个头文件。让我们称之为Foo。所以在你的库中,你有 Foo.h,它有很多返回信息的方法——小部件的数量、一些特殊文件夹的位置、plist、数组、字典等等。这个想法是库知道如何通过这个接口获得它需要的任何东西(类单例,或者只是一个具有类方法的类。YMMV。

PSS:其他人阅读本文,创建演示项目是值得的。

【讨论】:

不适合我。我已将示例项目上传到 herehere,因此您可以看到我的痛苦。 好的,我原则上理解它,但我不知道如何解决这个问题。无论如何,谢谢。 呃,忘掉那张纸条吧。我告诉过你如何移动配置 - 在库中运行的脚本文件中,就在库代码编译之前。不清楚吗?你真的需要我写脚本文件吗?如果你去我的个人资料,你会发现如何通过电子邮件直接与我联系,我们可以避免更多的 cmets... 我不会占用你更多的时间。感谢您的巨大努力。我很感激。我会尝试破解这个谜题。 看,这并不是一项巨大的努力,这就是我们很多人试图提供帮助的原因。脚本并不难——您可能只需将字符串从“/”抓取到第一个“-”,然后将“/headers/Config.h”附加到它。现在您有了 App Config.h 的完全限定路径。添加最后一行:“cp”/..../Config.h“$(PROJECT_DIR)/pathToIncludesInLibrary”。这将是一个不超过 6 行的脚本。【参考方案2】:

我会走另一条路。使用其中的编译器符号将此 config.h 文件作为静态库的一部分来切换功能。然后在您的项目中根据您需要的功能定义这些符号。

【讨论】:

我不能这样做,因为 config.h 特定于每个项目。如果我为每个项目修改 config.h 并且它位于静态库中,则所有项目都将读取该修改后的版本。 不适合我。我已将示例项目上传到 herehere,因此您可以看到我的痛苦。

以上是关于将项目中的标头包含到静态库中的主要内容,如果未能解决你的问题,请参考以下文章

ios 库中的 Libxml

静态库中的 VC++ 资源

链接到静态库中的 explicit_bzero (glibc)

从属项目在 Visual Studio 的引用中无法看到库中的标头

打包静态库时如何隐藏标题?

将静态库链接到类库项目