我一直在努力解决这个问题,而我与cmake的冒险只会导致我非常肯定不正确的黑客解决方案。
我创建了一个由多个文件组成的库,如下所示:
-libfolder
-codepart1folder
-CMakeLists.txt
-codepart1.cpp
-codepart1.hpp
-codepart2folder
-codepart3folder
-lib.cpp
-lib.hpp
-CMakeLists.txt
我写了一个CMakeLists文件来编译库(经过一些实验),我可以生成一个lib.a文件。现在我想将此代码作为库包含在其他项目中,并通过lib.hpp中的接口访问它。在目录结构方面,以及我需要在根项目中添加到CMakeLists.txt中的最佳方法是什么?
我目前的尝试是将-libfolder添加为当前项目的子文件夹,并添加命令:
include_directories(${PROJECT_SOURCE_DIR}/libfolder)
link_directories(${PROJECT_BINARY_DIR}/libfolder)
add_subdirectory(libfolder)
target_link_libraries(project lib)
当我运行make时,库编译得很好,但是当project.cpp编译时,它会抱怨它找不到codepart1.hpp(它包含在lib.hpp中,包含在project.cpp中)。
我怀疑这是做错的方法,但是我不能浏览CMake文档并找到一个关于设置这样的项目的好教程。请帮忙,CM大师!
答案 0 :(得分:5)
将一个CMake项目导入另一个CMake项目的简洁方法是通过find_package命令。包声明是使用export命令完成的。使用find_package的一个优点是它不需要对包文件的路径进行硬编码。
关于丢失的hpp文件,您没有包含codepart1文件夹,因此它不在包含路径中。
答案 1 :(得分:2)
好的,所以在咨询了我的同事CMake大师之后,似乎CMake没有支持我想要做的事情,留下一个有3个选项:
将所有依赖项添加到父项目CMakeLists.txt - 不是很干净,但它会让事情发挥作用。您必须为添加代码的每个项目执行此操作,并在库更改时返回并修复问题。
清理您的图书馆标题。这是通过一些编译器hackery完成的。我们的想法是向前声明每个类,并仅使用指针或boost :: shared_ptr,然后仅在cpp文件中包含依赖项。这样你就可以使用所有的findpackage东西来构建cpp文件,你可以通过只包含头文件并链接到库来获得使用lib的好处。
了解构建系统。具有复杂依赖性的可移植代码和快速代码编译不是一个解决的问题!从我的调查来看,结果非常复杂。我最终采用了他的同事构建系统,他是用cmake自己创建的,使用他从谷歌那里获得的东西。
答案 2 :(得分:1)
查看您的帖子,您似乎无法在任何地方添加“codepart1文件夹”。你是如何将codepart1.hpp包括在内的:
#include <codepart1.hpp>
#include "codepart1folder/codepart1.hpp"
我认为没有一种标准的可接受方式来构建cmake项目。我看了一堆cmake回购,他们往往有差异。我个人会做以下事情:
-project
CMakeLists.txt
-build
-cmake
OptionalCmakeModule.cmake
-src
-Main
Main.cpp
Main.hpp
-DataStructs
SomeTree.hpp
SomeObject.hpp
-Debug
Debug.hpp
-UI
Window.hpp
Window.cpp
基本上,将所有源代码转储到1个目录中,然后使用以下命令执行源代码构建:' mkdir build&amp;&amp; cd build&amp;&amp; cmake ..&amp;&amp;在项目根文件夹中生成。
如果您的项目中有单独的库,那么您可能需要一个单独的libs目录和另一个特定库的子文件夹。
如果您想查看CMakeLists.txt文件,我有一些我的回购:https://github.com/dcbishop/。
我的项目结构存在的主要问题是我使用了FILE_GLOB,这显然是“错误的”处理方式(如果你在运行' cmake .. 后添加文件,那么他们就赢了'如果你选择' make ')。我还没弄清楚“正确”的方法是什么(从我可以看到它涉及保留单独的文件列表)我也只使用1个CMakeLists.txt文件。
有些项目还会选择将cpp和hpp文件分成不同的目录。所以你会有一个include和src文件夹(至少对于打算在外部使用的hpp文件)。我认为这主要是针对主要是大型图书馆的项目。还可以使安装头文件更容易。
答案 3 :(得分:0)
你可能不见了
include_directories(${PROJECT_SOURCE_DIR}/libfolder/codepart1folder)
在这种情况下,您可能希望set( CMAKE_INCLUDE_CURRENT_DIR on)
将所有文件夹添加到包含目录路径变量。
在命令行上检查cmake的输出是否设置了正确的包含文件夹。此外,您始终可以使用message()
作为cmake变量的“打印调试”。
如果是include目录,则需要读取directory属性以查看include目录中的实际内容。
get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
message("inc_dirs = ${inc_dirs}")
我希望这可以帮助你找出遗漏的东西。
修改强>
我刚看到你对libfolder中添加的codepart1文件夹的评论。它仅在libfolder的include_directory路径中可用,而不会传播到根文件夹。 由于包含codepart1.hpp存在于lib.hpp中,但是您需要在项目路径中使用它,否则在构建项目时会出现缺少声明错误。