如何在我的 cmake 项目中包含另一个 cmake 项目的头文件?

Posted

技术标签:

【中文标题】如何在我的 cmake 项目中包含另一个 cmake 项目的头文件?【英文标题】:How to include another cmake project's header files in my cmake project? 【发布时间】:2019-09-03 02:38:11 【问题描述】:

我正在尝试包含另一个 CMake 项目作为我项目的第三方库。问题是我不能包含上述库中的标题。

我尝试使用add_subdirectory 函数添加库,但它似乎不起作用。

这是我的 CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)
project (Cam2ClientCpp)

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

include_directories ("$PROJECT_SOURCE_DIR/restclient-cpp")
add_subdirectory (restclient-cpp)

set(EXECUTABLE_OUTPUT_PATH $PROJECT_BINARY_DIR/bin)
set(LIBRARY_OUTPUT_PATH $PROJECT_BINARY_DIR/lib)

add_executable (Cam2ClientCpp main.cpp)
target_link_libraries (Cam2ClientCpp restclient-cpp)

另一个项目的 CMakeLists.txt 在这里:https://github.com/mrtazz/restclient-cpp/blob/master/CMakeLists.txt。

当我运行 make 时,我收到以下错误:

/Library/Developer/CommandLineTools/usr/bin/c++   -I/Users/nhendy/Development/cam2clientcpp/restclient-cpp  -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk   -std=gnu++11 -o CMakeFiles/Cam2ClientCpp.dir/main.cpp.o -c /Users/nhendy/Development/cam2clientcpp/main.cpp
/Users/nhendy/Development/cam2clientcpp/main.cpp:1:10: fatal error: 'restclient-cpp/connection.h' file not found
#include "restclient-cpp/connection.h"

【问题讨论】:

您编译并安装该库,然后从其安装位置在您的项目中使用它。 @JesperJuhl 我绝对不想在我的系统上安装库。我想把它打包成我项目的一部分。 【参考方案1】:

通常,要使用库,您必须:

调用add_subdirectory,以便解析和解释该项目的CMakeLists.txt。这使 CMake 知道项目/库。 库项目定义了库用户需要知道的包含路径 (PUBLIC),以及内部包含路径 (PRIVATE):
target_include_directories(MyLibrary
  PUBLIC
    include
  PRIVATE
    src
)
库的用户只需要引用库:
target_link_libraries(MyCoolApp
  PRIVATE
    MyLibrary
)

这样库导出使用库所需的路径,即不是库的用户知道如何使用它,而只有库本身。

我的建议是为图书馆创建一个 PR,并请他们使用这种方法。

如果无法做到这一点,您可以设置 include_directories。我的 CMakeLists.txt 看起来像这样(您的唯一更改是 include_directories 命令,使用$CMAKE_SOURCE_DIR):

cmake_minimum_required (VERSION 2.6)
project (Cam2ClientCpp)

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

file(WRITE
  $CMAKE_BINARY_DIR/restclient-cpp/include/restclient-cpp/version.h
  "#define RESTCLIENT_VERSION \"0.5.0\"\n"
)

include_directories ("$CMAKE_SOURCE_DIR/restclient-cpp/include")
include_directories ("$CMAKE_BINARY_DIR/restclient-cpp/include")
#add_subdirectory (restclient-cpp)

set(EXECUTABLE_OUTPUT_PATH $PROJECT_BINARY_DIR/bin)
set(LIBRARY_OUTPUT_PATH $PROJECT_BINARY_DIR/lib)

add_executable (Cam2ClientCpp main.cpp)
target_link_libraries (Cam2ClientCpp restclient-cpp)

我测试了以下文件结构:

./CMakeLists.txt
./restclient-cpp
./restclient-user
./restclient-user/CMakeLists.txt
./restclient-user/main.cpp
restclient-cpp 包含客户端库的克隆 repo restclient-user 使用该库的可执行代码 ./CMakeLists.txt 只包含:
cmake_minimum_required(VERSION 3.10)
add_subdirectory(restclient-cpp)
add_subdirectory(restclient-user)

【讨论】:

感谢您的回答!我确实试过了,但它仍然给我一个错误,它找不到头文件。我想知道安装调用是否会生成 FindLibrary 脚本。 install(EXPORT restclient-cppTargets DESTINATION $CONFIG_INSTALL_DIR) install( FILES $CMAKE_CURRENT_BINARY_DIR/restclient-cppConfig.cmake $CMAKE_CURRENT_BINARY_DIR/restclient-cppConfigVersion.cmake DESTINATION $CMAKE_INSTALL_PREFIX/$CONFIG_INSTALL_DIR ) 我在我的机器上测试了编译。我在使用 libcurl 时遇到了一些问题,并且缺少文件 restclient-cpp/version.h - 这可能与我的机器有关,我希望我的回答仍然对您有所帮助。【参考方案2】:

首先,需要单独编译第三方库。然后链接到 CMake 项目中的输出库。 见target_link_libraries

【讨论】:

以上是关于如何在我的 cmake 项目中包含另一个 cmake 项目的头文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据 cmak 在 qt creator 中使用 opencv Cuda

如何在 Hugo/Markdown 页面中包含另一个文件?

如何在 Grails 中搜索集合中包含另一个元素的元素?

在 php codeigniter 中包含另一个页面时,父页面未加载

如何在 CMake GUI 中显示 FooConfig.cmake 文件中的 CMake 变量?

Tomcat 在 web.xml 中包含另一个 xml 文件