Build/linker 使用 GoogleTest 的 C 项目错误

Build/linker error for a C project using GoogleTest

所以我为我创建的 C 项目创建了一个简单的模板,并用它来实现保龄球游戏套路以消除错误。该模板是一个使用C11的C项目,它使用GTest作为测试框架。

当 CMake 尝试构建测试二进制文件时,我遇到了链接器问题。

test目录下的CMakeLists.txt如下

include(AddGoogleTest)

## Added these #########
include_directories("${PROJECT_SOURCE_DIR})/include")
set(FILES ../src/library.c ../include/template_demo/library.h)
##################

set(TEST_FILES test_template_demo.cpp)
add_executable(template-demo-test ${TEST_FILES} ${FILES})
add_gtest(template-demo-test)

没有 'added these' 块中的行(因为我最初有文件),我得到了对我试图从我的源代码(位于 src/library.c 和 include/template_demo/library.h).

所以我在 'added these' 块中添加了这些行,因为我认为问题是测试二进制文件看不到源代码。有了这些行,错误就变成了没有这样的文件问题。

/projects/template_bowling/src/library.c:2:10: fatal error: template_demo/library.h: No such file or directory
    2 | #include "template_demo/library.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [tests/CMakeFiles/template-demo-test.dir/build.make:90: tests/CMakeFiles/template-demo-test.dir/__/src/library.c.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:1023: tests/CMakeFiles/template-demo-test.dir/all] Error 2
make: *** [Makefile:146: all] Error 2

生产二进制文件仍在构建中,据我所知运行没问题(这是一个最小的存根)。

test_template_demo.cpp 在 library.h.

的包含周围有 extern C

感谢收到任何帮助!

编辑:未定义的引用错误(至少是第一个)是

/usr/bin/ld: CMakeFiles/template-demo-test.dir/test_template_demo.cpp.o: in function `BowlingTest_test_bowling_gutter_game_Test::TestBody()':
test_template_demo.cpp:(.text+0x42): undefined reference to `score_game'

其他错误基本相同,只是在调用文件中的其他函数时。

score_game 函数在 src/library.c 中定义,具有以下结构(为简洁起见省略了实现)

#include <stdlib.h>
#include "template_demo/library.h"

#define MAX_ROLLS 21

struct bowling
{...};

struct bowling *bowling_init(void)
{...}

void bowling_free(struct bowling *b)
{
    free(b);
}

void roll_ball(struct bowling *b, int n)
{...}

int score_game(struct bowling *b)
{...}

文件头位于 include/template_demo/library.h

#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct bowling;
struct bowling *bowling_init(void);
void bowling_free(struct bowling *b);
void roll_ball(struct bowling *b, int n);
int score_game(struct bowling *b);
#ifdef __cplusplus
}
#endif

编辑:

通过将以下行添加到我的 tests/CMakeLists.txt

target_link_libraries(template-demo-test PRIVATE template_library)

它解决了问题并允许测试二进制文件 运行。

最后的 tests/CMakeLists.txt 现在看起来像

include(AddGoogleTest)

set(TEST_FILES
        test_template_demo.cpp
        )
add_executable(template-demo-test ${TEST_FILES})
target_link_libraries(template-demo-test PRIVATE template_library)
add_gtest(template-demo-test)

看起来比原来的更可靠和稳定。

你的结构基本上是这样的:

project
    main_binary (just the startup code for the main code)
    main_library (code which needs to be tested)
    google_binary

main_library 然后作为 target_link_libraries 添加到 main_binarygoogle_binary.

或者您必须将 main_binary 源也复制到 google_binary 中,但这更容易出错,因为这意味着您必须保持两个独立的项目同步.使用库方法更容易。