Qt5 +C++11+CMakeで、次のようなエラーになることがあります。ヘッダファイルの場所を変えるだけでエラーになったりならなかったりします。
text
1CMakeFiles/project_01.dir/mainwindow.cpp.o: 関数 `MainWindow::MainWindow(QWidget*)' 内: 2/path/to/project_01/mainwindow.cpp:6: `vtable for MainWindow' に対する定義されていない参照です 3/path/to/project_01/mainwindow.cpp:6: `vtable for MainWindow' に対する定義されていない参照です 4CMakeFiles/project_01.dir/mainwindow.cpp.o: 関数 `MainWindow::~MainWindow()' 内: 5/path/to/project_01/mainwindow.cpp:11: `vtable for MainWindow' に対する定義されていない参照です 6/path/to/project_01/mainwindow.cpp:11: `vtable for MainWindow' に対する定義されていない参照です
ソースファイル(.cpp)とヘッダファイル(.h)の場所は別にせざるを得ない前提だとして、どうすれば先のエラーにならないよう回避することができるのでしょうか?
ヒント等なにか思いつくことがある方、お助けください。
おそらくQt5とCMakeの組み合わせで必要な何かおまじないが抜けているんだと思うのですが、それが何かわかりません。
以降はエラーが発生するサンプル(と発生しないサンプル)です。
ディレクトリ構造
エラーにならないケース(ソースファイルとヘッダファイルが同じディレクトリ)
mainwindow.hとmainwindow.cppが同じ場所にある場合、エラーになりません。もちろん、ビルドした結果は期待通り実行できます。
text
1|--project_01 2| |--CMakeLists.txt 3| |--main.cpp 4| |--mainwindow.cpp 5| |--mainwindow.ui 6| |--mainwindow.h
エラーになるケース(ソースファイルとヘッダファイルが別のディレクトリ)
mainwindow.*がエラーにならないケースと全く同じであっても、mainwindow.cppと異なる場所にmainwindow.hがあるとエラー(vtable for MainWindow' に対する定義されていない参照です
)になります。
text
1|--include 2| |--mainwindow.h 3|--project_01 4| |--CMakeLists.txt(以降に内容を示します) 5| |--main.cpp 6| |--mainwindow.cpp 7| |--mainwindow.ui
ファイル
project_01/CMakeLists.txt(エラーになるケース)
cmake
1 2# 複数プロジェクトの一部なのでprojectは別の場所で定義しています。 3set(EXAMPLE_NAME project_01) 4 5set(CMAKE_CXX_STANDARD 11) 6 7file(GLOB SOURCES *.cpp) 8file(GLOB HEADERS *.h) 9set(UI_SOURCES mainwindow.ui) 10 11set(CMAKE_INCLUDE_CURRENT_DIR ON) 12set(CMAKE_AUTOMOC ON) 13 14qt5_wrap_ui(UI_HEADERS ${UI_SOURCES}) 15 16add_executable(${EXAMPLE_NAME} 17 ${SOURCES} 18 ${HEADERS} 19 ${UI_HEADERS}) 20 21target_include_directories(${EXAMPLE_NAME} PRIVATE 22 # 23 # ソースファイルと別の場所にヘッダファイルがあるとエラーになる。 24 # project_01/mainwindow.cpp:6: `vtable for MainWindow' に対する定義されていない参照です 25 # 26 ../include 27 28 ${CMAKE_CURRENT_SOURCE_DIR} 29 ${CMAKE_CURRENT_BINARY_DIR} 30 ) 31 32target_link_libraries(${EXAMPLE_NAME} PRIVATE 33 Qt5::Widgets 34 ) 35
mainwindow.h
c++
1#ifndef MAINWINDOW_H 2#define MAINWINDOW_H 3 4#include <QMainWindow> 5 6namespace Ui { 7class MainWindow; 8} 9 10class MainWindow : public QMainWindow 11{ 12 Q_OBJECT 13 14public: 15 explicit MainWindow(QWidget *parent = 0); 16 ~MainWindow(); 17 18private: 19 Ui::MainWindow *ui; 20}; 21 22#endif // MAINWINDOW_H
mainwindow.cpp
c++
1#include "mainwindow.h" 2#include "ui_mainwindow.h" 3 4MainWindow::MainWindow(QWidget *parent) : 5 QMainWindow(parent), 6 ui(new Ui::MainWindow) 7{ 8 ui->setupUi(this); 9} 10 11MainWindow::~MainWindow() 12{ 13 delete ui; 14}
開発環境
- Ubuntu 18.04
- GCC 4.8.5
- cmake 3.10.2
- Qt 5.9.5
あなたの回答
tips
プレビュー