【问题标题】:CMake target to just compile a source fileCMake 目标仅编译源文件
【发布时间】:2020-06-14 13:25:11
【问题描述】:

我正在使用 C++17 编写一个仅包含标头的库。我想将它包含在一个“虚拟”源文件中:

#include "my/library.h"
// EOF

目的是确保库正确包含其所有依赖项。我还想在其上运行静态分析器,并在启用尽可能多的编译器检查的情况下对其进行编译。

要创建一个正常的可执行目标,我需要添加main() 函数,否则链接阶段将失败。 我想我也可以创建一个静态库目标,它应该可以正常工作,尽管它会创建一个我不需要的工件。

还有其他选择吗?

【问题讨论】:

  • 即使您创建了一个库,您也必须从具有 main 的程序加载它(或从另一个库加载,该库将由具有 main 函数的 exec 加载)。我不明白你的问题
  • 也许只是添加单元测试,所以库被编译为副作用。
  • 我需要验证库中的代码:a) 没有丢失的包含,b) 编译干净且没有警告,c) 通过静态分析。这些检查都不需要构建可执行文件。
  • 我确实有单元测试。事实上,我在 TDD 中使用严格的红绿重构周期开发库。我不希望编译作为副作用。我希望它作为(几乎)唯一的目的,这就是为什么我想要一个单独的目标。
  • 您可以告诉 CMake 将其构建到 Object library 中,基本上只是 .o 或 .obj 目标文件。使用这个:add_library(MyObj OBJECT library.cpp),其中library.cpp 是您的虚拟源文件。

标签: c++ cmake compilation header-only


【解决方案1】:

大多数编译器允许您覆盖输入类型的默认扩展名。如果您只是将my/library.h 作为输入文件传递给编译器,它可以将其编译为library.o 或library.obj。

请注意,如果不编译可执行文件,您无法确定您的library.h 是否完整。特别是,C++ 要求非inline static const 类成员在每个程序中只定义一次,如果它们是 odr 使用的。因此,如果您在library.h 中忘记了inline,您可能不会在简单测试中注意到这一点。即使您添加一个空的main(),仍然不会使用这些成员。

【讨论】:

    【解决方案2】:

    CMake 可以创建一个简单的Object 库,它只会是一个.o 或.obj 文件:

    OBJECT 库类型定义了由编译给定源文件产生的目标文件的非归档集合。

    为此,请将OBJECT 关键字与add_library() 命令一起使用:

    add_library(MyObj OBJECT ${CMAKE_CURRENT_SOURCE_DIR}/library.cpp)
    target_include_directories(MyObj PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
    

    您可以稍后引用要编译到其他库或可执行文件中的目标文件:

    add_library(MyLibrary STATIC 
        $<TARGET_OBJECTS:MyObj> 
        MyOtherSource.cpp 
        HelpersFunctions.cpp
    )
    

    【讨论】:

      猜你喜欢
      • 2021-02-20
      • 1970-01-01
      • 2015-08-04
      • 1970-01-01
      • 2013-01-24
      • 2016-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多