在cmake中是否有类似于target_include_files的东西

时间:2020-10-12 13:08:47

标签: c++ cmake

除了单个文件之外,是否有任何其他方法可以与目标包含目录添加文件?

我的用例是这个。我使用了大量的模板和概念,并且头文件越来越庞大。我真的很喜欢将实现与定义分开,所以想要这样的东西:

.h文件

template <typename T>
T foo(T bar);

#include <name_of_implementation_file>

实施.h文件

template <typename T>
T foo(T bar) { return bar; };

当前包含必须看起来像这样:#include "path/to/implementation_file_name"

这很烦人,因为它使以后的重构变得很痛苦。我也不想添加仅包含1个或2个文件的额外目录并调用target_include_directories。我不想只是include,因为我的项目是一个库,并且我不希望用户能够包含实现文件。我还在建立多个目标,并希望将其包含的文件分开。

1 个答案:

答案 0 :(得分:1)

TLDR:要让用户使用模板,用户必须看到它 all

与cmake中的target_include_files类似吗

不,没有。

除了单个文件之外,是否有任何其他方法可以与目标包含目录添加文件?

唯一的方法是:

  • 创建一个空目录(在CMAKE_CURRENT_BINARY_DIR中的某个位置)
  • 在此处复制文件
  • 将该目录添加到include_directories

很有趣,它看起来很容易用未经测试的伪代码实现:

function(target_include_files target mode)
    string(MD5 dir "${ARGN}")
    set(dir ${CMAKE_CURRENT_BINARY_DIR}/${dir})
    file(MAKE_DIRECTORY ${dir})
    foreach(i IN LISTS ARGN)
       # TODO: replace with build-time generation
        configure_file(${i} ${CMAKE_CURRENT_BINARY_DIR}/${dir} COPYONLY)
    endforeach()
    target_include_directories(${target} ${mode} ${dir})
endfunction()

我真的很喜欢将实现与定义分开,所以想要这样的东西:

最简单的方法是将实现文件与头文件放在同一目录中-这样,简单的#include "file"就足够了,因为"中的include首先搜索当前include目录。如果不是,则将实现文件移动到子目录中,并仅将子目录也包含在当前文件中。如果不是,请-将带有实现文件的其他目录添加到搜索路径。

我不希望用户包含实现文件。

因此,就像某些封闭的C ++库一样,在源文件中显式实例化常见类型的模板,并在头文件中为它们的模板化类型提供外部显式实例化声明。这可能会导致模板的可用性仅限于您明确实例化的类型。

我希望用户自己能够[实例化模板],

那么这是不可能的事情(或者这会使您的库变得不可用且毫无意义)。使用模板实例化模板的任何人必须查看模板的整体定义(或者在某些情况下,可以在其中提供该类型的外部显式实例化上面提到的一个单独的翻译单元)。如果用户看不到他使用的所有符号的完整定义,并且不提供外部显式实例化,则用户最终只会从模板中获得undefined reference to个符号。

为进一步研究,我建议仅在C ++,模板的上下文中研究“显式实例化”一词,以及何时使用它以及与“隐式实例化”有何不同。为了进一步研究,请查看有关编译器和链接器如何工作,什么是链接以及如何设计C ++模板的材料。