2

I'm new to cmake and I'm trying to create a CMakeLists.txt for compiling my test files. I have 3 files: calc.cpp, calc.hpp, and calc_test.cpp and I use the following command to compile my tests:

g++ -o calc_test calc_test.cpp calc.cpp -lgtest -lpthread

which generates a binary file (calc_test) that I execute to run my tests.

Here's my calc.hpp:

#ifndef CALC_HPP_
#define CALC_HPP_

int add(int op1, int op2);
int sub(int op1, int op2);

#endif

My calc.cpp:

#include "calc.hpp"

int add(int op1, int op2) {
    return op1 + op2;
}

int sub(int op1, int op2) {
    return op1 - op2;
}

And my calc_test.cpp:

#include <gtest/gtest.h>
#include "calc.hpp"

TEST(CalcTest, Add) {
    ASSERT_EQ(2, add(1, 1));
    ASSERT_EQ(5, add(3, 2));
    ASSERT_EQ(10, add(7, 3));
}

TEST(CalcTest, Sub) {
    ASSERT_EQ(3, sub(5, 2));
    ASSERT_EQ(-10, sub(5, 15));
}

int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

Now I have created a CMakeLists.txt file to compile my test files and it generates Makefile successfully, but when I execute cmake --build . it throws undefined reference error. Here's the content of my CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)

project(Google_Test)

add_library(TestModlue calc.cpp)
target_link_libraries(TestModlue -lgtest -lpthread)

add_executable(calc_test calc_test.cpp)

What am I doing wrong?

Farzin
  • 359
  • 1
  • 4
  • 21
  • You probably need to link your `calc_test` application against googleTest, instead of your library. – Alexey S. Larionov Feb 03 '21 at 14:11
  • How can I do that? As I've said I'm new to cmake. @AlexeyLarionov – Farzin Feb 03 '21 at 14:14
  • Best approach is to create a library from your main project. This library can you then link against the main executable or the Google Test binary, as both are individual executables, but need to share your main code. I had a sample project, but I can't find it. :( – Devolus Feb 03 '21 at 14:34
  • Thanks, I'll share my files. @Devolus – Farzin Feb 03 '21 at 14:43
  • List the library names without `-l`, i.e. `target_link_libraries(TestModlue gtest pthread)` Furthermore you're linking `gtest` to your lib, but link neither that lib nor gtest to the executable. Since `calc_test.cpp` us he file using gtest, you should link the lib to the target that actually makes use of `gtest`, not some other target. `target_link_libraries(calc_test gtest TestModlue pthread)` seems to be the correct version of the `target_link_libraries` command. (To be positioned after `add_executable`) – fabian Feb 03 '21 at 18:58
  • If you just want to **replicate** the command line `g++ -o calc_test calc_test.cpp calc.cpp -lgtest -lpthread`, then it creates a single executable without the library. That is, your `CMakeLists.txt` with `add_library` doesn't correspond to the your intentions. But creating a library and test executable is actually a proper way for use gtest. See the [duplicate question](https://stackoverflow.com/questions/8507723/how-to-start-working-with-gtest-and-cmake) and its answers. E.g. your current approach corresponds to that answer: https://stackoverflow.com/a/34980359/3440745. – Tsyvarev Feb 03 '21 at 20:20

1 Answers1

0

You can use this as an example how to setup a project structure. It basically follows what I wrote above in my comment. CMake Google Test Example

* Your main code is put inside a library instead of directly including it in the application
* Create a seperate main binary (your application)
* Create another binary which contains your google tests
* Link both projects (application/gtests) against your library
Devolus
  • 21,661
  • 13
  • 66
  • 113