私は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 で実装する必要があることは知っていますが、何もテンプレート化していません。テストしたいだけです。
助けていただければ幸いです。