【问题标题】:Qt4 to Qt5 Migration Linker Warning (and Error) with VS2013VS2013 的 Qt4 到 Qt5 迁移链接器警告(和错误)
【发布时间】:2013-08-25 14:20:42
【问题描述】:

我有一个项目,我最初使用 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})
#############################################

with(这需要清理)

#############################################
# 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 标头。

当我在 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 文件:

项目(网络)

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(网络静态 ${SOURCE_FILES} ${HEADER_FILES} ${MOC_SOURCE_FILES})

QT5_USE_MODULES(网络网络)

以及(部分)警告:

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,或者我还缺少什么?

谢谢!

【问题讨论】:

    标签: c++ qt qt4 cmake qt5


    【解决方案1】:

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

    【讨论】:

    • 我开启了 CMAKE_AUTOMOC,这是我的问题的一部分。我也在我的个人项目文件中进行 MOC。我的猜测是我是“双重 MOC”,因此链接器看到每个 MOC 函数的两个定义。我尝试删除单个 MOC 调用,但这又产生了另一个错误。所以,相反,我关闭了 automoc,这似乎解决了它!所以你的回答引导我朝着正确的方向前进!非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 2012-12-27
    相关资源
    最近更新 更多