Article

Can I use [[ GoogleTest for a C project,**]]=] or is it only for C++?

Topic: TravelBy Rchard MathewPublished Recently added

Legacy signals

Legacy popularity: 274 legacy views

I'll walk you through the process of setting up GoogleTest for a C project and help you resolve common linker errors. Additionally, I'll include a detailed FAQ section to address these errors and provide solutions.

1. Project Setup Overview

1.1 File Structure

Let's start by clarifying the structure of your project:

makefile

Copy code

ProjectRoot/ â âââ CMakeLists.txt # CMake configuration file âââ src/ # Source files â âââ main.c # Your main C file, calling the add function âââ include/ # Header files â âââ add.h # Declaration of the add function âââ tests/ # Test files âââ test_example.cpp # GoogleTest test for the add function

1.2 Key Files

src/main.c

c

Copy code

#include "add.h" int main() { int result = add(2, 3); return result; }
include/add.h

c

Copy code

#ifndef ADD_H #define ADD_H #ifdef __cplusplus exter
"C" { #endif int add(int a, int b); #ifdef __cplusplus } #endif #endif // ADD_H
tests/test_example.cpp

cpp

Copy code

#include <gtest/gtest.h> exter
"C" { #include "add.h" } TEST(AddFunctio
Test, BasicTest) { EXPECT_EQ(add(2, 3), 5); }

1.3 CMake Configuration (CMakeLists.txt)

Your CMakeLists.txt should include the following basic configuration:

cmake

Copy code

cmake_minimum_required(VERSION 3.10) project(MyCProject) # Enable testing enable_testing() # Specify where to find GoogleTest find_package(GTest REQUIRED) # Include the directories for header files include_directories(include) # Add the source directory add_executable(main src/main.c) # Add the test directory (C++ test file) add_executable(test_example tests/test_example.cpp) # Link the test executable to GoogleTest target_link_libraries(test_example GTest::GTest GTest::Main) # Enable testing for the test executable add_test(NAME MyTest COMMAND test_example)

1.4 GoogleTest Installation

Ensure that GoogleTest is installed and correctly linked. If you're using CMake's find_package(GTest REQUIRED) feature, make sure you've installed the GoogleTest package either via vcpkg, Conan, or manually.

2. Common Linker Errors and Solutions

2.1 LNK2019: Unresolved Exte
al Symbol

Error Message:

sql

Copy code

LNK2019: unresolved exte
al symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z) referenced in function _main
This error occurs when the linker cannot find the definition of a function that was declared. In your case, the add function is declared in add.h but might not be properly defined or linked.

Solution:

Ensure Function Definition Exists: The error suggests that while the add function is declared, it isn't defined. You'll need to define it somewhere, such as in a .c file.

For example, in src/add.c:

c

Copy code

#include "add.h" int add(int a, int b) { return a + b; }
Link the add.c File: Ensure that add.c is part of your CMake configuration. If you don't include it, the linker won't be able to find the definition of add:

Modify the CMakeLists.txt file:

cmake

Copy code

add_executable(main src/main.c src/add.c)
This tells CMake to include add.c in the build, so the linker can find the definition of add.

2.2 LNK2005: Symbol Redefined

Error Message:

kotli

Copy code

LNK2005: "int __cdecl add(int,int)" (?add@@YAHHH@Z) already defined in main.obj
This error occurs when the same symbol (in this case, the add function) is defined in multiple places.

Solution:

Header Guards: Ensure that your add.h header file has proper include guards (which you already have). This prevents the header from being included multiple times in different source files.

Exte
"C" in C++ Files: In your test_example.cpp, the exter
"C" block ensures that the C function add is treated with C linkage and not C++ linkage. If you missed this in your C++ test file, it could cause the linker to treat the function as if it has C++ name mangling, resulting in a conflict.

No Duplicate Definitions: If you have the function definition (int add(int a, int b) {...}) in a .h file or if it is included in multiple .c files, it can result in a multiple definitions issue. Ensure that function definitions only exist in .c files, not headers.

2.3 Resolving LNK Errors with CMake

Object File Conflicts: If the error persists, try doing a clean rebuild by deleting your build folder and regenerating the build files. Sometimes, old object files from previous builds can cause conflicts.

3. FAQ on Linker Errors (LNK2019 & LNK2005) in GoogleTest Setup

3.1 What is LNK2019?

Answer: LNK2019 is a linker error that occurs when the linker cannot find the definition of a symbol (function or variable) that was declared and referenced. It usually happens when:

The function is declared but not defined.

The object file containing the function definition is not linked to the project.

To fix LNK2019, make sure that:

The function is properly defined in a source file.

The source file is included in the CMake build configuration.

3.2 What is LNK2005?

Answer: LNK2005 is a linker error that occurs when a symbol (such as a function or variable) is defined multiple times. This can happen when:

A function is defined in both a header file and a source file.

The same source file is included multiple times or linked multiple times.

To fix LNK2005, ensure:

Function definitions are placed in source files (.c or .cpp), not in headers.

Use #ifndef guards in header files to prevent multiple inclusions.

Use exter
"C" in C++ files when calling C functions to avoid name mangling conflicts.

3.3 How can I debug linker errors in Visual Studio?

Answer: To debug linker errors in Visual Studio:

Go to View > Output to see the build log.

Look for any missing or duplicated symbols in the linker output.

Check the CMakeLists.txt for errors in source file inclusion or library linking.

Clean and rebuild the project to ensure no stale object files remain.

If using find_package to locate GoogleTest, ensure the path to the GoogleTest package is correct.

3.4 Why am I getting "unresolved exte
al" errors with GoogleTest?

Answer: This can occur if:

GoogleTest is not correctly linked to your test executable.

The GTest::GTest and GTest::Main targets are missing in the target_link_libraries command in your CMakeLists.txt.

Make sure GoogleTest is correctly installed, and that your CMake configuration properly links it.

3.5 Can I use GoogleTest for a C project, or is it only for C++?

Answer: Although GoogleTest is a C++ testing framework, it can still be used in C projects with a few precautions:

C functions need to be declared with exter
"C" when included in C++ files to prevent name mangling.

GoogleTest itself is a C++ library, so you need to compile and link the test files as C++ files (.cpp).

3.6 How can I prevent conflicts betwee
C and C++ in my project?

Answer: To avoid conflicts betwee
C and C++ code in your project:

Use exter
"C" in C++ files when declaring C functions.

Make sure that all function definitions are placed in .c files, not in header files.

Use separate compilation for C and C++ files in CMake.

4. Conclusion

Setting up unit tests in a C project using GoogleTest can be a bit tricky due to the interaction betwee
C and C++ code, especially when dealing with linker errors like LNK2019 and LNK2005. By ensuring correct declarations, proper CMake configurations, and using exter
"C" to manage the C/C++ boundary, you can avoid these common pitfalls. The solutions and FAQ provided above should help guide you through these challenges and get your unit testing up and running smoothly.

Article author

About the Author

Rchard Mathew is a passionate writer, blogger, and editor with 36+ years of experience in writing. He can usually be found reading a book, and that book will more likely than not be non-fictional.