2

私はcmakeとgtest(Googleテスト)で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 関数を別のファイル (たとえば 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 に答える