Qt4のアプリをQt Creatorでビルドするのではなく、CMakeを使ってビルドしてみる。
残念ながら、このために、Windows環境を離れ、Linux環境に変える。

ビルド環境をコマンドラインにできることは、自動ビルドができることでもあり、
それだけで、作られたバイナリの品質は保ちやすくなる。
また、複数のOS(デバイス)対応でも、それらを手順ではなく、
自動で切り分けできれば、よりいっそう使いやすいものになるはずだ。

Qtは、現在、iOSでもAndroidでも、
もちろん、Windows,Mac,Linuxといったデスクトップ環境で動かすことができるようなので、
マルチデバイスの為の共通フレームワークとして、個人的にちょっと注目している。
このあたりは、Adobe AIRにも通じるが、ライトなAIR、ディープなQtという感じに思う。
もちろん、もっとディープにそれぞれ別で・・・
もあり得るが、結局、人的リソースもコストも制限されると、
自ずと共通を持ちたくなってしまうものである。

さて、でもって話はもどって、QtのCMakeのビルド方法です。
今回、Using CMake to Build Qt Projectsを参考にしています。

違うところと言えば、1つ。
uiファイルを使っていること
です。
ちなみに、作成する際につかったのは、「Qt GUI アプリケーション」です。

そこで、プロジェクト名をsampleにしています。
そしてできあがったファイルが、以下のようになります。

一応、ここでそのままビルドして実行してみてください。
まず、失敗することはないと思いますが、
これからCMakeという環境でビルドする際に、そもそもビルドできない環境だったりしても、
CMakeでの問題なのか、もともとの問題なのか切り分けが難しくなります。

では、やっと本題です。
CMakeLists.txt
ファイルを作成します。
(ちなみに、CMakeとはなんぞや?という説明はしません。どこぞで調べてください。)

cmake_minimum_required(VERSION 2.6)

PROJECT(sample)
SET(PROJECT_NAME "sample")
#SET(CMAKE_CXX_FLAGS "-Wall")
SET(CMAKE_BUILD_TYPE Release)

MESSAGE("== build ${PROJECT_NAME} : ${CMAKE_BINARY_DIR}")

FIND_PACKAGE(Qt4 REQUIRED)

SET(sample_SOURCES
        main.cpp
        sample.cpp
)
SET(sample_FORMS
        sample.ui
)
SET(sample_RESOURCES
)
SET(sample_HEADERS
        sample.h
)

INCLUDE(${QT_USE_FILE})

QT4_WRAP_CPP(sample_HEADERS_MOC ${sample_HEADERS})
QT4_WRAP_UI(sample_FORMS_HEADERS ${sample_FORMS})
QT4_ADD_RESOURCES(sample_RESOURCES_RCC ${sample_RESOURCES})

INCLUDE_DIRECTORIES(.)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})

MESSAGE("QT LIBS: ${QT_LIBRARIES} /")

ADD_DEFINITIONS(${QT_DEFINITIONS})

ADD_EXECUTABLE(sample ${sample_SOURCES}
        ${sample_HEADERS_MOC}
        ${sample_FORMS_HEADERS}
        ${sample_RESOURCES_RCC}
)
TARGET_LINK_LIBRARIES(sample ${QT_LIBRARIES})

ここで、肝は、
QT4_WRAP_CPP
QT4_WRAP_UI
QT4_ADD_RESOURCES
の3つです。
これが、

ADD_EXECUTABLE(sample ${sample_SOURCES}
        ${sample_HEADERS_MOC}
        ${sample_FORMS_HEADERS}
        ${sample_RESOURCES_RCC}
)

に対応している部分があり、

上の例ではQtがビルドに必要な
mod_sample.cxx
というソースと、
ui_sample.h
というファイルを作ります。

まずは、これで実行してみます。

mkdir build
cd build
cmake  ..
make

です。

[ 20%] Generating ui_sample.h
[ 40%] Generating moc_sample.cxx
Scanning dependencies of target sample
[ 60%] Building CXX object CMakeFiles/sample.dir/main.cpp.o
[ 80%] Building CXX object CMakeFiles/sample.dir/sample.cpp.o
[100%] Building CXX object CMakeFiles/sample.dir/moc_sample.cxx.o
Linking CXX executable sample
[100%] Built target sample

みたいに表示されます。

ここで、

このui_sample.hというファイルの中身を見ると、

// 一部の抜粋です。
    void setupUi(QMainWindow *sample)
    {
        if (sample->objectName().isEmpty())
            sample->setObjectName(QString::fromUtf8("sample"));
        sample->resize(400, 300);
        menuBar = new QMenuBar(sample);
        menuBar->setObjectName(QString::fromUtf8("menuBar"));
        sample->setMenuBar(menuBar);
        mainToolBar = new QToolBar(sample);
        mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
        sample->addToolBar(mainToolBar);
        centralWidget = new QWidget(sample);
        centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
        sample->setCentralWidget(centralWidget);
        statusBar = new QStatusBar(sample);
        statusBar->setObjectName(QString::fromUtf8("statusBar"));
        sample->setStatusBar(statusBar);

        retranslateUi(sample);

        QMetaObject::connectSlotsByName(sample);
    } // setupUi

とあるように、uiファイルがどのようなコードになるのかを確認することができるので、
あのXMLはどうなって画面になるんだ?という疑問も解けます。
(ちなみに、uic-qt4というコマンドでもこの表示はできます。)

ここまで、何も問題がなければよいのですが、私が遭遇した問題と原因です。

CMakeFiles/sample.dir/sample.cpp.o: In function `sample::~sample()':
sample.cpp:(.text+0xf): undefined reference to `vtable for sample'
sample.cpp:(.text+0x16): undefined reference to `vtable for sample'
CMakeFiles/sample.dir/sample.cpp.o: In function `sample::sample(QWidget*)':
sample.cpp:(.text+0x69): undefined reference to `vtable for sample'
sample.cpp:(.text+0x70): undefined reference to `vtable for sample'
CMakeFiles/sample.dir/sample.cpp.o: In function `sample::~sample()':
sample.cpp:(.text+0xcf): undefined reference to `vtable for sample'

のようなエラーが出る場合。
これは、MOCファイルの作成に失敗しています。
ADD_EXECUTABLE
内に、MOCのファイルの指定がまちがっているか、
QT4_WRAP_CPP
の指定が間違っています。

次に、

error: ui_sample.h: そのようなファイルやディレクトリはありません

これは、
QT4_WRAP_UI
ADD_EXECUTABLE
での記述間違いか、
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
の記述忘れ(間違い)です。

ui_sample.hは、buildしているディレクトリ配下にできてしまうので、
ここをincludeパスに通す必要があります。

とここまで、実行してみて、再度、
Using CMake to Build Qt Projects
を見てみれば、より詳しく内容がわかるのではないかと思います。

お仕事のご依頼・相談を承ります
この記事に関連するお仕事のご依頼やご相談をお待ちしております。 詳しくは、こちら

Leave a Reply

お仕事のご依頼・相談
この記事に関連するお仕事のご依頼やご相談をお待ちしております。 詳しくは、こちら
ソフトウェア&ライブラリ




ライブラリ
airxmail(en)
AIR版メール送受信ライブラリ
airxzip
AIR版ZIP圧縮・解凍ライブラリ
執筆書籍
本、雑誌等

WEB記事:CodeZine
執筆記事はこちら
カレンダー
2012年6月
« 5月   7月 »
 123
45678910
11121314151617
18192021222324
252627282930  

カスタム検索
RSS
Add to Google < !–adsense–>
アーカイブ
カテゴリ
にほんブログ村 IT技術ブログへ