使用cmake构建c ++项目的正确方法?

时间:2011-12-13 20:46:49

标签: c++ compilation makefile cmake

我一直在努力解决这个问题,而我与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大师!

4 个答案:

答案 0 :(得分:5)

将一个CMake项目导入另一个CMake项目的简洁方法是通过find_package命令。包声明是使用export命令完成的。使用find_package的一个优点是它不需要对包文件的路径进行硬编码。

关于丢失的hpp文件,您没有包含codepart1文件夹,因此它不在包含路径中。

答案 1 :(得分:2)

好的,所以在咨询了我的同事CMake大师之后,似乎CMake没有支持我想要做的事情,留下一个有3个选项:

  1. 将所有依赖项添加到父项目CMakeLists.txt - 不是很干净,但它会让事情发挥作用。您必须为添加代码的每个项目执行此操作,并在库更改时返回并修复问题。

  2. 清理您的图书馆标题。这是通过一些编译器hackery完成的。我们的想法是向前声明每个类,并仅使用指针或boost :: shared_ptr,然后仅在cpp文件中包含依赖项。这样你就可以使用所有的findpackage东西来构建cpp文件,你可以通过只包含头文件并链接到库来获得使用lib的好处。

  3. 了解构建系统。具有复杂依赖性的可移植代码和快速代码编译不是一个解决的问题!从我的调查来看,结果非常复杂。我最终采用了他的同事构建系统,他是用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中,但是您需要在项目路径中使用它,否则在构建项目时会出现缺少声明错误。