ошибка компоновщика при создании тестового модуля Google с использованием cmake - PullRequest
0 голосов
/ 29 октября 2019

Как получить этот код cmake / gtest для сборки

У меня есть библиотечные источники в папке lib:

computing.hpp:

#ifndef  CALCULATIONS_HPP_
#define CALCULATIONS_HPP_

class calculations {
public:
  int square(int n);
};

#endif // CALCULATIONS_HPP_

computing.cpp:

#include "calculations.hpp"

int calculations::square(int n) {
  return n * n;
}

Файл CMakeLists.txt в этой папке:

set(SRC_FILES calculations.cpp)
add_library(Calculations STATIC "${SRC_FILES}")

в корневой папке:

computing_unittests.cpp:

#include "calculations.hpp"

#include <gtest/gtest.h>

TEST(CalculationsUnitTests, square_test) {
  calculations calc;
  ASSERT_EQ(calc.square(2), 4);
}

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

CMakeLists.txt в этой корневой папке:

cmake_minimum_required(VERSION 3.5)

set (CMAKE_CXX_STANDARD 14)

set(GTEST_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libGoogleTest/googletest/include/")

message( "GTEST_INCLUDE_DIR = ${GTEST_INCLUDE_DIR}" )

message( "CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}" )

include_directories("${GTEST_INCLUDE_DIR}"
                    "${CMAKE_CURRENT_SOURCE_DIR}/lib/")

set(GTEST_LIBRARY "${CMAKE_CURRENT_SOURCE_DIR}/libGoogleTest/googletest/libgtest.a")
set(GTEST_MAIN_LIBRARY "${CMAKE_CURRENT_SOURCE_DIR}/libGoogleTest/googletest/libgtest_main.a")

message( "GTEST_LIBRARY = ${GTEST_LIBRARY}" )


add_subdirectory(lib)

# Locate GTest
find_package(GTest REQUIRED)

message( "lib = ${Calculations}" )

# Link runTests with what we want to test and the GTest and pthread library
add_executable(runTests calculations_unittests.cpp ${Calculations})

Также в этой корневой папке находится структура папки gtest. Папка libGoogleTest с папками.

Я также создал lib-файлы libgtest.a и libgtest_main.a, которые находятся в папке libGoogleTest / googletest.

Если я запускаю следующие команды из папки 'root':

combera@combera-1604_64:~/Documents/scratch/cmake_gtest$ cmake CMakeLists.txt 
GTEST_INCLUDE_DIR = /home/combera/Documents/scratch/cmake_gtest/libGoogleTest/googletest/include/
CMAKE_CURRENT_SOURCE_DIR = /home/combera/Documents/scratch/cmake_gtest
GTEST_LIBRARY = /home/combera/Documents/scratch/cmake_gtest/libGoogleTest/googletest/libgtest.a
lib = 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/combera/Documents/scratch/cmake_gtest
combera@combera-1604_64:~/Documents/scratch/cmake_gtest$ make runTests
[ 50%] Linking CXX executable runTests
CMakeFiles/runTests.dir/calculations_unittests.cpp.o: In function `CalculationsUnitTests_square_test_Test::TestBody()':
calculations_unittests.cpp:(.text+0x30): undefined reference to `calculations::square(int)'
calculations_unittests.cpp:(.text+0x73): undefined reference to `testing::Message::Message()'
calculations_unittests.cpp:(.text+0xa0): undefined reference to `testing::internal::AssertHelper::AssertHelper(testing::TestPartResult::Type, char const*, int, char const*)'
calculations_unittests.cpp:(.text+0xb3): undefined reference to `testing::internal::AssertHelper::operator=(testing::Message const&) const'
calculations_unittests.cpp:(.text+0xbf): undefined reference to `testing::internal::AssertHelper::~AssertHelper()'
calculations_unittests.cpp:(.text+0x107): undefined reference to `testing::internal::AssertHelper::~AssertHelper()'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o: In function `main':
calculations_unittests.cpp:(.text+0x164): undefined reference to `testing::InitGoogleTest(int*, char**)'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o: In function `__static_initialization_and_destruction_0(int, int)':
calculations_unittests.cpp:(.text+0x1da): undefined reference to `testing::internal::GetTestTypeId()'
calculations_unittests.cpp:(.text+0x248): undefined reference to `testing::internal::MakeAndRegisterTestInfo(char const*, char const*, char const*, char const*, testing::internal::CodeLocation, void const*, void (*)(), void (*)(), testing::internal::TestFactoryBase*)'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o: In function `RUN_ALL_TESTS()':
calculations_unittests.cpp:(.text._Z13RUN_ALL_TESTSv[_Z13RUN_ALL_TESTSv]+0x5): undefined reference to `testing::UnitTest::GetInstance()'
calculations_unittests.cpp:(.text._Z13RUN_ALL_TESTSv[_Z13RUN_ALL_TESTSv]+0xd): undefined reference to `testing::UnitTest::Run()'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o: In function `CalculationsUnitTests_square_test_Test::CalculationsUnitTests_square_test_Test()':
calculations_unittests.cpp:(.text._ZN38CalculationsUnitTests_square_test_TestC2Ev[_ZN38CalculationsUnitTests_square_test_TestC5Ev]+0x14): undefined reference to `testing::Test::Test()'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o: In function `testing::internal::scoped_ptr<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::reset(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)':
calculations_unittests.cpp:(.text._ZN7testing8internal10scoped_ptrINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5resetEPS7_[_ZN7testing8internal10scoped_ptrINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5resetEPS7_]+0x29): undefined reference to `testing::internal::IsTrue(bool)'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o: In function `testing::internal::scoped_ptr<std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> > >::reset(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >*)':
calculations_unittests.cpp:(.text._ZN7testing8internal10scoped_ptrINSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEEE5resetEPS7_[_ZN7testing8internal10scoped_ptrINSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEEE5resetEPS7_]+0x28): undefined reference to `testing::internal::IsTrue(bool)'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o: In function `testing::AssertionResult testing::internal::CmpHelperEQ<int, int>(char const*, char const*, int const&, int const&)':
calculations_unittests.cpp:(.text._ZN7testing8internal11CmpHelperEQIiiEENS_15AssertionResultEPKcS4_RKT_RKT0_[_ZN7testing8internal11CmpHelperEQIiiEENS_15AssertionResultEPKcS4_RKT_RKT0_]+0x43): undefined reference to `testing::AssertionSuccess()'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o: In function `testing::AssertionResult testing::internal::CmpHelperEQFailure<int, int>(char const*, char const*, int const&, int const&)':
calculations_unittests.cpp:(.text._ZN7testing8internal18CmpHelperEQFailureIiiEENS_15AssertionResultEPKcS4_RKT_RKT0_[_ZN7testing8internal18CmpHelperEQFailureIiiEENS_15AssertionResultEPKcS4_RKT_RKT0_]+0x87): undefined reference to `testing::internal::EqFailure(char const*, char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o:(.rodata._ZTV38CalculationsUnitTests_square_test_Test[_ZTV38CalculationsUnitTests_square_test_Test]+0x20): undefined reference to `testing::Test::SetUp()'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o:(.rodata._ZTV38CalculationsUnitTests_square_test_Test[_ZTV38CalculationsUnitTests_square_test_Test]+0x28): undefined reference to `testing::Test::TearDown()'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o: In function `CalculationsUnitTests_square_test_Test::~CalculationsUnitTests_square_test_Test()':
calculations_unittests.cpp:(.text._ZN38CalculationsUnitTests_square_test_TestD2Ev[_ZN38CalculationsUnitTests_square_test_TestD5Ev]+0x20): undefined reference to `testing::Test::~Test()'
CMakeFiles/runTests.dir/calculations_unittests.cpp.o:(.rodata._ZTI38CalculationsUnitTests_square_test_Test[_ZTI38CalculationsUnitTests_square_test_Test]+0x10): undefined reference to `typeinfo for testing::Test'
collect2: error: ld returned 1 exit status
CMakeFiles/runTests.dir/build.make:94: recipe for target 'runTests' failed
make[3]: *** [runTests] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/runTests.dir/all' failed
make[2]: *** [CMakeFiles/runTests.dir/all] Error 2
CMakeFiles/Makefile2:79: recipe for target 'CMakeFiles/runTests.dir/rule' failed
make[1]: *** [CMakeFiles/runTests.dir/rule] Error 2
Makefile:118: recipe for target 'runTests' failed
make: *** [runTests] Error 2

Я не вижу ни одного файла libCalculations.a, созданного где-либо.

Как это исправить?

Я могу собрать, используя make-файлы, например:

LIB_DIR=./lib

GOOGLE_TEST_LIB = gtest

GOOGLE_TEST_INCLUDE=./libGoogleTest/googletest/include/

G++ = g++
G++_FLAGS = -c -Wall -I $(GOOGLE_TEST_INCLUDE) -I ./lib
LD_FLAGS = -L ./libGoogleTest/googletest -l $(GOOGLE_TEST_LIB) -l pthread libCalculations.a

OBJECTS = main.o
TARGET = main

all: $(TARGET)

libCalculations.a: libCalculations.a
    ar rcs libCalculations.a calculations.o

calculations.o: calculations.hpp calculations.cpp
    g++ -o calculations.o $(LIB_DIR)/calculations.cpp

$(TARGET): $(OBJECTS)
    g++ -o $(TARGET) $(OBJECTS) $(LD_FLAGS)

%.o : %.cpp
    $(G++) $(G++_FLAGS) $<

clean:
    rm -f $(TARGET) $(OBJECTS)

.PHONY: all clean

Но как мне сделать эквивалент, используя cmake CMakeLists.txt?

1 Ответ

0 голосов
/ 30 октября 2019

После многих часов экспериментов я обнаружил, что этот файл CMakeLists.txt работает:

cmake_minimum_required(VERSION 3.5)

project(calcTests)

set (CMAKE_CXX_STANDARD 14)

set(GTEST_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libGoogleTest/googletest/include/")

#message( "GTEST_INCLUDE_DIR = ${GTEST_INCLUDE_DIR}" )

#message( "CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}" )

include_directories("${GTEST_INCLUDE_DIR}"
                    "${CMAKE_CURRENT_SOURCE_DIR}/lib/")

set(GTEST_LIBRARY "${CMAKE_CURRENT_SOURCE_DIR}/libGoogleTest/googletest/libgtest.a")
set(GTEST_MAIN_LIBRARY "${CMAKE_CURRENT_SOURCE_DIR}/libGoogleTest/googletest/libgtest_main.a")

message( "GTEST_LIBRARY: ${GTEST_LIBRARY}" )


add_subdirectory(lib)

# it seems that gtest is built with the shared .so pthreads lib
find_library(pthreads NAMES libpthread.so FIND_LIBRARY_USE_LIB64_PATHS)
message( "Using thread lib: ${pthreads}" )

# Locate GTest
find_package(GTest REQUIRED)

set(CMAKE_PREFIX_PATH "./lib")
find_library(Calculations NAMES libCalculations.a "./lib/")

message( "Calculations lib: ${Calculations}" )


add_executable(calcTests calculations_unittests.cpp ${Calculations} ${pthreads})

target_link_libraries(calcTests ${GTEST_LIBRARY} ${GTEST_MAIN_LIBRARY} ${Calculations} ${pthreads})
...