【问题标题】:Omiting declarations of header files in source code compiled by CMake在 CMake 编译的源代码中省略头文件的声明
【发布时间】:2019-09-12 18:51:02
【问题描述】:

我最近一直在学习并熟悉 CMake,希望能够彻底改造工作中的项目以使用它。我知道当我创建一个库目标并将其链接到几个不同的可执行目标时,该库只编译一次。

我发现我可以删除源代码中的#include,同时保留对库的函数调用,并且代码编译和运行都很好。这对我来说似乎是不好的做法,为了便于阅读,我更愿意将#include 保留在库中。但是,如果我保留所有这些#include,是否会为每个单独的可执行文件编译这些库?

【问题讨论】:

  • 你能提供一个Minimal Reproducible Example 来证明这种行为吗?
  • 不确定你想要什么。 “我希望将#include 保留在库中” - #include 包含 headers,但库是 linked(在 CMake 中使用 target_link_libraries 命令)。跨度>
  • If I keep in all those #includes, will those libraries be compiled for each separate executable? 源代码中的预处理器语句#include 与库是否已启用编译和/或将与之链接无关。
  • 除非内容未被使用,否则不应从代码中省略标头。如果您使用在标头中声明的函数,请使用标头。
  • 听起来好像你不确定头文件的用途。它们不仅使 IDE 能够提供自动完成等功能,而且对于正确调用函数至关重要。例如,假设您的代码调用myfunc(123)。如果没有标头,myfunc 仍将被调用,它将传递包含整数 123 的 4 个字节。如果 myfunc 被声明为采用整数(这可能是您的代码运行良好的原因),那就没问题了……但是如果myfunc 真的需要浮动怎么办?有了标头,编译器就有了正确地将 123 转换为 123.0 的信息。

标签: c cmake


【解决方案1】:

库目标将被编译一次,然后链接到您的可执行文件。当您修改可执行文件的文件时,不会重新编译该库。如果您修改库,它将被重建并且可执行文件将被重新链接。

只要您在库目标中包含标头,那么链接目标的所有可执行文件也将链接标头。所以是这样的:

add_library(my_super_cool_lib my_header.h
                              my_code.cpp)

然后可以链接

add_executable (do_cool_stuff cool_code.cpp)
target_link_libraries(do_cool_stuff my_super_cool_lib)

标题会自动添加到路径中

如果您创建一个链接到其他库的库,那么您可以选择如何处理标题。在 CMake 中,这被称为“链接接口”

  • 您只需在本地使用它们来构建您的库 - PRIVATE
  • 您可以在本地使用它们,也可以“转发”它们,以便链接您的库的任何人也将获得这些标题 - PUBLIC
  • 你甚至不能在本地使用它们,但让任何链接你的图书馆的人都能得到它们 - 界面

这些是用可选参数设置的:

target_link_libraries(do_cool_stuff <PRIVATE|PUBLIC|INTERFACE> my_super_cool_lib)

见:https://cmake.org/cmake/help/v3.0/command/target_link_libraries.htmlhttps://cmake.org/cmake/help/v3.0/command/add_library.html 文档有点枯燥,但非常全面。请仔细阅读并重新阅读:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 2020-10-02
    相关资源
    最近更新 更多