我想在我自己的Objective-C应用程序中使用LLVM项目中的一些类。具体来说,我想使用BitstreamReader.h和BitstreamWriter.h中声明的类。不幸的是,我没有太多链接C++库的经验,所以我真的不知道从哪里开始。我开始是通过Homebrew使用brew install llvm@14
安装llvm。然后,在我的Xcode项目中,我尝试链接/opt/homebrew/opt/llvm@14/lib
中的库,并将/opt/homebrew/opt/llvm@14/include/**
添加到我的HEADER_SEARCH_PATHS
中。
现在我完全卡住了。我在Xcode中有一堆构建错误,比如:
- “引用未解析的using声明”
- “全局命名空间中没有名为'ldiv'的成员”
- “使用未声明的标识符'wcspbrk'”
- ...
任何帮助都将不胜感激。谢谢!
1条答案
按热度按时间jtoj6r0c1#
在C++的世界里,有很多种方法可以将依赖关系合并到你的项目中,我将概述其中的一些,但会尝试详细描述我发现最适合你的场景的一种:
1.安装库系统/用户范围
这是最经典的方法,当你为你的特定平台预编译和预安装了库,这样它们就可以在默认的库搜索路径下使用。这类似于iOS中系统框架的使用-你只需要向项目添加链接器命令,而框架(库)独立于它而存在(或者不存在,这会导致链接器错误)。这种方法的问题是,您不能真正将库用于受限系统,其中“默认”库不可更改(iOS、tvOS、iPadOS)
2.嵌入静态库
另一种方法是将你需要的所有库预编译到所有平台的归档文件中,然后只将其中一个库版本嵌入到你最终的应用二进制文件中。这种方法有点麻烦,不便于移植,因为每次你需要修改库的某些部分或支持新平台时,你都需要手动编译库并重新嵌入。
3.嵌入一个
xcframework
这种方法与前一种方法非常相似,但有一些好处,您可以将所有平台的二进制文件 Package 在一个包中,甚至可以在SPM中发布它。
4.使用CMake构建系统
C++中的许多项目(LLVM也不例外)都使用所谓的CMake工具。它是广泛采用的多平台构建系统,您可以使用它的好处之一是,您可以轻松地将任何其他项目作为自己项目的一部分。同时,CMake在移动的开发领域并不普遍,因此您可能很难找到这些平台的相关信息。
5.使用Xcode工作区
这就是我想要更详细描述的解决方案。简而言之,这个方法包括6个步骤:
这种方法的好处在于它提供了最一致的体验(生成项目后,所有部分都可以从Xcode配置)、管理源代码的自由(LLVM项目文件可以随意更改)以及内置依赖关系图的奢华(构建目标所需的所有库都在Xcode设置下提供)。
正在下载LLVM项目
您可以从here克隆项目。请注意,这必须位于您将来的工作区所在的同一个文件夹中,因此您最好提前做好准备:
正在生成LLVM Xcode项目
首先,确保你已经安装了CMake(它在macOS中不是开箱即用的)。你可以使用
brew
或者直接从the official site下载应用。然后,在llvm-project
repo文件夹旁边为将来的Xcode项目创建一个新文件夹,并在LLVM工具包项目上运行cmake
:创建Xcode工作区
这里没有什么花哨的东西,只要打开Xcode并导航到
File/New/Workspace
菜单(Ctrl+Cmd+N 快捷方式)。确保您的工作区是在MyWorkspace
文件夹中创建的。您可以直接从Xcode中执行此操作:然后添加上一步创建的LLVM项目,打开
File/Add Files to "MyWorkspace"...
菜单(Option+Cmd+A),选择Xcode项目文件:如果Xcode建议自动创建方案,我建议接受这个建议,这样你就不必在以后自己处理它。
添加您自己的项目
这一步与前一步类似,只是你需要将自己的项目添加到工作区中。我没有一个现成的项目,所以我只是在工作区目录中创建了一个新项目(在我的例子中是macOS命令行应用程序)。如果你做了同样的操作,请确保该项目已添加到“MyWorkspace”中,并且文件夹是正确的:
最终,您的工作空间“项目导航器”应如下所示:
下面是目录树的简要外观:
向项目添加依赖项
从现在开始,您只需要Xcode就可以完成这项工作。让我们将所需的库链接到项目,并从Bitstream存档开始。打开项目的目标“常规”选项卡设置,然后在框架和库下单击**+**符号,该符号应将您带到显示当前所有可用本地依赖项的屏幕。它'LLVM项目+原生Apple库中的工具列表相当长,因此您可能希望根据需要对其进行过滤,以找到所需的位置:
现在是棘手的部分。实际上你可能不需要这样做,但是如果LLVMBitstreamReader目标本身依赖于其他库的符号(并且通过显式使用库符号来暴露这样的依赖关系),项目链接将失败,所以为了安全起见,请转到LLVMBitstreamReader构建设置,并在Target Dependencies部分检查它依赖于什么:
现在将这些依赖项也添加到您的项目中。最终您的Frameworks and Libraries部分应该如下所示:
调整项目设置
Debug
/Release
/MinSizeRel
/RelWithDebInfo
).为了让您自己的项目的目标找到使用给定配置构建的库,您必须调整LLVM项目/目标设置,我不推荐这样做,因为这需要大量的手工工作,或者只是添加自定义库搜索路径到您的项目。对于后者,请转到您在上一步添加依赖项的目标的Build Settings,找到Library Search Path项并添加$(SRCROOT)/../LLVM/$(CONFIGURATION)/lib
作为新项:大结局
现在你应该可以使用LLVMBitstreamReader库和其中定义的类了,我把我的
main.m
重命名为main.mm
,这样clang就知道我将在代码中使用C++,下面是我的示例代码:如果一切都做对了,现在编译应该没有任何错误。
**P.S.**我多次关注特定的目录层次结构是有原因的--当XCode项目通过CMake生成时,它通常使用绝对路径,而不是相对路径,如果您将项目移动到另一个目录,您将不得不在所需目标/项目的构建设置中调整路径,或者再次重复生成LLVM Xcode项目的步骤。