首页 > 解决方案 > 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"

没有找到。我究竟做错了什么 ?

标签: cmake

解决方案


我究竟做错了什么?

几件事:

  1. 永远不要在 CMakeLists.txt 中放置绝对路径,并且始终链接到目标而不是库文件
# Linking to a target propagates usage requirements, like include paths.
target_link_libraries(MyLibB PRIVATE MyLibA)
  1. CMAKE_SOURCE_DIR不是你想的那样。它总是指顶级构​​建目录,如果您的项目可能是一个add_subdirectoryFetchContent目标,这是一个糟糕的假设。您的用法可以替换为:
# Not optimal, see below.
target_include_directories(MyLibA INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
  1. $<BUILD_INTERFACE:...>如果您打算导出目标,则缺少包含路径。导出目标时,它们的属性会逐字复制到输出中。不保护本地包含路径$<BUILD_INTERFACE:...>会破坏导出目标的用户。
target_include_directories(
  MyLibA 
  INTERFACE
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
)

推荐阅读