CMake с GoogleTest не может связать определение функции - PullRequest
0 голосов
/ 28 марта 2020

В настоящее время я изучаю CMake :) Проект прост: модульные тесты для моей собственной версии очереди в C. У меня есть следующая структура проекта:

Queue/
|--build/
|--lib/
|  |--CMakeLists.txt
|--src/
|  |--queue.h
|  |--queue.c
|--tst/
|  |--CMakeLists.txt
|  |--main.cpp
|  |--constructor_tests.cpp
|  |--destructor_tests.cpp
|--CMakeLists.txt

lib / CMakeLists.txt:

cmake_minimum_required (VERSION 3.1)
# Download and install GTest
include(ExternalProject)
ExternalProject_Add(gtest
  URL https://github.com/google/googletest/archive/release-1.8.0.zip

  PREFIX ${PROJECT_SOURCE_DIR}/lib/gtest
  INSTALL_COMMAND ""
)

tst / CMakeLists.txt:

cmake_minimum_required (VERSION 3.1)

# Include src directory
include_directories(${PROJECT_SOURCE_DIR}/src)

set(TESTS main.cpp
          constructor_tests.cpp
          destructor_tests.cpp
          ${PROJECT_SOURCE_DIR}/src/queue.c)

# Set paths for GTest include dir and GTest libs
set(GTEST_INCLUDE_DIR 
    ${PROJECT_SOURCE_DIR}/lib/gtest/src/gtest/googletest/include)
set(GTEST_LIB_DIR 
    ${PROJECT_SOURCE_DIR}/lib/gtest/src/gtest-build/googlemock/gtest)

add_executable(QueueTests ${TESTS})

add_dependencies(QueueTests gtest)
include_directories(${GTEST_INCLUDE_DIR})
target_link_libraries(QueueTests ${GTEST_LIB_DIR}/libgtest.a)
target_link_libraries(QueueTests ${GTEST_LIB_DIR}/libgtest_main.a)

enable_testing()

add_test(NAME    QueueTests 
         COMMAND QueueTests)

root CMakeLists .txt:

cmake_minimum_required(VERSION 3.10)
project(Tests)

# Set language standards
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD 11)

# Add lib dir and go to /lib/CMakeLists.txt
add_subdirectory(lib)

# Add tst dir and go to /tst/CMakeLists.txt
add_subdirectory(tst)

Однако на последнем этапе компиляции (связывание) у меня есть неопределенная ошибка символов:

Undefined symbols for architecture x86_64:
  "init(Queue_T*, int)", referenced from:
      Queue_Tests_Values_after_init_Test::TestBody() in constructor_tests.cpp.o
ld: symbol(s) not found for architecture x86_64

Исходный код выглядит следующим образом:

src / queue.h:

#ifndef QUEUE_H
#define QUEUE_H

//==========================================================//
// INCLUDES SECTION START                                   //
//==========================================================//
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
//==========================================================//
// INCLUDES SECTION END                                     //
//==========================================================//

//==========================================================//
// TYPES SECTION START                                      //
//==========================================================//
typedef uint8_t Check_Val;
typedef signed int Position;
typedef const int* Element;

#define E_NOT_OK  ((Check_Val) 0u)
#define E_OK      ((Check_Val) 1u)

#define EMPTY     ((bool) 0u)
#define NOT_EMPTY ((bool) 1u)

#define INIT_FRONT ((Position) 0)
#define INIT_BACK ((Position) 0)
#define INVALID_FRONT ((Position) -1)
#define INVALID_BACK ((Position) -1)

#define INVALID_SIZE ((signed int) -1)

typedef struct {
    int* data;
    Position front;
    Position back;
    int size;
} Queue_T;
//==========================================================//
// TYPES SECTION END                                        //
//==========================================================//

//==========================================================//
// FUNCTION PROTOTYPES SECTION START                        //
//==========================================================//
Check_Val init(Queue_T* queue, const int size);
Check_Val deinit(Queue_T* queue);
Check_Val push(Queue_T* queue, const int* val);
Check_Val pop(Queue_T* queue);
Element front(const Queue_T* queue);
Element back(const Queue_T* queue);
bool empty(const Queue_T* queue);
//==========================================================//
// FUNCTION PROTOTYPES SECTION END                          //
//==========================================================//

#endif

src / queue. c:

#include <stdlib.h>

#include "queue.h"

//==========================================================//

Check_Val init(Queue_T* queue, const int size) {
    queue->data = (int*)malloc(sizeof(int) * size);

    if(queue->data == NULL) {
        puts("Malloc failed in init\n");
        return E_NOT_OK;
    }

    queue->front = INIT_FRONT;
    queue->back = INIT_BACK;
    queue->size = size;

    return E_OK;
}

Проверка также очень проста, поэтому она не является ошибкой. tst / constructor_tests. cpp:

#include "gtest/gtest.h"

#include "queue.h"

TEST(Queue_Constructor_Tests, structAfterInit) {
    const size_t WANTED_SIZE = 10u;
    Check_Val init_retVal = E_NOT_OK;

    Queue_T queue;
    init_retVal = init(&queue, WANTED_SIZE);

    EXPECT_TRUE(queue.data != NULL);
    EXPECT_EQ(queue.front, INIT_FRONT);
    EXPECT_EQ(queue.back, INIT_BACK);
    EXPECT_EQ(queue.size, WANTED_SIZE);
    EXPECT_EQ(init_retVal, E_OK);
}

Видимо, компилятор видит объявления функции, но не может связать ее реализацию. Думал, что добавление sr c решит проблему:

set(TESTS main.cpp
          constructor_tests.cpp
          destructor_tests.cpp
          ${PROJECT_SOURCE_DIR}/src/queue.c)

, но это не так. Любая помощь, как правильно связать это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...