target_include_directories 结果包含路径

Dav*_*ria 4 c++ cmake

假设我有一个项目,如下所示:

 Project (dir)
   -- CMakeLists.txt
   -- MyLib (dir)
     |-- CMakeLists.txt
     |-- MyLib.h
     |-- MyLib.cpp

   -- MyOtherLib (dir)
     |-- CMakeLists.txt
     |-- MyLib.h (note that this is exactly the same name as in MyLib above)
     |-- MyLib.cpp
Run Code Online (Sandbox Code Playgroud)

如果在 MyLib/CMakeLists.txt 中我这样做:

target_include_directories(MyLib PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
Run Code Online (Sandbox Code Playgroud)

那么任何事情target_link_libraries都会MyLib有“正确的”包含路径去做#include "MyLib.h"。但是,如果另一个可执行文件MyExecutable依赖于这两个库,target_link_libraries(MyExecutable MyLib MyOtherLib)您希望能够使用#include "MyLib/MyLib.h"或来指定哪个库#include "MyOtherLib/MyLib.h"。我认为做到这一点的唯一方法是使用:

target_include_directories(MyLib PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
Run Code Online (Sandbox Code Playgroud)

这破坏了它的一个好处,target_include_directories因为它确实强烈地强制避免意外的标头依赖性,因为您实际上不能包含您未明确声明使用的东西。

还有其他方法可以实现这种#include "MyLib/MyLib.h"行为吗?

Cla*_*dio 5

您应该重新考虑您的目录树,如下所示:

Project (dir)
   -- CMakeLists.txt
   -- MyLib (dir)
     |-- CMakeLists.txt
     |-- src (dir)
         MyLib.cpp
     |-- include/MyLib (two dirs)
         MyLib.h

   -- MyOtherLib (dir)
     |-- CMakeLists.txt
     |-- src (dir)
         MyLib.cpp
     |-- include/MyOtherLib (two dirs)
         MyLib.h
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以避免包含../ieProject文件夹及其中的所有内容,这不是一个干净的方法,并且如果您将来添加其他文件/文件夹,可能会导致其他问题。然后,您可以写入MyLib/CMakeLists.txt

target_include_directories(MyLib PUBLIC 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include)
Run Code Online (Sandbox Code Playgroud)

并在MyOtherLib/CMakeLists.txt

target_include_directories(MyOtherLib PUBLIC 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include)
Run Code Online (Sandbox Code Playgroud)

因此,您将能够在任何程序中编写#include "MyLib/MyLib.h"并链接到构建树#include "MyOtherLib/MyLib.h"中的库。

如果您还想区分构建树安装树之间的包含目录,请查看target_include_directories 文档和有用的cmake-generator-expressions