CMakeは、Qtで広く使用されているソフトウェアビルドシステム(より正確には、アセンブリ制御ファイルの生成)です。 大規模または複雑なプロジェクトを作成する場合は、qmakeを使用するよりもCMakeを選択する方が適切です。 KDEはかつてCMakeの人気のターニングポイントでしたが、その後Qt 4が「貢献」し、Qt 5ではCMakeのサポートが大幅に改善されました。
Qt 5ライブラリを検索して接続する
Qt 5でCMakeを使用する際の主な変更点の1つは、Qt自体のモジュール性が向上したことです。
Qt 4では、検索は次のとおりでした。
find_package (Qt4 COMPONENTS QTCORE QTGUI)
Qt 5では、使用するすべてのモジュールを個別のコマンドで見つけることができます。
find_package (Qt5Widgets)
find_package (Qt5Declarative)
将来的には、1つのコマンドで特定のモジュールを見つける方法があるかもしれませんが、Qt 5では、この種類の検索は機能しません。
find_package(Qt5 COMPONENTS Widgets Declarative)
Qt 5プロジェクトをビルドする
find_package
が
find_package
に完了
find_package
後、Qt 4ユーザーにはCMake変数を使用する機会が与えられました。コンパイル時に
${QT_INCLUDES}
を追加リンクし、リンク時に
${QT_LIBRARIES}
または
${QT_GUI_LIBRARIES}
を設定します。
${QT_USE_FILE}
を使用して、必要なディレクトリと定義を「半自動的に」含めることもできました。
Qt 5モジュラーシステムでは、変数は次のようになります:
${Qt5Widgets_INCLUDE_DIRS}, ${Qt5Widgets_LIBRARIES}, ${Qt5Declarative_INCLUDE_DIRS}, ${Qt5Declarative_LIBRARIES}
など。
これにより、プロジェクトをQt 4からQt 5に移植する際に非互換性が生じます。幸い、これはすべて簡単に修正できます。
Qt 5でのビルドはQt 4よりも少し複雑です。違いの1つは、Qt 5ではconfigure
-reduce-relocations
オプションがデフォルトで有効になっていることです。 このため、コンパイルは
-Bsymbolic-functions
オプションで開始されました。これは、実行可能モジュールの
-fPIC
時に
-fPIE
フラグが追加されていない場合、または位置独立コードのライブラリを
-fPIC
ときに
-fPIC
追加されていない場合、ポインター比較関数を無効にします。
もちろん、
-no-reduce-relocations
オプションを使用してQtを手動で構成し、この問題を回避できますが、CMakeで回避できる位置独立コードのコンパイラーにフラグを追加すると、新しい問題が発生します。
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
これは、Qt 5で使用可能な各モジュールの変数で、Qtの構成方法に応じて
-fPIE
または空の文字列を追加するように展開されます。 ただし、
-fPIE
フラグは実行可能プログラム専用であり、ライブラリには使用しないでください。
-fPIC
グローバルインストールは、実行可能モジュールを
-fPIC
場合でもエラーを引き起こしませんが、このオプションが最初ではありません。
set(CMAKE_CXX_FLAGS "-fPIC")
mocの自動呼び出しなどのCMakeの新機能と組み合わせると、Qt 5を使用した単純なCMakeビルドシステムは次のようになります。
CMakeLists
cmake_minimum_required(2.8.7) project(hello-world) # Tell CMake to run moc when necessary: set(CMAKE_AUTOMOC ON) # As moc files are generated in the binary dir, tell CMake # to always look for includes there: set(CMAKE_INCLUDE_CURRENT_DIR ON) # Widgets finds its own dependencies (QtGui and QtCore). find_package(Qt5Widgets REQUIRED) # The Qt5Widgets_INCLUDES also includes the include directories for # dependencies QtCore and QtGui include_directories(${Qt5Widgets_INCLUDES}) # We need add -DQT_WIDGETS_LIB when using QtWidgets in Qt 5. add_definitions(${Qt5Widgets_DEFINITIONS}) # Executables fail to build with Qt 5 in the default configuration # without -fPIE. We add that here. set(CMAKE_CXX_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") add_executable(hello_world main.cpp mainwindow.cpp) # The Qt5Widgets_LIBRARIES variable also includes QtGui and QtCore target_link_libraries(hello_world ${Qt5Widgets_LIBRARIES})
CMakeのより現代的な使用に向けて
CMake 2.8.8以降、次のように以前のバージョンを少し改善できます。
CMakeLists
cmake_minimum_required(2.8.8) project(hello-world) # Tell CMake to run moc when necessary: set(CMAKE_AUTOMOC ON) # As moc files are generated in the binary dir, tell CMake # to always look for includes there: set(CMAKE_INCLUDE_CURRENT_DIR ON) # Widgets finds its own dependencies. find_package(Qt5Widgets REQUIRED) add_executable(hello_world main.cpp mainwindow.cpp) qt5_use_modules(hello_world Widgets)
qt5_use_modules
CMake
qt5_use_modules
は、Qtを使用するために必要なインストール全体をカプセル化します。 簡潔にするために、複数の引数を一度に使用できます。次に例を示します。
qt5_use_modules(hello_world Widgets Declarative)
qmakeの場合、これは次と同等です。
TARGET = hello_world
QT += widgets declarative
すべてのプロパティは、CMakeListsのスコープ内ではなく、使用される特定のターゲット関数のスコープ内にあります。 たとえば、次のスニペットでは:
CMakeList
add_executable(hello_world main.cpp mainwindow.cpp) add_library(hello_library lib.cpp) add_executable(hello_coretest test.cpp) find_package(Qt5Widgets) qt5_use_package(hello_world Widgets) qt5_use_package(hello_library Core) qt5_use_package(hello_coretest Test)
なぜなら すべてのパラメーターは、それらが機能するターゲット(実行可能モジュールまたはライブラリ)のスコープ内にあります。hello_libraryライブラリの構築時に
-fPIE
使用されず、
-fPIE
構築時に
-DQT_GUI_LIB
使用されません。
これは、CMakeでビルドシステムを記述するはるかに合理化された方法です。
実装の詳細
CMakeを使用する多くの開発者が使い慣れているCMakeの機能の1つは、Findファイルです。 アイデアは、プロジェクトの依存関係ごとに検索ファイルを作成するか、既存の検索ファイルを使用することです。 CMake自体は、多数の検索ファイルを提供します。
CMakeが提供するFindファイルの1つは
FindQt4.cmake
ファイルです。 このファイルは、システムでQtを見つける責任を負います。そのため、次のように呼び出すことができます。
find_package(Qt4)
このFindファイルは、変数
${QT_INCLUDES}
および
${QT_QTGUI_LIBRARIES}
。 このファイルの欠点の1つは、古くなる可能性があることです。 たとえば、2009年12月にQt 4.6がリリースされたとき、新しいQtMultimediaモジュールが含まれていました。 2010年6月にリリースされたCMake 2.8.2まで、このモジュールのサポートはありませんでした。
Qt 5の検索は少し異なります。 Findファイルを使用して依存関係を見つけることができることに加えて、CMakeはライブラリとヘッダーファイルを見つけるための依存関係を提供するファイルを読み取ることもできます。 このようなファイルは構成ファイルと呼ばれ、通常CMake自体によって生成されます。
Qt 5ビルドもこれらのCMake構成ファイルを生成しますが、CMakeに依存することはありません。
これの主な利点は、CMakeで使用できるQt関数(およびモジュール)が、使用されるCMakeのバージョンに依存しないことです。 すべてのQt EssentialsおよびQt Addonsモジュールは独自のCMake構成ファイルを作成し、モジュールによって提供される機能はCMakeマクロおよび変数を介してすぐに利用可能になります。
もとの記事: www.kdab.com/using-cmake-with-qt-5