cmake - target_include_directories - INTERFACE 不导出包含路径
问题描述
我创建了一个非常简单的 cmake 项目来测试 cmake 功能。项目目录包含两个库。我想导出 MyLibA 包含路径。
主要的 CMakeLists.txt:
cmake_minimum_required(VERSION 3.11)
project(TestProject)
add_subdirectory(MyLibA)
add_subdirectory(MyLibB)
MyLibA CMakeLists.txt:
add_library(MyLibA SHARED)
target_sources(MyLibA PRIVATE fileA.h fileA.cpp)
target_include_directories(MyLibA INTERFACE "${CMAKE_SOURCE_DIR}/MyLibA")
MyLibB CMakeLists.txt:
add_library(MyLibB SHARED)
target_sources(MyLibB PRIVATE fileB.h fileB.cpp)
target_link_libraries(MyLibB PRIVATE /home/user/MyProjects/CmakeTestProject/build/MyLibA/libMyLibA.so)
我使用 INTERFACE 关键字导出了包含路径,但 fileB.h 中包含以下内容:
#include "fileA.h"
没有找到。我究竟做错了什么 ?
解决方案
我究竟做错了什么?
几件事:
- 永远不要在 CMakeLists.txt 中放置绝对路径,并且始终链接到目标而不是库文件。
# Linking to a target propagates usage requirements, like include paths.
target_link_libraries(MyLibB PRIVATE MyLibA)
CMAKE_SOURCE_DIR
不是你想的那样。它总是指顶级构建目录,如果您的项目可能是一个add_subdirectory
或FetchContent
目标,这是一个糟糕的假设。您的用法可以替换为:
# Not optimal, see below.
target_include_directories(MyLibA INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
$<BUILD_INTERFACE:...>
如果您打算导出目标,则缺少包含路径。导出目标时,它们的属性会逐字复制到输出中。不保护本地包含路径$<BUILD_INTERFACE:...>
会破坏导出目标的用户。
target_include_directories(
MyLibA
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
)
推荐阅读
- python - Pandas - 根据其他列中的值将数据添加到列
- twitter-bootstrap - 覆盖 Bootstrap 4 CDN 颜色映射
- python-3.x - 如何从用户那里获取多个输入并将它们写入文件
- r - R:如何添加与数据框的其余部分具有不同列数的行?
- php - 没有附件的正文上的phpMailer图像
- angular - 在 angularjs 控制器中侦听来自 angular 4 组件的事件
- javascript - 会话变量不与嵌入式 PHP 共享
- java - 启动Tomcat服务器时如何使用命令行传递参数?
- python - 如何使用 Keras API 在 TensorFlow Eager 中将 dropout 应用于 RNN 的输出?
- reactjs - 在反应中渲染之前获取数据的最佳位置