2

我一直在尝试使用 cmake 和 gtest(谷歌测试)来适应 c++。

我试图理解为什么这个设置会产生错误

Undefined symbols for architecture x86_64:
"Project1::foo(int&)", referenced from:
    Project1Test_MethodBarDoesAbc_Test::TestBody()      in test_project1.cpp.o
        ld: symbol(s) not found for architecture x86_64

当我运行“make”时。

当我在 .h 文件中实现方法时,一切正常;但是当我只在 .h 文件中声明方法,然后在关联的 .cpp 文件中实现它时,就会发生此错误。

我的测试文件:test_project1.cpp

#include <iostream>
#include "gtest/gtest.h"

#include "project1.h"

// tests outside of the class
TEST(IndependentMethod, ResetsToZero2) {
    int i = 0;
    independentMethod(i);
    EXPECT_EQ(0, i);
}
//...

// The fixture for testing the class
class Project1Test : public ::testing::Test {
protected:
    // You can remove any or all of the following functions if its body
    // is empty.

    Project1Test() {
        // nothing here
    }
};

// Test case must be called the class above
TEST_F(Project1Test, MethodBarDoesAbc) {
    Project1 p;
    int i = 0;
    p.foo(i); // WHY CAN'T Project1::foo(int&) be detected here?!
    EXPECT_EQ(1, i);
}

类定义:project1.h

#ifndef PROJECT1_H_
#define PROJECT1_H_

#include <iostream> // IO access

using namespace std;

class Project1 {

public:
    // why only detected if implemented here?
    // void foo(int &i) {
    //  i = 1;
    // }
    void foo(int &i);

};

void independentMethod(int &i) {
    // From experience, should be implemented in the .h, not the .cpp.
    // Otherwise, test can't find independentMethod, but WHY?
    i = 0;
}

#endif /* PROJECT1_H_ */

Project1类的实现:project1.cpp

#include <iostream>
#include "project1.h"

void Project1::foo(int &i) {
    i = 1;
}

int main() {
    // this works fine if I directly compile project1.cpp and run ./a.out
    cout << "do stuff" << endl;
    int x = 4;
    cout << x << endl;
    independentMethod(x);
    cout << x << endl;
    Project1 p;
    p.foo(x);
    cout << x << endl;
}

我进行测试的过程很典型:

mkdir build
cd build
cmake ..
make

我不知道这是否相关,但这是我项目根目录中的CMakeLists.txt文件:

cmake_minimum_required(VERSION 2.8)

# Make PROJECT_SOURCE_DIR, PROJECT_BINARY_DIR, and PROJECT_NAME available
set(PROJECT_NAME MyProject)
project(${PROJECT_NAME})

set(CMAKE_CXX_FLAGS "-g -Wall")

#set(COMMON_INCLUDES ${PROJECT_SOURCE_DIR}/include) if you want your own include/ directory
# then you can do include_directories(${COMMON_INCLUDES}) in other cmakelists.txt files

################################
# Normal files
################################
add_executable(project1 project1.cpp)

################################
# GTest
################################
# This adds another subdirectory, which has project(gtest)
add_subdirectory(lib/gtest-1.6.0)

enable_testing()

# Include the gtest library
# gtest_SOURCE_DIR is available due to project(gtest) above
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})

################################
# Unit Tests
################################
add_executable(runUnitTests test_project1.cpp)
target_link_libraries(runUnitTests gtest gtest_main)
add_test(NAME runUnitTests COMMAND runUnitTests)

我觉得这个问题是由于我对实现 .cpp 与 .h 有一些误解。我知道模板化函数必须在.h 中实现,但我没有模板化任何东西。我只是想测试一下。

帮助表示赞赏。

4

1 回答 1

2

您需要在 project1.cpp 中使用您自己的代码链接到您的 runUnitTests 可执行文件。

我倾向于从project1.cpp 的内容中创建一个库,并将主函数移动到一个单独的文件中(例如main.cpp)。然后你可以做

add_library(project1_lib project1.cpp project1.h)
add_executable(project1 main.cpp)
target_link_libraries(project1 project1_lib)

add_executable(runUnitTests test_project1.cpp)
target_link_libraries(runUnitTests project1_lib gtest gtest_main)
于 2013-01-04T12:41:28.243 回答