我开始学习 C++,CMake 对我来说是一个更大的困难。 我已经编写了一些代码来帮助我开始,并且还想从一开始就编写测试。 除了每次运行测试时我都会得到未定义的符号。
我已经在 test.cp 中包含#include“ConfigStore.h”并且该文件似乎已被识别
编译时出错:
[build] ld: Undefined symbols:
[build] ConfigStore::addValue(std::__1::basic_string<char, std::__1::char_traits<char>
...
[build] clang: error: linker command failed with exit code
这就是我的制作方法:
项目结构
根:
CMakeLists.txt
根/基础设施/ConfigStore:
ConfigStore.h /ConfigStore.cpp ->(包括“../Singleton/Singleton.h”)
CMakeLists.txt
根/基础设施/单例:
Singleton.h / Singleton.cpp
根/测试
CMakeLists.txt 谷歌测试 ConfigStore_test.cpp
为了简洁起见,以下是我如何将 ConfigStore 添加到我的测试项目中。
CMakeLists(测试):
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/googletest/include ${CMAKE_SOURCE_DIR}/Infrastructure/ConfigStore)
link_directories(${BinanceAPI_LIB_OUT}/ConfigStore)
在 CMakeLists.txt 中:
set(LIBRARY_OUTPUT_PATH ${BinanceAPI_LIB_OUT}/${PROJECT_NAME})
set(CONFIG_STORE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
add_library(${PROJECT_NAME} SHARED ConfigStore)```
还有根 CMakeLists.txt :
add_subdirectory(${CMAKE_SOURCE_DIR}/Infrastructure/ConfigStore)
add_subdirectory(test)
add_library(BinanceAPI BinanceAPI.cpp)
target_link_libraries(${PROJECT_NAME} PUBLIC
ConfigStore)```
编辑
以下是 .h 和 .cpp 文件中的内容:
ConfigStore.h
#ifndef CONFIGSTORE
#define CONFIGSTORE
#include "../Singleton/Singleton_H"
#include<map>
#include<fstream>
#include<string>
typedef std::map<std::string,std::string> t_Store;
class ConfigStore final : public Singleton<ConfigStore>
{
private:
t_Store m_StoredConfig;
public:
ConfigStore(token){ }
~ConfigStore() {}
void parseFile(std::ifstream& p_inStream);
void addValue(std::string key,std::string value);
std::string getValue(std::string key);
};
#endif // CONFIGSTORE
ConfigStore.cpp
#include "ConfigStore.h"
void ConfigStore::addValue(std::string key, std::string value){
auto[it,result] = m_StoredConfig.try_emplace(key,value);
if(!result){
//error management
}
}
std::string ConfigStore::getValue(std::string key){
auto pos = m_StoredConfig.find(key);
if(pos == m_StoredConfig.end()){
return "";
} else {
return pos->second;
}
}
单例.h:
#ifndef SINGLETON
#define SINGLETON
template<typename T>
class Singleton
{
public:
static T& instance();
Singleton(const Singleton&) = delete;
Singleton& operator= (const Singleton) = delete;
protected:
struct token {};
Singleton() {};
};
#endif // SINGLETON
单例.cpp
#include "Singleton.h"
#include <memory>
template<typename T>
T& Singleton<T>::instance(){
static const std::unique_ptr<T> instance{new T{}};
return *instance;
}
最后是 ConfigStore_test.cpp:
#include <gtest/gtest.h>
#include "ConfigStore_H"
TEST(ConfigStoreTest, ConstructTest){
auto &config = ConfigStore::instance();
std::string value = "t";
config.addValue("test",value);
EXPECT_EQ(value,config.getValue("test"));
}
我知道这是很多代码,但我真的很难找出问题所在。感谢您的帮助!
有两个问题阻止此设置工作:
I - 未正确命名头文件 :
我所有的头文件都没有'.h'扩展名,我只是在最后添加了_H。这并没有阻止 Intellisense 工作,但 CMake 并不高兴。
这解决了与 ConfigStore 相关的所有未定义符号。
我在 main 中留下了一个未定义的符号。
II - 未正确导入 Gtest:gtest_main :
由于我使用 GTest 来编写单元测试,因此我不必编写 main.相反,GTest 作为处理测试入口点的 gtest_main 方法。
所以代替:
target_link_libraries(
ConfigStore_Test PUBLIC
gtest
ConfigStore
)
我用过这个:
target_link_libraries(
ConfigStore_Test PUBLIC
GTest::gtest_main
ConfigStore
)