使用 CMake 创建和使用库

Creating and using a library with CMake

我正在尝试学习 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?

为了匹配您指定的目录结构,您的 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 意味着您的库不仅将此作为 "include path",任何链接到它的目标也是如此。

然而,此设置的缺点是您还将 my_lib 的任何内部 headers 暴露给消费目标。假设您还有一个 "Internal.h" 作为 my_lib 的一部分,您不想公开它。您可以通过将 intentionally-public headers 移动到单独的文件夹中来执行此操作,例如"include":

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

您的 top-level 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"