Isk*_*rak 12 c++ linker qt cmake moc
稍微搞砸了(以及对生成的Makefile的一些编辑),看起来正在发生的是moc没有正确处理MainWindow.h
(包括在内main.cpp
,MainWindow.cpp
除非它与包含它的源文件位于同一文件夹中).
Moc运行MainWindow.cpp
,不处理包含,因此没有看到Q_OBJECT宏,因此继续产生一个空的输出文件.我不确定moc通常是进程包含还是只是扫描目录,但无论哪种方式,需要mocing但在其他目录中的头文件都没有被处理!
问题似乎与moc产生的输出有关.在第一种情况下(编译的那个),hello-world_automoc.cpp
并moc_MainWindow.cpp
生成.hello-world_automoc.cpp
好像
/* This file is autogenerated, do not edit*/
#include "moc_MainWindow.cpp"
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,hello-world_automoc.cpp
产生了一个看起来像的
/* This file is autogenerated, do not edit*/
enum some_compilers { need_more_than_nothing };
Run Code Online (Sandbox Code Playgroud)
并且根本没有moc_MainWindow.cpp
.如果我从cmake手动调用moc而不是在破碎的情况下使用automoc,我确实得到moc_MainWindow.cpp
但它是空的.
首先,不,我没有忘记set(CMAKE_AUTOMOC ON)
.还要注意的是MainWindow
的析构函数声明和实现.
当我的目录结构如下所示:
CMakeLists.txt |__ main.cpp |__ MainWindow.cpp |__ MainWindow.h |__ MainWindow.ui
编译工作得很好.
但是,当它看起来像:
helloworld/ |__ CMakeLists.txt |__ src/ | |__ CMakeLists.txt | |__ main.cpp | |__ MainWindow.cpp | |__ inc/ | |__ MainWindow.h | |__ gui/ |__ MainWindow.ui
我得到链接错误:
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
Run Code Online (Sandbox Code Playgroud)
我真的希望将我的源代码和标题放在适当的子目录中,但我不太确定如何解决这个问题.
这实际上是来自更大项目的错误的最简单的可识别情况,所以我真的不是那么热衷于展平项目目录只是因为我正在添加Qt GUI.
Isk*_*rak 14
如上所述,moc MainWindow.h
在您的示例中不处理.强制执行此操作的一种方法是qt_wrap_cpp()
直接调用它(而不是on 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)
Run Code Online (Sandbox Code Playgroud)
和你的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)
Run Code Online (Sandbox Code Playgroud)
附录:
qt5_wrap_cpp(hello-world_SRC ../inc/MainWindow.h)
小智 7
我遇到了同样的问题并找到了解决方案。正如 Eric Lemanissier在 GitHub 上的一个问题中评论的那样:
这个错误与conan无关:你需要在add_executable中添加你的头文件,否则moc不会解析它们
必须使用add_executable
oradd_library
语句将头文件添加到项目中。如果不这样做,automoc 将不会解析文件。