【发布时间】:2018-07-31 01:29:17
【问题描述】:
我正在将一个项目从 Qmake 移植到 Cmake。它的大多数实用程序现在都可以了,我已经为所有这些实用程序制作了 Cmake 文件。 但是,两个项目因“未定义的 vtable 引用”链接器错误而无法编译:
TaskTestLib/libTaskTestLib.a(remotejobsrunnerconfigurationtest.cpp.o): na função
RemoteJobsRunnerConfigurationTest::RemoteJobsRunnerConfigurationTest()': remotejobsrunnerconfigurationtest.cpp:(.text+0x2293): referência indefinida avtable for RemoteJobsRunnerConfigurationTest' TaskTestLib/libTaskTestLib.a(abstractjobconfigurationtest.cpp.o): na funçãoAbstractJobConfigurationTest::AbstractJobConfigurationTest()': abstractjobconfigurationtest.cpp:(.text+0x2315): referência indefinida avtable for AbstractJobConfigurationTest' collect2:错误:ld 返回 1 个退出状态
所涉及的类是 Qt Test 所期望的测试类。以下是失败项目的简化项目依赖关系:
TaskSingleTest -> 需要TaskTestLib -> 需要QtToolsLib
错误中所述的RemoteJobsRunnerConfigurationTest 是TaskTestLib 的一部分。它继承了 AbstractJobConfigurationTest,它也是 TaskTestLib 的一部分,TaskTestLib 本身继承自 QtToolsLib 的 QtTestSuite。
奇怪的是我有另一个测试项目已经移植到Cmake,编译和链接都很好。以它为例,我注意到这些链接问题只发生在来自 TaskTestLib 的测试类中。其他测试库(有很多)链接很好。 问题似乎在 TaskTestLib 项目文件中,但它几乎与工作文件完全相同。 这是TaskTestLib(失败的lib)Cmake文件:
cmake_minimum_required (VERSION 3.2)
project (TaskTestLib)
file(GLOB SOURCES "../../src/*")
set(INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../src/")
add_library(TaskTestLib ${SOURCES})
set_target_properties(TaskTestLib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${INCLUDE_DIR}")
target_link_libraries (TaskTestLib TaskLib QtToolsLib)
和 ParsersTestLib(工作库)Cmake 文件:
cmake_minimum_required (VERSION 3.2)
project (ParsersTestLib)
file(GLOB SOURCES "../../src/*")
set(INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../src/")
add_library(ParsersTestLib ${SOURCES})
set_target_properties(ParsersTestLib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${INCLUDE_DIR}")
target_link_libraries (ParsersTestLib ParsersLib QtToolsLib)
以下是链接错误中涉及的类:
class RemoteJobsRunnerConfigurationTest : public AbstractJobConfigurationTest
{
Q_OBJECT
public:
RemoteJobsRunnerConfigurationTest() = default;
//RemoteJobsRunnerConfigurationTest();
virtual ~RemoteJobsRunnerConfigurationTest() = default;
private Q_SLOTS:
void testConfigure_ConfFileProperty();
void testConfigure_TimedRunProperty_data();
void testConfigure_TimedRunProperty();
protected:
AbstractJobConfiguration* CreateNewConfiguration() const override;
private:
void TestConfFileProperty(const std::string& propertyValue);
void TestTimedRunProperty(const std::string& propertyValue, const bool expectedValue);
};
class AbstractJobConfigurationTest : public QtTestSuite
{
Q_OBJECT
public:
AbstractJobConfigurationTest();
virtual ~AbstractJobConfigurationTest() = default;
private Q_SLOTS:
void testConfigure_NullConfiguration();
void testConfigure_UnknownProperty();
void testConfigure_UnknownSubObject();
protected:
AbstractJob *TestConfiguration(ConfigurationObject* confObject,
const std::vector<std::string>& expectedErrorMessages);
AbstractJob *TestConfigurationWithoutErrors(ConfigurationObject* confObject);
virtual AbstractJobConfiguration* CreateNewConfiguration() const = 0;
ConfigurationObject* CreateSimpleConfigurationObject(
const std::string& property, const std::string& value);
private:
AbstractJob* RunConfiguration(ConfigurationObject* confObject,
std::vector<std::string> &errorMessages);
void CheckErrorMessages(const std::vector<std::string> &errorMessages,
const std::vector<std::string> &expectedErrorMessages);
std::string BuildUnknownError(const std::string& object,
const std::string& name) const;
};
AbstractJobConfigurationTest::AbstractJobConfigurationTest()
: QtTestSuite("", "")
{
}
AbstractJobConfiguration*RemoteJobsRunnerConfigurationTest::CreateNewConfiguration() const
{
return new RemoteJobsRunnerConfiguration();
}
我不认为发布 QtTestSuite 代码或其项目 Cmake 文件是相关的,因为它们可以很好地编译并与使用它们的其他项目链接。 我只发布了我认为相关的 cpp 文件部分,但如果有要求,我可以发布更多内容(包括其他项目文件等...)。
有人知道为什么这个项目没有链接吗?
编辑
相关问题here的答案没有回答我的问题:
- 我的“Makefile”是最新的,我从 Cmake 重新生成它们,但问题仍然存在。
- 没有未实现的纯虚函数。有人在 AbstractJobConfigurationTest 中提出了纯虚拟 CreateNewConfiguration() 方法,但该类没有在任何地方实例化。实例化的是它的子类,它确实实现了纯虚方法。
另外,请注意,该项目有一个现有的 qmake 项目,并且 qmake 项目正在正确构建和链接该项目,具有相同的源代码。因此,我预计问题出在 Cmake 文件中。
【问题讨论】:
-
如果您不实现非纯虚函数,该错误(缺少 vtable)很常见。是否所有虚函数都已定义并有实现?
-
由于这是一个
Qt项目,我猜这些错误是由于没有链接到moc生成的代码造成的。 -
虽然没有回答具体问题,但我建议避免
file(GLOB SOURCES "../../src/*"),任何删除或添加源文件都不会被拾取。见cmake.org/cmake/help/latest/command/file.html -
类
AbstractJobConfigurationTest具有 纯虚拟 (virtual ... = 0) 方法。你绝对不能实例化这个类(即创建这个类的对象)。
标签: c++ cmake linker-errors