问题
在书写日志模块的时候发现,yaml-cpp如果在子类override父类的函数中使用就会在编译阶段出现问题。
环境:mac os13。
cmake 3.5
Undefined symbols for architecture arm64:
"YAML::InvalidNode::~InvalidNode()", referenced from:
YAML::Node::EnsureNodeExists() const in logger.cpp.o
YAML::Node::Scalar() const in logger.cpp.o
YAML::Node::Type() const in logger.cpp.o
"YAML::BadSubscript::~BadSubscript()", referenced from:
YAML::detail::node& YAML::detail::node_data::get<char [5]>(char const (&) [5], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
YAML::detail::node& YAML::detail::node_data::get<char [6]>(char const (&) [6], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
YAML::detail::node& YAML::detail::node_data::get<char [10]>(char const (&) [10], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
"YAML::detail::memory_holder::merge(YAML::detail::memory_holder&)", referenced from:
YAML::detail::node& YAML::detail::node_data::convert_to_node<char [5]>(char const (&) [5], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
YAML::detail::node& YAML::detail::node_data::convert_to_node<char [6]>(char const (&) [6], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
YAML::detail::node& YAML::detail::node_data::convert_to_node<char [10]>(char const (&) [10], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
"YAML::detail::memory::create_node()", referenced from:
YAML::detail::memory_holder::create_node() in logger.cpp.o
"YAML::detail::node_data::set_scalar(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
YAML::detail::node_ref::set_scalar(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in logger.cpp.o
"YAML::detail::node_data::empty_scalar()", referenced from:
YAML::Node::Scalar() const in logger.cpp.o
"YAML::detail::node_data::mark_defined()", referenced from:
YAML::detail::node_ref::mark_defined() in logger.cpp.o
"YAML::detail::node_data::convert_to_map(std::__1::shared_ptr<YAML::detail::memory_holder> const&)", referenced from:
YAML::detail::node& YAML::detail::node_data::get<char [5]>(char const (&) [5], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
YAML::detail::node& YAML::detail::node_data::get<char [6]>(char const (&) [6], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
YAML::detail::node& YAML::detail::node_data::get<char [10]>(char const (&) [10], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
"YAML::detail::node_data::insert_map_pair(YAML::detail::node&, YAML::detail::node&)", referenced from:
YAML::detail::node& YAML::detail::node_data::get<char [5]>(char const (&) [5], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
YAML::detail::node& YAML::detail::node_data::get<char [6]>(char const (&) [6], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
YAML::detail::node& YAML::detail::node_data::get<char [10]>(char const (&) [10], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
"YAML::detail::node_data::set_null()", referenced from:
YAML::detail::node_ref::set_null() in logger.cpp.o
"typeinfo for YAML::InvalidNode", referenced from:
YAML::Node::EnsureNodeExists() const in logger.cpp.o
YAML::Node::Scalar() const in logger.cpp.o
YAML::Node::Type() const in logger.cpp.o
"typeinfo for YAML::BadSubscript", referenced from:
YAML::detail::node& YAML::detail::node_data::get<char [5]>(char const (&) [5], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
YAML::detail::node& YAML::detail::node_data::get<char [6]>(char const (&) [6], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
YAML::detail::node& YAML::detail::node_data::get<char [10]>(char const (&) [10], std::__1::shared_ptr<YAML::detail::memory_holder>) in logger.cpp.o
"vtable for YAML::InvalidNode", referenced from:
YAML::InvalidNode::InvalidNode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in logger.cpp.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
"vtable for YAML::BadSubscript", referenced from:
YAML::BadSubscript::BadSubscript<char [5]>(YAML::Mark const&, char const (&) [5]) in logger.cpp.o
YAML::BadSubscript::BadSubscript<char [6]>(YAML::Mark const&, char const (&) [6]) in logger.cpp.o
YAML::BadSubscript::BadSubscript<char [10]>(YAML::Mark const&, char const (&) [10]) in logger.cpp.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
"vtable for YAML::RepresentationException", referenced from:
YAML::RepresentationException::RepresentationException(YAML::Mark const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in logger.cpp.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
"vtable for YAML::Exception", referenced from:
YAML::Exception::Exception(YAML::Mark const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in logger.cpp.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [/Users/al/Desktop/C++/workspace/lib/libsylar.dylib] Error 1
这个问题就是第三方库找不到。
相关函数源代码
class Appender{
public:
using ptr = std::shared_ptr<Appender>;
virtual ~Appender(){}
virtual std::string toYamlString(){return "";}
// 当然这是记录
virtual void log(std::shared_ptr<Logger>, LoggerEvent::ptr, LogLevel::Level){};
void setFormatter(std::shared_ptr<Formatter> formatter_){formatter = formatter_;}
std::shared_ptr<Formatter> getFormatter()const{return formatter;}
void setLevel(LogLevel::Level level){m_level = level;}
LogLevel::Level getLevel()const{return m_level;}
// 保护访问权限的私有变量
protected:
// 输出地有什么需要有自己的级别
// 这里是统一输出地的格式
LogLevel::Level m_level = LogLevel::DEBUG;
std::shared_ptr<Formatter> formatter;
};
class stdOutAppender: public Appender{
public:
// 需要什么,需要现场记录
void log(Logger::ptr, LoggerEvent::ptr, LogLevel::Level)override;
std::string toYamlString()override{
YAML::Node node;
// node["type"] = "stdOutAppender";
// YAML::Emitter emitter;
// emitter << node;
std::stringstream ss;
// ss<<node;
return ss.str();
}
private:
// 也是,何必进行其记录呢直接实现啊
};
class fileAppender: public Appender{
public:
std::string toYamlString()override{
YAML::Node node;
// std::unordered_map<std::string, std::string> maps;
// node["type"] = "fileAppender";
// node["file"] = getfilePath();
// node["level"] = LogLevel::ToString(m_level);
// node["formatter"] = formatter->getPattern();
// for(auto it:maps){
// // node[it.first] = it.second;
// }
std::stringstream ss;
// ss<<node;
return ss.str();
}
fileAppender(const std::string & file_):filePath(file_){
// 寻找最后一个/然后进行分割
// 这里的C++17的文件操作属实棒。
try
{
int pos;
for(int i=0;i<filePath.size();i++){
if(filePath[i] =='/') pos = i;
}
std::string directory_ = std::filesystem::absolute(filePath.substr(0,pos));
if(!std::filesystem::exists(directory_)){
std::filesystem::create_directory(directory_);
}
file.open(filePath);
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}
}
void log(Logger::ptr, LoggerEvent::ptr, LogLevel::Level) override;
void reopen(){
if(file.is_open()){
file.close();
}
file.open(filePath);
}
std::string getfilePath()const{return filePath;}
private:
std::string filePath;
std::ofstream file;
};
注释部分就是会出现错误的代码。在toYamlString函数内。
解决办法
暂未解决!