使用 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" 文件夹是 PRIVATE
到 my_lib
,main.cpp 将无法 #include "Internal.h"
。
我正在尝试学习 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" 文件夹是 PRIVATE
到 my_lib
,main.cpp 将无法 #include "Internal.h"
。