CMake target_include_directories:我应该使用PUBLIC、PRIVATE还是INTERFACE?

5

我有一个CMake库add_library(helpers helpers.h),我想通过target_include_directories包含源文件。然后,我必须在PRIVATEPUBLICINTERFACE参数之间进行选择。

它们之间的区别是什么?


1
密切相关,如果不是重复的话:https://dev59.com/_8Lra4cB1Zd3GeqPM5er - fabian
1
@fabian 是的,但我认为这个问题更清晰、更适合初学者。 - Chris
1
@Chris ***add_library(helpers helpers.h)***,这是什么?没有源代码,只有头文件。一个库怎么可能只由头文件创建呢?你能否详细解释一下? - John
@John 举个例子,fmt是一个只有头文件的库:https://github.com/fmtlib/fmt。特别是模板不能在*.cpp文件中单独定义。 - Chris
1个回答

7
  1. PRIVATE: 这些头文件仅供helpers-library本身使用。
  2. PUBLIC: 这些头文件可以被helpers-library本身以及任何使用helpers-library的目标使用,例如通过target_link_libraries(MainApplication PUBLIC libhelpers)
  3. INTERFACE: 这些头文件不能被helpers-library使用,只能被使用helpers-library的目标使用。

这个示例说明了可能的导入方式。结构:

│   CMakeLists.txt
│   helper.cpp
│   main.cpp
│
├───details_interface
│       details_interface.cpp
│
├───details_private
│       details_private.cpp
│
└───details_public
        details_public.cpp

CMakeLists.txt:

cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 17)
project(cmake_experiment)

add_executable(cmake_experiment main.cpp)

target_link_libraries(cmake_experiment libhelper)

add_library(libhelper helper.cpp)

target_include_directories(libhelper
        INTERFACE details_interface
        PUBLIC details_public
        PRIVATE details_private)

main.cpp:

#include <iostream>

#include "details_public.cpp"
#include "details_interface.cpp"

// fatal error: details_private.cpp: No such file or directory:
// #include "details_private.cpp"

int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

helper.cpp:

#include "details_public.cpp"
#include "details_private.cpp"

// fatal error: details_interface.cpp: No such file or directory:
// #include "details_interface.cpp"


我非常确定你不能在真正的库中使用INTERFACE,我认为它只适用于接口库。 - gerum
3
我很确定你不能在真正的库中使用INTERFACE关键字,我认为它只适用于接口库。 我很确定你可以随时在任何库上使用INTERFACE关键字。 你测试过吗? - KamilCuk
2
@gerum 错了。INTERFACE 可以用于任何目标的可见性。但这只对库有意义,很少有头文件不包含在库中。(我刚测试过了,可以肯定这一点。) - fabian
@gerum 这不是真的,我添加了一个包含INTERFACE的示例。 - Chris
1
除了抽象化之外,将包含的头文件隐藏在"PRIVATE"后面还有其他好处吗? - rocksNwaves
在大型项目中,您可能会获得更好的构建时间。而且,不必要的公共引用更容易出错。 - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接