【问题标题】:Configuring CMake to re-compile source when unit testing配置 CMake 以在单元测试时重新编译源代码
【发布时间】:2015-06-03 03:24:41
【问题描述】:

我在下面定义了一个项目结构,其中包含 src 和 test 目录。

├── CMakeLists.txt
├── src
│   ├── CMakeLists.txt
│   ├── table.c
│   └── table.h
├── test
│   ├── CMakeLists.txt
│   └── test_table.c
├── build
    ├── src    [src build]
    └── test   [src + test build with UNIT_TESTING defined]

我想配置 cmake,以便在构建测试(单元测试)目录时,它还使用 UNIT_TESTING 定义集编译 ./src 目录中的文件,并将所有构建工件放在 ./build/test /目录。

这样我可以在 UNIT_TESTING 时使用 malloc free 的包装函数等来跟踪内存泄漏,而在没有单元测试的情况下正常构建时使用实际内存分配函数。

有人知道如何让我开始吗?

【问题讨论】:

    标签: unit-testing cmake


    【解决方案1】:

    首先我会推荐一个out-of-source-build 像这样:

    ├── build
    │   ├── src
    │   └── test
    └── code
        ├── CMakeLists.txt
        ├── src
        │   ├── CMakeLists.txt
        │   ├── table.c
        │   └── table.h
        └── test
            └── CMakeLists.txt
            └── test_table.c
    

    code 中的顶级 CMakeLists.txt 如下所示:

    project(example)
    set(BUILD_TESTS FALSE CACHE BOOL "Build unit tests")
    if(BUILD_TESTS)
        add_definitions(-DUNIT_TESTING)
        add_subdirectory(test)
    endif()
    add_subdirectory(src)
    

    然后您配置项目两次:

    1. build/src: cmake ../../code
    2. 构建/测试中: cmake -DBUILD_TESTS:BOOL=TRUE ../../code

    (2.) 将构建 srctest 以及额外的 #define,而 (1.) 将仅构建 src

    【讨论】:

    • 感谢您的回答。你确定这行得通吗?当然(2)仍然会构建单元测试源到 ./build/src 而不是所需的 ./build/test/src?
    • (对不起,我在完全输入之前提交了评论!)当然(2)仍然会将单元测试源构建到 ./build/src 而不是所需的 ./build/test/src?我不会在同一个构建文件夹中同时拥有生产编译和单元测试编译。还是在与单元测试完全不同的构建目录中构建生产二进制文件是一种好习惯?
    • @Adam 您将拥有两个完全独立的构建。当您在 build/src 中运行 make 时,它将仅构建 src,而当您在 build/test 中运行 make 时,它将构建 srctest。所有这些都发生在各自的构建目录中。是的,我认为将生产和测试二进制文件分开是一种很好的做法。
    【解决方案2】:

    使用 How to build a program with 2 different values of a variable in CMake 进一步了解 ms 的答案,您甚至可以在一个生成的构建环境中执行此操作。

    CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)
    project(Example C)
    add_subdirectory(src)
    add_subdirectory(test)
    

    src/CMakeLists.txt

    set(inFiles table.c table.h)
    add_library(TableLib ${inFiles})
    add_library(TestTableLib ${inFiles})
    set_property(TARGET TestTableLib APPEND PROPERTY COMPILE_DEFINITIONS "UNIT_TESTING")
    

    test/CMakeLists.txt

    add_executable(TestTableExe test_table.c)
    add_dependencies(TestTableExe TestTableLib)
    # add_test(NAME RunTableTest COMMAND ...)
    

    CMake 会注意 TableLibTestTableLib 的编译器输出最终位于不同的目录中。

    唯一的缺点是您将有两个目标具有相同的源文件(TableLibTestTableLib)。但是您可以在某些 IDE 中使用 FOLDER 目标属性将它们分组。

    另一种方法是将您需要的文件直接编译到测试中。如果您有一些东西被模拟/存根并且您不想或者您无法链接“代码确实要测试”的所有依赖项,这有时会非常方便。

    test/CMakeLists.txt(包含所有来源的版本)

    include_directories(../src)
    add_definitions(-DUNIT_TESTING)
    add_executable(TestTableExe test_table.c ../src/table.c ../src/table.h)
    # add_test(NAME RunTableTest COMMAND ...)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多