我有一个非常简单的代码,关于继承自另一个(请求)的3个类(添加,更新,删除)。
这些类在另一个名为interpreter的实例化中,作为shared_ptrs与make_shared一起实例化。我使用CMake构建整个项目,Interpreter
不属于与Request
相同的共享库。
事情是,当我在MacOS上使用g ++(调用Clang)编译它时,它运行得很好。现在,当我尝试使用g ++(真实的)在Unix上导出它时,它会在链接期间抛出此错误:
src/interpreter/libinterpreter_obj.so : undefined reference to 'request::Remove::Remove(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
src/interpreter/libinterpreter_obj.so : undefined reference to 'request::Add::Add(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
src/interpreter/libinterpreter_obj.so : undefined reference to 'request::Update::Update(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
Clang可以编译和运行而不是g ++的事实与我对Clang的选项有关:-undefined dynamic_lookup
。
所以链接器试图在libinterpreter_obj.so
中找到那些构造函数,它应该在librequest_obj.so
中找到它们
此外,这里有一个简单的方法来重现问题(因为三个类的错误是相同的,所以只包含Remove):
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(ANALYSEUR_STX C CXX)
set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_CXX_COMPILER "g++")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Werror -pedantic -std=c++14")
find_package(Threads REQUIRED) #Technicaly needed for shared_ptr
include_directories(src/)
add_subdirectory(src/request)
add_subdirectory(src/interpreter)
set(ALL
src/main.cc)
add_executable(main ${ALL})
target_link_libraries(main
request_obj
interpreter_obj
${CMAKE_THREAD_LIBS_INIT})
src / interpreter / interpreter.hh:
# pragma once
#include <string>
namespace interpreter
{
class Interpreter
{
public:
Interpreter();
std::string request();
private:
std::string item_;
};
}
src / interpreter / interpreter.cc:
#include <memory>
#include "interpreter/interpreter.hh"
#include "request/request.hh"
#include "request/remove.hh"
namespace interpreter
{
Interpreter::Interpreter() {}
std::string Interpreter::request()
{
std::shared_ptr<request::Request> rq;
rq = std::make_shared<request::Remove>(item_);
return (rq->gen_request());
}
}
src / interpreter / CMakeLists.txt:
set(SRC
interpreter.cc)
add_library(interpreter_obj SHARED ${SRC})
src / request / request.hh:
# pragma once
#include <string>
namespace request
{
class Request
{
public:
Request(std::string item);
virtual ~Request() = default;
virtual std::string gen_request() = 0;
protected:
std::string item_;
};
}
src / request / request.cc:
#include "request.hh"
namespace request
{
Request::Request(std::string item)
: item_(item)
{}
}
src / request / remove.hh:
# pragma once
#include "request/request.hh"
namespace request
{
class Remove: public Request
{
public:
Remove(std::string item);
std::string gen_request() override;
};
}
src / request / remove.cc:
#include "request/remove.hh"
namespace request
{
Remove::Remove(std::string item)
: Request(item)
{}
std::string Remove::gen_request() { return ("remove"); }
}
src / request / CMakeLists.txt:
set(SRC
request.cc
remove.cc)
add_library(request_obj SHARED ${SRC})
src / main.cc:
#include "interpreter/interpreter.hh"
int main()
{
interpreter::Interpreter itp;
}
编译:
mkdir build
cd build/
cmake ..
make
感谢您的帮助!