【问题标题】:Creating and using a library with CMake使用 CMake 创建和使用库
【发布时间】:2015-03-27 23:32:38
【问题描述】:

我正在尝试学习 CMake,但我无法掌握可用的教程。

假设我的项目具有以下结构,并且我想通过其 CMakeLists 文件使 my_lib 可用并在我的 main.cpp 中使用它,我的 CMakeLists 文件会是什么样子?

├── CMakeLists.txt
├── externals
│   └── my_lib
│       └── src
│           ├── CMakeLists.txt
│           ├── MyClass.h
│           └── MyClass.cpp
└── main.cpp

我应该使用 include_directories 还是 add_subdirectory?

【问题讨论】:

    标签: c++ cmake


    【解决方案1】:

    为了匹配您指定的目录结构,您的 CMakeLists.txt 文件可能如下所示:

    /CMakeLists.txt:

    cmake_minimum_required(VERSION 3.0)
    project(Main)
    add_subdirectory(externals/my_lib/src)
    add_executable(my_main main.cpp)
    target_link_libraries(my_main my_lib)
    

    /externals/my_lib/src/CMakeLists.txt:

    cmake_minimum_required(VERSION 3.0)
    project(MyLib)
    add_library(my_lib MyClass.cpp MyClass.h)
    target_include_directories(my_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
    

    target_include_directories 调用中使用PUBLIC 意味着您的库不仅将其作为“包含路径”,而且任何链接到它的目标也是如此。

    但是,此设置的缺点是您还将向消费目标公开my_lib 的任何内部标头。假设您还有一个“Internal.h”作为您不想公开的my_lib 的一部分。您可以通过将有意公开的标头移动到单独的文件夹中来做到这一点,例如“包括”:

    ├── CMakeLists.txt
    ├── externals
    │   └── my_lib
    │       ├── CMakeLists.txt
    │       ├── include
    │       │   └── MyClass.h
    │       └── src
    │           ├── Internal.h
    │           └── MyClass.cpp
    └── main.cpp
    

    您的顶级 CMakeLists.txt 不会更改,但 /externals/my_lib/CMakeLists.txt(已上移一个级别)现在显示为:

    cmake_minimum_required(VERSION 3.0)
    project(MyLib)
    add_library(my_lib src/MyClass.cpp src/Internal.h include/MyClass.h)
    target_include_directories(my_lib
        PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
        PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
        )
    

    现在,由于您的库的“src”文件夹是 PRIVATEmy_lib,因此 main.cpp 将无法 #include "Internal.h"

    【讨论】:

    • 谢谢,这让事情变得更清楚了,而且确实有效!我是否可以假设包含目录中的任何文件现在都可以使用 Internal.h?
    • “include”目录通常只包含标题。这些头文件应该只#include "include" 目录中的其他头文件。说“MyClass.h”创建#include "Internal.h"。这对于任何依赖于my_lib 的东西来说都是一个问题,例如说“main.cpp”有#include "MyClass.h"。编译器知道在哪里可以找到“MyClass.h”——我们已经告诉它“externals/my_lib/include”,但它找不到“MyClass.h”需要的“Internal.h”。因此,“include”中的任何标题都不应引用“src”中的文件。
    • 如果无法避免暴露“Internal.h”(通常是模板代码的情况),通常将其放在名为“detail”的“include”子目录中,以向库,它是一种私有代码,可能会在没有警告的情况下更改,不应该由他们直接#includeed。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    • 2013-12-01
    • 2023-04-07
    • 2021-07-07
    • 1970-01-01
    • 2021-12-25
    相关资源
    最近更新 更多