c++ - VS2013 的 Qt4 到 Qt5 迁移链接器警告(和错误)

标签 c++ qt qt4 cmake qt5

我有一个项目,最初是使用 Qt4 开始开发的,现在正在努力迁移到 Qt5。经过几个小时重新编写一些代码并删除新弃用的调用后,我能够编译该项目,但现在我在链接它时遇到了问题。

我正在使用 CMake 生成项目文件。我开始迁移,首先修改“解决方案”CMake 文件并替换:

#############################################
# find QT
FIND_PACKAGE(Qt4 REQUIRED)

# configure QT modules
SET(QT_USER_QTCORE TRUE)
SET(QT_USE_QTMAIN TRUE)
SET(QT_USE_QTWEBKIT TRUE)
SET(QT_USE_QTNETWORK TRUE)
SET(QT_USE_QTSQL TRUE)

SET(QT_USE_QTXML TRUE)
SET(QT_USE_QTUITOOLS TRUE)

# include QT requirements
INCLUDE(${QT_USE_FILE})
ADD_DEFINITIONS(${QT_DEFINITIONS})
#############################################

与(需要清理)

#############################################
# find QT
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)

FIND_PACKAGE(Qt5Concurrent REQUIRED)
FIND_PACKAGE(Qt5Core REQUIRED)
FIND_PACKAGE(Qt5Network REQUIRED)
FIND_PACKAGE(Qt5Sql REQUIRED)
FIND_PACKAGE(Qt5WebKit REQUIRED)
FIND_PACKAGE(Qt5WebKitWidgets REQUIRED)
FIND_PACKAGE(Qt5Widgets REQUIRED)
FIND_PACKAGE(Qt5Xml REQUIRED)

INCLUDE_DIRECTORIES(
    ${Qt5Concurrent_INCLUDE_DIRS}
    ${QT5_FOLDER}
    "C:/Qt/Qt5.0.2/5.0.2/msvc2012_64/include"
)

ADD_DEFINITIONS(${QT_DEFINITIONS})
#############################################

此后,我注释掉了对 ADD_SUBDIRECTORY() 的所有调用,并开始一次将它们添加回来。我的项目使用Log4Qt由于它不依赖于其他子目录,因此这是我开始研究的第一个子项目。

在 Log4Qt 的 CMakeLists.txt 文件中,我只是将 QT4_WRAP_CPP(MOC_SOURCE_FILES ${MOC_HEADERS}) 更改为 QT5_WRAP_CPP(MOC_SOURCE_FILES ${MOC_HEADERS}),并使用 MOC_HEADERS 被定义为 Log4Qt 中所有必需的 MOC header 。

当我在 VS2013 中加载它并构建时,它编译得很好,但链接会对每个 moc_* 抛出相同的警告:

>moc_stringmatchfilter.obj : warning LNK4006: "public: static struct QMetaObject const Log4Qt::StringMatchFilter::staticMetaObject" (?staticMetaObject@StringMatchFilter@Log4Qt@@2UQMetaObject@@B) already defined in log4qt_automoc.obj; second definition ignored
>moc_stringmatchfilter.obj : warning LNK4006: "private: static void __cdecl Log4Qt::StringMatchFilter::qt_static_metacall(class QObject *,enum QMetaObject::Call,int,void * *)" (?qt_static_metacall@StringMatchFilter@Log4Qt@@CAXPEAVQObject@@W4Call@QMetaObject@@HPEAPEAX@Z) already defined in log4qt_automoc.obj; second definition ignored
>moc_stringmatchfilter.obj : warning LNK4006: "public: virtual struct QMetaObject const * __cdecl Log4Qt::StringMatchFilter::metaObject(void)const " (?metaObject@StringMatchFilter@Log4Qt@@UEBAPEBUQMetaObject@@XZ) already defined in log4qt_automoc.obj; second definition ignored
>moc_stringmatchfilter.obj : warning LNK4006: "public: virtual void * __cdecl Log4Qt::StringMatchFilter::qt_metacast(char const *)" (?qt_metacast@StringMatchFilter@Log4Qt@@UEAAPEAXPEBD@Z) already defined in log4qt_automoc.obj; second definition ignored
>moc_stringmatchfilter.obj : warning LNK4006: "public: virtual int __cdecl Log4Qt::StringMatchFilter::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@StringMatchFilter@Log4Qt@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z) already defined in log4qt_automoc.obj; second definition ignored
>moc_stringmatchfilter.obj : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library

我继续迁移并继续收到相同的警告。例如,以下是子项目之一的完整 CMakeLists.txt 文件:

PROJECT(Network)

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})

SET (SOURCE_FILES RequestCache.cpp WebClient.cpp )

SET (MOC_HEADERS RequestCache.h WebClient.h )

SET (HEADER_FILES ${MOC_HEADERS} )

SET(DEPENDENCY_LIST log4qt Core )

ADD_LIBRARY(Network STATIC ${SOURCE_FILES} ${HEADER_FILES} ${MOC_SOURCE_FILES} )

QT5_USE_MODULES(Network Network)

以及(一些)警告:

moc_WebClient.obj : warning LNK4006: "public: virtual struct QMetaObject const * __cdecl owl::WebClient::metaObject(void)const " (?metaObject@WebClient@owl@@UEBAPEBUQMetaObject@@XZ) already defined in Network_automoc.obj; second definition ignored
moc_WebClient.obj : warning LNK4006: "public: virtual void * __cdecl owl::WebClient::qt_metacast(char const *)" (?qt_metacast@WebClient@owl@@UEAAPEAXPEBD@Z) already defined in Network_automoc.obj; second definition ignored
moc_WebClient.obj : warning LNK4006: "public: virtual int __cdecl owl::WebClient::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@WebClient@owl@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z) already defined in Network_automoc.obj; second definition ignored
moc_WebClient.obj : warning LNK4006: "private: static void __cdecl owl::WebClient::qt_static_metacall(class QObject *,enum QMetaObject::Call,int,void * *)" (?qt_static_metacall@WebClient@owl@@CAXPEAVQObject@@W4Call@QMetaObject@@HPEAPEAX@Z) already defined in Network_automoc.obj; second definition ignored
moc_WebClient.obj : warning LNK4006: "public: static struct QMetaObject const owl::WebClient::staticMetaObject" (?staticMetaObject@WebClient@owl@@2UQMetaObject@@B) already defined in Network_automoc.obj; second definition ignored
moc_WebClient.obj : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library

继续前进,我继续添加所有相关项目并尝试构建项目的可执行文件。然后我收到以下错误(可执行文件的项目名称为“Owl”)(这是错误的摘录,而不是完整的列表):

error LNK2005: "public: static struct QMetaObject const owl::PostListWebView::staticMetaObject" (?staticMetaObject@PostListWebView@owl@@2UQMetaObject@@B) already defined in moc_PostListView.obj   C:\vbulletin\cmake\deltas\Win64\Deltas\Owl_automoc.obj  Owl
error LNK2005: "private: static void __cdecl owl::PostListWebView::qt_static_metacall(class QObject *,enum QMetaObject::Call,int,void * *)" (?qt_static_metacall@PostListWebView@owl@@CAXPEAVQObject@@W4Call@QMetaObject@@HPEAPEAX@Z) already defined in moc_PostListView.obj   C:\vbulletin\cmake\deltas\Win64\Deltas\Owl_automoc.obj  Owl
error LNK2005: "public: virtual struct QMetaObject const * __cdecl owl::BoardTreeView::metaObject(void)const " (?metaObject@BoardTreeView@owl@@UEBAPEBUQMetaObject@@XZ) already defined in moc_BoardTreeView.obj    C:\vbulletin\cmake\deltas\Win64\Deltas\Owl_automoc.obj  Owl
error LNK2005: "public: virtual void * __cdecl owl::BoardTreeView::qt_metacast(char const *)" (?qt_metacast@BoardTreeView@owl@@UEAAPEAXPEBD@Z) already defined in moc_BoardTreeView.obj C:\vbulletin\cmake\deltas\Win64\Deltas\Owl_automoc.obj  Owl
error LNK2005: "public: virtual int __cdecl owl::BoardTreeView::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@BoardTreeView@owl@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z) already defined in moc_BoardTreeView.obj    C:\vbulletin\cmake\deltas\Win64\Deltas\Owl_automoc.obj  Owl
error LNK2005: "private: static void __cdecl owl::BoardTreeView::qt_static_metacall(class QObject *,enum QMetaObject::Call,int,void * *)" (?qt_static_metacall@BoardTreeView@owl@@CAXPEAVQObject@@W4Call@QMetaObject@@HPEAPEAX@Z) already defined in moc_BoardTreeView.obj  C:\vbulletin\cmake\deltas\Win64\Deltas\Owl_automoc.obj  Owl
error LNK2005: "public: virtual struct QMetaObject const * __cdecl owl::ConfiguringBoardDlg::metaObject(void)const " (?metaObject@ConfiguringBoardDlg@owl@@UEBAPEBUQMetaObject@@XZ) already defined in moc_ConfiguringBoardDlg.obj  C:\vbulletin\cmake\deltas\Win64\Deltas\Owl_automoc.obj  Owl
error LNK2005: "public: virtual void * __cdecl owl::ConfiguringBoardDlg::qt_metacast(char const *)" (?qt_metacast@ConfiguringBoardDlg@owl@@UEAAPEAXPEBD@Z) already defined in moc_ConfiguringBoardDlg.obj   C:\vbulletin\cmake\deltas\Win64\Deltas\Owl_automoc.obj  Owl

我做错了什么?我是否必须在 CMake 文件中修复此问题?我无法看到我如何错误地配置 CMake 或者是否还缺少其他内容?

谢谢!

最佳答案

感觉您没有正确清理项目构建目录。另外,如果您的 CMake 版本足够高,您可以尝试使用 CMAKE_AUTOMOC。更多详情here .

关于c++ - VS2013 的 Qt4 到 Qt5 迁移链接器警告(和错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18429957/

相关文章:

c++ - QOpenGLWidget可以与第三方OpenGL库集成吗?

c++ - 64 位系统上的 32 位 Com 服务器

c++ - QProgressBar随着函数的进展而更新

c++ - 在 Qt 中防止触发信号

c++ - Qt读取文本文件

c++ - 使用不完整类型的函数模板实例化

c++ - 如何将 std::array C++11 操作转换为 Boost+VS08?

qt - 模块 "QtQuick"版本 2.5 未安装

c++ - 为什么这个错误是 : reference to ‘statusBar’ is ambiguous. 。 future ?这是一个错误吗?

qt - 检查目录是否为空