简体   繁体   English

使用 GoogleTest 的 C 项目的构建/链接器错误

[英]Build/linker error for a C project using GoogleTest

So I have a simple template for C projects that I have created, and have used it to implement the bowling game kata to shake out the bugs.所以我有一个简单的模板用于我创建的 C 项目,并用它来实现保龄球游戏 kata 以消除错误。 The template is for a C project using C11, and it uses GTest as the testing framework.该模板适用于使用 C11 的 C 项目,它使用 GTest 作为测试框架。

I have got stuck with a linker issue when CMake is trying to build the test binary.当 CMake 尝试构建测试二进制文件时,我遇到了 linker 问题。

The CMakeLists.txt in the test directory is as follows测试目录下的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)

Without the lines in the 'added these' block (as I originally had the file), I get an undefined reference to all of the functions I'm trying to call from my source code (located at src/library.c and include/template_demo/library.h).如果没有“添加这些”块中的行(因为我最初拥有该文件),我会从我的源代码中获得对我试图调用的所有函数的未定义引用(位于 src/library.c 并包含/模板演示/库.h)。

So I added the lines in the 'added these' block, as I thought that the issue was the test binary couldn't see the source code.所以我在“添加这些”块中添加了这些行,因为我认为问题是测试二进制文件看不到源代码。 With these lines in, the error changes to a no such file issue.加入这些行后,错误将变为无此类文件问题。

/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

The production binary is still built and runs OK as far as I can tell (it's a minimal stub).据我所知,生产二进制文件仍然构建并运行良好(这是一个最小的存根)。

The test_template_demo.cpp has extern C around the include for the library.h. test_template_demo.cpp 在 library.h 的包含周围有 extern C。

Any help gratefully received!任何帮助都感激不尽!

Edit: The undefined reference error (the first one at least) is编辑:未定义的参考错误(至少第一个)是

/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'

The other errors are essentially the same, but when calling the other functions in the file.其他错误基本相同,但在调用文件中的其他函数时。

The score_game function is defined in src/library.c, and has the following structure (implementations omitted for brevity) score_game function 定义在 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)
{...}

The header that goes with the file is located at include/template_demo/library.h文件附带的 header 位于 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

Edit:编辑:

By adding the following line to my tests/CMakeLists.txt通过将以下行添加到我的测试/CMakeLists.txt

target_link_libraries(template-demo-test PRIVATE template_library)

It resolved the issue and allowed the test binary to run.它解决了问题并允许测试二进制文件运行。

The final tests/CMakeLists.txt now looks like最终的测试/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)

Which seems more reliable and stable than the original.这似乎比原来的更可靠和稳定。

Your structure basically looks like this:您的结构基本上如下所示:

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

main_library is then added as target_link_libraries to main_binary and google_binary .然后将main_library作为target_link_libraries添加到main_binarygoogle_binary

Either that, or you have to replicate the main_binary sources into the google_binary as well, but this is more error prone, because it means that you have to maintain two separate projects in sync.要么,要么您必须将main_binary源也复制到google_binary中,但这更容易出错,因为这意味着您必须保持两个独立的项目同步。 Using the library approach makes it easier.使用库方法使其更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM