使用 Cmake 文件在 Visual Studio 中构建 Qt 项目时出现链接错误

Posted

技术标签:

【中文标题】使用 Cmake 文件在 Visual Studio 中构建 Qt 项目时出现链接错误【英文标题】:Linking Error using Cmake file to build Qt project in Visual Studio 【发布时间】:2015-01-21 13:19:49 【问题描述】:

我正在尝试使用 cmake 构建一个 qt 项目。作为一个起点,我首先在 qt creator 中编写了一个简单的代码,其中包含 main.cpp、mainwindow.cpp 和 mainwindow.h。下面是我的 CMakeLists.txt 配置。

cmake_minimum_required(VERSION 2.8.11)
project(testproject)

# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)

# Find the QtWidgets library
find_package(Qt5Widgets)
find_package(Qt5Core)

get_target_property(QtCore_location Qt5::Core LOCATION)

# Tell CMake to create the executable
add_executable(testproject WIN32 main.cpp mainwindow.cpp)

# Use the Widgets module from Qt 5.
target_link_libraries(testproject Qt5::Widgets)

Cmake 确实成功生成了 VS 项目文件。但是,当我尝试在 Visual Studio 中构建它们时,它给了我链接错误。下面列出了一些错误。我无法发布整个错误列表,因为它太长了。

>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __cdecl QWidget::show(void)" (__imp_?show@QWidget@@QEAAXXZ) referenced in function main
2>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl QApplication::QApplication(int &,char * *,int)" (__imp_??0QApplication@@QEAA@AEAHPEAPEADH@Z) referenced in function main
2>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __cdecl QApplication::~QApplication(void)" (__imp_??1QApplication@@UEAA@XZ) referenced in function main
2>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static int __cdecl QApplication::exec(void)" (__imp_?exec@QApplication@@SAHXZ) referenced in function main
2>mainwindow.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl QMetaObject::Connection::~Connection(void)" (__imp_??1Connection@QMetaObject@@QEAA@XZ) referenced in function "public: __cdecl MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z)
2>mainwindow.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl QString::~QString(void)" (__imp_??1QString@@QEAA@XZ) referenced in function "public: __cdecl MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z)
2>testproject_automoc.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual int __cdecl QMainWindow::qt_metacall(enum QMetaObject::Call,int,void * *)" (__imp_?qt_metacall@QMainWindow@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z) referenced in function "public: virtual int __cdecl MainWindow::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@MainWindow@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)
2>testproject_automoc.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static struct QMetaObject const QMainWindow::staticMetaObject" (__imp_?staticMetaObject@QMainWindow@@2UQMetaObject@@B) referenced in function "void __cdecl `dynamic initializer for 'public: static struct QMetaObject const MainWindow::staticMetaObject''(void)" (??__E?staticMetaObject@MainWindow@@2UQMetaObject@@B@@YAXXZ)
2>MSVCRT.lib(crtexew.obj) : error LNK2019: unresolved external symbol WinMain referenced in function __tmainCRTStartup

我正在使用 Qt5.3.1、cmake 3.0.2 和 Visual Studio 2012。

【问题讨论】:

【参考方案1】:

为了解决这个问题,您必须从 add_executable(testproject WIN32 main.cpp mainwindow.cpp).

【讨论】:

【参考方案2】:

可能的原因:

检查CMakeLists.txtadd_executable 命令中的源文件名是否存在拼写错误。源列表中不存在的文件名将产生链接器错误error LNK2019: unresolved external symbol main referenced。 您的入口点函数是什么样的? WinMain 需要 add_executable(testproject WIN32 main.cpp mainwindow.cpp) main 需要 add_executable(testproject main.cpp mainwindow.cpp) 注意:我建议使用int main(int argc, char *argv[]),因为它可以移植到linux,而使用WinMain则不能。

【讨论】:

请阅读[CMake官方文档入口][cmake.org/cmake/help/latest/prop_tgt/WIN32_EXECUTABLE.html].您仍然可以在代码中使用 int main(...) 并拥有 WIN32 属性。【参考方案3】:

我刚刚遇到这个错误,我在Visual Studio中使用x64-Debug配置,但是CMake中的变量CMAKE_PREFIX_PATH的路径>x86 Qt,所以链接器尝试将x86 Qt库链接到x64程序,出现错误。

解决方案是将 Visual Studio 配置和 Qt 路径更正为同一架构。

【讨论】:

除非可以在 CMake 本身中完成,否则我发现此解决方案不是一个好选择(即使它确实有效,我无法确认)。每当运行 CMake 并重新生成项目时,所有这些更改都将丢失。【参考方案4】:

你必须链接到QtCore,你只能链接到Qt5::Widgets。将Qt5::Core 添加到您的链接库。至少对我来说,CMake 文件不包含传递依赖项(因此链接 Qt5::Widgets 是不够的。)

【讨论】:

嗨 Anteru,我把那行改成了target_link_libraries(testproject Qt5::Widgets Qt5::Core),但这并没有解决问题。 您是否手动检查了链接器路径?您应该链接 Qt5::Widgets、Qt5::Gui 和 Qt5::Core。添加 Qt5::Core 后链接错误有什么变化吗? 添加 Qt-Core 后没有任何变化。但是,我没有尝试在 Visual studi 中创建构建文件,而是尝试使用 mingw 编译器来构建项目。所以我相信我应该在 Visual Studio 中手动检查链接器路径 包含传递依赖。 Qt5::Widgets 就够了。

以上是关于使用 Cmake 文件在 Visual Studio 中构建 Qt 项目时出现链接错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 Cmake 文件在 Visual Studio 中构建 Qt 项目时出现链接错误

CMake 和 Visual Studio - 指定解决方案文件目录

如何在没有 CMake 的情况下使用 Visual Studio 2013 设置 Dlib?

从 CMake 创建 Visual Studio 项目,Visual Studio 找不到可执行文件

cmake - 支持 Visual Studio 过滤器

用CMake设置Visual Studio工程中第三方库