C测试-未定义的Unity和CMake参考



我目前正试图获得一个项目设置与代码覆盖和测试是在c。我目前的堆栈是CLion为IDE, Clang为编译器,gcov和lcov的覆盖,Unity为测试框架,和CMock模拟/存根在测试期间。

我现在有如下的包结构:

app/root
  | build
      | *.*
  |- cmake
     |- modules
        |- CodeCoverage.cmake
  |- coverage
      |- coverage.info
  |- external
      |- Unity
      |- CMock
      |- CMakeLists.txt
  |- src
      |- *.c
      |- *.h
      |- CMakeLists.txt
  |- tests
      |- *.c
      |- *.h
      |- CMakeLists.txt
  |- CMakeLists.txt

我的高级CMakeLists.txt看起来像:

cmake_minimum_required(VERSION 3.6)
project(my_c_app)
set(CMAKE_C_COMPILER "/usr/bin/clang")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake/modules)

set(CMAKE_VERBOSE_MAKEFILE ON)
add_subdirectory(external)
add_subdirectory(src)
add_subdirectory(tests)

我的应用程序级别CMakeLists.txt看起来像:

SET(CMAKE_CXX_FLAGS "-O0")
SET(CMAKE_C_FLAGS "-DLINUX -O0 -Wall -std=c99")
set(SOURCE_FILES
        util.c
        util.h)
add_executable(my_c_app ${SOURCE_FILES})
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(my_c_app Threads::Threads)
target_include_directories(my_c_app PUBLIC ${PROJECT_SOURCE_DIR}/include)

我的测试级别CMakeLists.txt看起来像:

enable_testing()
include(CodeCoverage)
include(CTest)
SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
SET(CMAKE_C_FLAGS "-DLINUX -O0 -Wall -std=c99 -g -fprofile-arcs -ftest-coverage")
SETUP_TARGET_FOR_COVERAGE(coverage tests ${PROJECT_SOURCE_DIR}/coverage/coverage "'/usr/*';'tests/*';'external/*'")
add_executable(tests util_test.c)
target_link_libraries(tests Unity CMock)
add_test(tests util_test.c)

目前我的问题是我没有做正确的事情。在尝试测试util.c中的函数时,我得到了一个未定义的引用:

CMakeFiles/tests.dir/util_test.c.o: In function `test_my_method':
/home/patches/my_c_app/tests/util_test.c:6: undefined reference to `my_method'

我的util_test.c当前是:

#include <unity.h>
#include "../src/util.h"
void test_my_method(void) {
    uchar result = my_method();
    // assertion and other logic would go here
}
int main(void) {
    UNITY_BEGIN();
    RUN_TEST(test_my_method);
    return UNITY_END();
}

我是一个测试驱动c开发和CMake的新手,所以我应该如何设置我的测试,使它们依赖于src中的c文件?

如果我只是执行TEST_ASSERT_EQUAL(1,1)而不是调用util.c函数,我确实看到:

1 Tests 0 Failures 0 Ignores
OK
Process finished with exit code 0

所以我觉得我100%卡住了链接器的问题。

util.c不是tests源代码的一部分,也不是在链接到tests的库中编译的。因此,您没有为my_method提供tests的任何定义,因此是未定义的引用。

您的可执行my_c_app的源代码中没有main.c文件。我猜你的主要功能是在util.c中定义的。如果我是对的,在main.c文件中取出它,并将您的应用程序级别CMakeLists.txt更改为:

SET(CMAKE_CXX_FLAGS "-O0")
SET(CMAKE_C_FLAGS "-DLINUX -O0 -Wall -std=c99")
set(SOURCE_FILES
        util.c
        util.h)
add_library(my_c_lib STATIC ${SOURCE_FILES})
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(my_c_app Threads::Threads)
target_include_directories(my_c_app PUBLIC ${PROJECT_SOURCE_DIR}/include)
add_executable(my_c_app main.c)
target_link_libraries(my_c_app my_c_lib)

现在您的源代码在静态库my_c_lib中编译,您可以链接到它。你的应用与它相关联,你也可以在你的测试级别CMakeLists.txt中与它相关联:

enable_testing()
include(CodeCoverage)
include(CTest)
SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
SET(CMAKE_C_FLAGS "-DLINUX -O0 -Wall -std=c99 -g -fprofile-arcs -ftest-coverage")
SETUP_TARGET_FOR_COVERAGE(coverage tests ${PROJECT_SOURCE_DIR}/coverage/coverage "'/usr/*';'tests/*';'external/*'")
add_executable(tests util_test.c)
target_link_libraries(tests Unity CMock my_c_lib)
                                        ^^^^^^^^
add_test(tests util_test.c)

关于这行:

add_test(tests util_test.c)

我在文档中没有看到一个签名记录目标及其来源。你想要达到什么目的?

请注意,您可以使用C_STANDARD而不是CMAKE_C_FLAGS指定C版本:

SET(CMAKE_C_STANDARD 99)

编译定义也可以用target_compile_definitions声明,以避免全局污染。

相关内容

  • 没有找到相关文章

最新更新