gpt4 book ai didi

c++ - Qt 5 cmake 失败,未定义对 hello world 上的 vtable 的引用,其中 inc 和 src 作为子目录

转载 作者:IT老高 更新时间:2023-10-28 23:15:10 25 4
gpt4 key购买 nike

更新 2

在搞砸了一点(以及对生成的 Makefile 进行了一些编辑)之后,看起来正在发生的事情是 moc 没有正确处理 MainWindow.h (包含在 main.cpp MainWindow.cpp 除非它与包含它的源文件位于同一文件夹中。

Moc 在 MainWindow.cpp 上运行,不处理包含,因此看不到 Q_OBJECT 宏,因此继续生成一个空的输出文件。我不确定 moc 是否通常处理包含或是否只是扫描目录,但无论哪种方式,需要 mocing 但位于其他目录中的 header 都不会被处理!

更新

问题似乎与 moc 产生的输出有关。在第一种情况下(编译的那个),hello-world_automoc.cppmoc_MainWindow.cpp被生成。 hello-world_automoc.cpp 看起来像

/* This file is autogenerated, do not edit*/
#include "moc_MainWindow.cpp"

在第二种情况下,生成的 hello-world_automoc.cpp 看起来像

/* This file is autogenerated, do not edit*/
enum some_compilers { need_more_than_nothing };

根本没有moc_MainWindow.cpp。如果我从 cmake 手动调用 moc 而不是在损坏的情况下使用 automoc,我会得到 moc_MainWindow.cpp 但它是空的。

原始状态

首先,不,我没有忘记 set(CMAKE_AUTOMOC ON) .还要注意 MainWindowdestructor is declared and implemented .

当我的目录结构如下所示:

CMakeLists.txt|__ main.cpp|__ MainWindow.cpp|__ MainWindow.h|__ MainWindow.ui

compiling works just fine.

However, when it looks like:

helloworld/|__ CMakeLists.txt|__ src/|   |__ CMakeLists.txt|   |__ main.cpp|   |__ MainWindow.cpp||__ inc/|   |__ MainWindow.h||__ gui/    |__ MainWindow.ui

I get linking errors:

Linking CXX executable hello-world
CMakeFiles/hello-world.dir/MainWindow.cpp.o: In function `MainWindow::MainWindow()':
MainWindow.cpp:(.text+0x3b): undefined reference to `vtable for MainWindow'
MainWindow.cpp:(.text+0x4d): undefined reference to `vtable for MainWindow'
CMakeFiles/hello-world.dir/MainWindow.cpp.o: In function `MainWindow::~MainWindow()':
MainWindow.cpp:(.text+0xaf): undefined reference to `vtable for MainWindow'
MainWindow.cpp:(.text+0xc1): undefined reference to `vtable for MainWindow'
collect2: error: ld returned 1 exit status
make[2]: *** [src/hello-world] Error 1
make[1]: *** [src/CMakeFiles/hello-world.dir/all] Error 2

我真的很想将我的源代码和标题放在适当的子目录中,但我不太确定如何解决这个问题。

这实际上是一个更大的项目中最简单的可识别错误案例,所以我真的不那么热衷于仅仅因为我正在向其中添加 Qt GUI 来展平项目目录。

最佳答案

如前所述,moc 未处理 MainWindow.h在你的例子中。迫使这种情况发生的一种方法是调用qt_wrap_cpp()。直接在它上面(而不是在 MainWindow.cpp 上),然后将生成的文件包含在对 add_executable() 的调用中.

您的顶级 CMakeLists.txt 可能如下所示:

cmake_minimum_required(VERSION 2.8.9)

#set(CMAKE_AUTOMOC ON)

set(CMAKE_PREFIX_PATH "/opt/Qt/5.1.1/gcc_64")
set(CMAKE_INCLUDE_CURRENT_DIR ON)

project(hello-world)

find_package(Qt5Widgets REQUIRED)

set(HW_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc)
set(HW_GUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/gui)

include_directories(${HW_HEADER_DIR})

subdirs(src)

和你的 src 一级像:

qt5_wrap_cpp(hello-world_SRC ${HW_HEADER_DIR}/MainWindow.h)
qt5_wrap_ui(hello-world_UI ${HW_GUI_DIR}/MainWindow.ui)

add_executable(hello-world MainWindow.cpp main.cpp
${hello-world_UI} ${hello-world_SRC})
qt5_use_modules(hello-world Widgets)

附录:

  • 这适用于您启用和未启用 AUTOMOC 的示例。我不确定是否会在将来引起问题。如果你不启用它,你将不得不手动 moc 任何其他东西......虽然它可能都表现得像 MainWindow 在这种情况下你将手动 moc 标题不管。
  • 您不必在顶级 CMakeLists.txt 中设置目录变量,但我发现它比 qt5_wrap_cpp(hello-world_SRC ../inc/MainWindow.h) 更干净。
  • 可能有更好的方法来做到这一点。
  • 对于其他有类似问题的人,到目前为止,这个解决方案在我最初遇到的较大项目中得到了支持。如果它失败,我会相应地更新。

关于c++ - Qt 5 cmake 失败,未定义对 hello world 上的 vtable 的引用,其中 inc 和 src 作为子目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19761767/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com