CMake target_来源和安装

CMake target_来源和安装,cmake,Cmake,我很难弄清楚如何安装中指定的公共头文件 除了将私有源添加到可执行文件之外,目标源似乎有点神秘。 在阅读了大量的资料后,我设法理解了这个问题,并通过目标资源和公共文件绕过了这个问题。cMcList.txt在我的C++库项目的许多子目录中的一个看起来是这样的: target_sources(mylib PRIVATE foo.cpp PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/foo.h

我很难弄清楚如何安装中指定的公共头文件

除了将私有源添加到可执行文件之外,目标源似乎有点神秘。 在阅读了大量的资料后,我设法理解了这个问题,并通过目标资源和公共文件绕过了这个问题。cMcList.txt在我的C++库项目的许多子目录中的一个看起来是这样的:

target_sources(mylib
    PRIVATE
        foo.cpp

    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/foo.hpp>
        $<INSTALL_INTERFACE:foo.hpp>
)
install(
    TARGETS
        mylib
    EXPORT mylib-targets
    LIBRARY
        DESTINATION ${CMAKE_INSTALL_LIBDIR}
        COMPONENT lib
    ARCHIVE
        DESTINATION ${CMAKE_INSTALL_LIBDIR}
        COMPONENT lib
    RUNTIME
        DESTINATION ${CMAKE_INSTALL_BINDIR}
        COMPONENT bin
    INCLUDES
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mylib
但是,这不会安装任何头文件。 这提到了使用,但阅读文档并没有让我觉得这与我的情况相关

问题:使用install安装公共或接口头的正确方法是什么

背景:我的目标是在源代码树的每个子目录中都有一个单独的CMakeLists.txt。这些列表中的每一个都应该使用目标_源向构建中添加私有和公共文件。所有公共和接口源都应在安装过程中安装。

目标\u源命令的公共部分与使用安装命令的公共\u头选项安装的公共头没有任何共同之处

要将库视为公共的标题应列在目标的属性中

的文档提供了一个设置和安装私有头的好例子。在您的情况下,这将是:

# This defines `foo.hpp` located in the current source directory as a 'public header'.
set_target_properties(mylib PROPERTIES PUBLIC_HEADER foo.hpp)
# This install public headers among with the library.
install(
  TARGETS
    mylib
  PUBLIC_HEADER
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mylib
  # ... other options
)
另请参见相关问题:

另外请注意,installTARGETS命令的include和PUBLIC_HEADERS子句是不同的:

INCLUDES为已安装的库指定包含目录 PUBLIC_HEADERS指定安装时复制所有目标的公共头的目录。 例如,如果您希望头文件通过

#include <mylib/foo.h>
因此,通过/与include指令中的相对路径连接将提供头文件的绝对路径。

target\u sources命令的PUBLIC部分与使用install命令的PUBLIC\u header选项安装的公共头没有任何共同之处

要将库视为公共的标题应列在目标的属性中

的文档提供了一个设置和安装私有头的好例子。在您的情况下,这将是:

# This defines `foo.hpp` located in the current source directory as a 'public header'.
set_target_properties(mylib PROPERTIES PUBLIC_HEADER foo.hpp)
# This install public headers among with the library.
install(
  TARGETS
    mylib
  PUBLIC_HEADER
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mylib
  # ... other options
)
另请参见相关问题:

另外请注意,installTARGETS命令的include和PUBLIC_HEADERS子句是不同的:

INCLUDES为已安装的库指定包含目录 PUBLIC_HEADERS指定安装时复制所有目标的公共头的目录。 例如,如果您希望头文件通过

#include <mylib/foo.h>

因此,通过/与include指令中的相对路径连接将提供头文件的绝对路径。

公共头文件总是让我感觉这是一个macOS/iOS特有的功能。根据您的帖子,我认为这是错误的?我会将此属性解释为:此属性适用于macOS/iOS,但也适用于其他平台。请参阅非Apple平台上的短语。这些标头可以使用installTARGETS命令的PUBLIC_HEADER选项安装。在.My中对该属性的描述结束时,我的结论是:使用installTARGETS时,target\u sources绝对无效。因此,当我试图在我的库的每个子目录中都有一个单独的CMakeLists.txt时,我只是使用旧方法将每个源文件相对于顶级CMakeLists.txt的路径添加到变量列表中,然后使用installFILES。对吗?我一直在寻找一种方法,在每个子目录中都有一个CMakeLists.txt,列出该目录相对于该CMakeLists.txt的源文件,同时在安装时保留目录结构。是的,在非苹果平台上,PUBLIC_头没有简单安装文件的优势。至于目标源,我发现它只对接口目标有用。对于普通的库来说,直接在add_library调用中列出它的源代码更简单。PUBLIC_头文档总是让我觉得这是macOS/iOS特有的功能。根据您的帖子,我认为这是错误的?我会将此属性解释为:此属性适用于macOS/iOS,但也适用于其他平台。请参阅非Apple平台上的短语。这些标头可以使用installTARGETS命令的PUBLIC_HEADER选项安装。在.My中对该属性的描述结束时,我的结论是:使用installTARGETS时,target\u sources绝对无效。因此,当我试图在我的库的每个子目录中都有一个单独的CMakeLists.txt时,我只是使用旧方法将每个源文件相对于顶级CMakeLists.txt的路径添加到变量列表中,然后使用installFILES。对吗?我一直在寻找一种方法,在每个子目录中都有一个CMakeLists.txt,列出该目录相对于该CMakeLists.txt的源文件,同时保留目录str
是的,在非苹果平台上,PUBLIC_头与简单的安装文件相比没有优势。至于目标源,我发现它只对接口目标有用。对于普通库,直接在add_library调用中列出其源代码更简单。那么,您是否最终将set_target_属性和target_源代码添加到每个子目录CMakeLists.txt?是的。现在,所有操作都是使用子目录中的各种目标函数完成的。但是,公共头被添加到名为headers\u public的列表中,该列表随后被传递到目标源,但也传递到相应的安装指令。如果这对你有帮助的话,我可以发表一篇关于这个的博客文章。可能需要几天时间。不,没关系。谢谢你的提议。我相信我现在已经成功了;虽然我没有在子目录CMakeLists.txt中使用install命令,但从您的评论来看,这似乎就是您正在做的。那么您是否最终将set_target_属性和target_源添加到每个子目录CMakeLists.txt?是的。现在,所有操作都是使用子目录中的各种目标函数完成的。但是,公共头被添加到名为headers\u public的列表中,该列表随后被传递到目标源,但也传递到相应的安装指令。如果这对你有帮助的话,我可以发表一篇关于这个的博客文章。可能需要几天时间。不,没关系。谢谢你的提议。我相信我现在已经成功了;虽然我没有在子目录CMakeLists.txt中使用install命令,但从您的评论来看,这似乎就是您正在做的事情。