使用 CMake 从静态库中包含 header 个文件
Include header files from static library with CMake
我在使用静态库构建 CMake 项目时遇到问题。
我的项目结构如下所示:
Foo/
|-- CMakeLists.txt
|-- lib/
|-- CMakeLists.txt
|-- libA/
|-- CMakeLists.txt
|-- libA.cpp
|-- libA.h
|-- libAB.h
|-- src/
|-- CMakeLists.txt
|-- main.cpp
|-- srcDirA/
|-- CMakeLists.txt
|-- srcA.h
|-- srcDirB/
|-- CMakeLists.txt
|-- srcB.cpp
|-- srcB.h
*/CMakeLists.txt 看起来像这样:
Foo/CMakeLists.txt:
cmake_minimum_required(VERSION 3.5.1)
project(FOO)
set(CMAKE_CXX_STANDARD 11)
add_subdirectory(lib)
add_subdirectory(src)
Foo/lib/CMakeLists.txt:
add_subdirectory(libA)
Foo/lib/libA/CMakeLists.txt:
add_library (staticLibA STATIC libA.cpp)
Foo/src/CMakeLists.txt:
add_subdirectory(srcDirA)
add_subdirectory(srcDirB)
include_directories(".")
add_executable(foo main.cpp)
target_link_libraries(foo LINK_PUBLIC libA)
Foo/src/srcDirA/CMakeLists.txt 为空
Foo/src/srcDirB/CMakeLists.txt 为空
现在我正尝试将静态库中的 header 包含到我的主项目中,如下所示:
Foo/src/main.cpp:
#include "srcDirB/srcB.h"
#include "libA/libA.h"
int main() {
//...
return 0;
}
如果我尝试使用 CMake 构建它,则会生成 libA,但出现致命错误:
libA/libA.h: No such file or directory.
有谁知道我做错了什么?我必须 create a ProjectConfig.cmake file 吗?
您不需要创建任何配置文件;这些用于导入第 3 方项目。
由于您使用的是 CMake >= 3.5.1,因此您可以轻松地为您的库指定 usage requirements。使用要求是诸如标志或 include 目录 之类的东西,客户需要用库构建这些东西。
所以在 Foo/lib/libA/CMakeLists.txt: 中,您将这样做:
add_library (staticLibA STATIC libA.cpp)
target_include_directories(staticLibA INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/..)
或者,如果您希望将相同的包含目录应用于 libA 本身(这很可能),请使用 PUBLIC
而不是 INTERFACE
。
这就是您真正需要做的。但是,鉴于您使用的是现代 CMake,您应该将旧关键字 LINK_PUBLIC
的使用替换为现代等效关键字 PUBLIC
.
另外,既然你提到 .../srcDir*
中的两个 CMakeLists 都是空的,为什么一开始就把它们放在那里?您可以轻松摆脱它们和相关的 add_subdirectory
调用。
我在使用静态库构建 CMake 项目时遇到问题。 我的项目结构如下所示:
Foo/
|-- CMakeLists.txt
|-- lib/
|-- CMakeLists.txt
|-- libA/
|-- CMakeLists.txt
|-- libA.cpp
|-- libA.h
|-- libAB.h
|-- src/
|-- CMakeLists.txt
|-- main.cpp
|-- srcDirA/
|-- CMakeLists.txt
|-- srcA.h
|-- srcDirB/
|-- CMakeLists.txt
|-- srcB.cpp
|-- srcB.h
*/CMakeLists.txt 看起来像这样:
Foo/CMakeLists.txt:
cmake_minimum_required(VERSION 3.5.1)
project(FOO)
set(CMAKE_CXX_STANDARD 11)
add_subdirectory(lib)
add_subdirectory(src)
Foo/lib/CMakeLists.txt:
add_subdirectory(libA)
Foo/lib/libA/CMakeLists.txt:
add_library (staticLibA STATIC libA.cpp)
Foo/src/CMakeLists.txt:
add_subdirectory(srcDirA)
add_subdirectory(srcDirB)
include_directories(".")
add_executable(foo main.cpp)
target_link_libraries(foo LINK_PUBLIC libA)
Foo/src/srcDirA/CMakeLists.txt 为空
Foo/src/srcDirB/CMakeLists.txt 为空
现在我正尝试将静态库中的 header 包含到我的主项目中,如下所示:
Foo/src/main.cpp:
#include "srcDirB/srcB.h"
#include "libA/libA.h"
int main() {
//...
return 0;
}
如果我尝试使用 CMake 构建它,则会生成 libA,但出现致命错误:
libA/libA.h: No such file or directory.
有谁知道我做错了什么?我必须 create a ProjectConfig.cmake file 吗?
您不需要创建任何配置文件;这些用于导入第 3 方项目。
由于您使用的是 CMake >= 3.5.1,因此您可以轻松地为您的库指定 usage requirements。使用要求是诸如标志或 include 目录 之类的东西,客户需要用库构建这些东西。
所以在 Foo/lib/libA/CMakeLists.txt: 中,您将这样做:
add_library (staticLibA STATIC libA.cpp)
target_include_directories(staticLibA INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/..)
或者,如果您希望将相同的包含目录应用于 libA 本身(这很可能),请使用 PUBLIC
而不是 INTERFACE
。
这就是您真正需要做的。但是,鉴于您使用的是现代 CMake,您应该将旧关键字 LINK_PUBLIC
的使用替换为现代等效关键字 PUBLIC
.
另外,既然你提到 .../srcDir*
中的两个 CMakeLists 都是空的,为什么一开始就把它们放在那里?您可以轻松摆脱它们和相关的 add_subdirectory
调用。