Qt4到Qt5迁移链接器警告(和错误)与VS2013。

时间:2021-11-18 07:26:12

I have a project that I originally started developing using Qt4 and am now working on migrating to Qt5. After a couple hours reworking some code and removing newly deprecated calls, I was able to get the project to compile but now I'm having problems getting it to link.

我有一个项目,我最初是使用Qt4开发的,现在正致力于迁移到Qt5。经过几个小时的重新编写代码和删除新弃用的调用之后,我能够让这个项目进行编译,但是现在我遇到了让它链接起来的问题。

I am using CMake to generate the project files. I started migrating by first modifying the "solutions's" CMake file and replacing:

我正在使用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 (this needs to be cleaned up)

(需要清理)

#############################################
# 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})
#############################################

After this, I commented out all my calls to ADD_SUBDIRECTORY() and started adding them back in one at a time. My project uses Log4Qt and since that has no other dependencies on other subdirectories, it was the first subproject I started working on.

在此之后,我将所有对ADD_SUBDIRECTORY()的调用都注释掉,并开始一次将它们添加回一个。我的项目使用Log4Qt,因为它与其他子目录没有其他依赖关系,这是我开始工作的第一个子项目。

In Log4Qt's CMakeLists.txt file, I simply changed QT4_WRAP_CPP(MOC_SOURCE_FILES ${MOC_HEADERS}) to QT5_WRAP_CPP(MOC_SOURCE_FILES ${MOC_HEADERS}), with MOC_HEADERS being defined as all the necessarily MOC'd headers in Log4Qt.

Log4Qt CMakeLists。txt文件,我简单地将QT4_WRAP_CPP(MOC_SOURCE_FILES ${MOC_HEADERS})更改为QT5_WRAP_CPP(MOC_SOURCE_FILES ${MOC_HEADERS}), MOC_HEADERS被定义为Log4Qt中所有必须的MOC文件头。

When I load this up in VS2013 and build, it compiles fine but linking throws the same warnings for every 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

I continued with my migration and continue to get the same warnings. For example, here is the entire CMakeLists.txt file for one of the subprojects:

我继续迁移,并继续得到相同的警告。例如,这里是整个CMakeLists。一个子项目的txt文件:

PROJECT(Network)

项目(网络)

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})

INCLUDE_DIRECTORIES($ { CMAKE_CURRENT_BINARY_DIR })

SET (SOURCE_FILES RequestCache.cpp WebClient.cpp )

集(SOURCE_FILES RequestCache。cpp WebClient。cpp)

SET (MOC_HEADERS RequestCache.h WebClient.h )

集(MOC_HEADERS RequestCache。h WebClient。h)

SET (HEADER_FILES ${MOC_HEADERS} )

集(HEADER_FILES $ { MOC_HEADERS })

SET(DEPENDENCY_LIST log4qt Core )

集(DEPENDENCY_LIST log4qt核心)

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

ADD_LIBRARY(网络静态${SOURCE_FILES} ${MOC_SOURCE_FILES})

QT5_USE_MODULES(Network Network)

QT5_USE_MODULES(网络网络)

And (some of) the warnings:

以及(一些)警告:

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

Pressing ahead still, I went ahead and added all the relevant projects and attempted to build the project's executable. And then I got the following errors (the executable's project name being 'Owl') (this is an excerpt of the errors, not the full listing):

继续前进,我继续前进,添加了所有相关的项目,并试图构建项目的可执行文件。然后我得到了以下错误(可执行程序的项目名称是“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

What am I doing wrong? Do I have to fix this in my CMake files? I fail to see how I'm configuring CMake incorrectly or is there's something else I'm missing?

我做错了什么?我必须在我的CMake文件中解决这个问题吗?我没有看到我是如何正确配置CMake的,或者我还缺少什么?

Thank you!

谢谢你!

1 个解决方案

#1


3  

It feels like you didn't clean your project build directory properly. Also if your CMake version is high enough you can try using CMAKE_AUTOMOC. More details here.

感觉您没有正确地清理您的项目构建目录。如果您的CMake版本足够高,您可以尝试使用cmake_auto。更多细节在这里。

#1


3  

It feels like you didn't clean your project build directory properly. Also if your CMake version is high enough you can try using CMAKE_AUTOMOC. More details here.

感觉您没有正确地清理您的项目构建目录。如果您的CMake版本足够高,您可以尝试使用cmake_auto。更多细节在这里。