[C++][Qt]windeployqtをCMakeから実行する。

動機

オープンソース版のQtは基本的にLGPLライセンスであるため、ライセンスの汚染を避けるためには動的リンクが必要になる。この場合、何らかのアプリケーションを作って配布するときは、Qtの関連する共有ライブラリなどをアプリケーションに同梱して配布することが望ましい。

QtはWindowwsとMacに対しては、それぞれwindeployqt、macdeployqtという、必要な共有ライブラリを自動的にコピーしてくれるツールが用意されている。Linuxに関しては残念ながらQtオフィシャルなものはないが、有志の方々がlinuxdeployqtというツールを開発し公開している。
このうちwindeployqtをCMake上で実行してみたい。

本記事はWindowsのみを対象としているが、MacLinuxの場合も似たようなものだろうとは思う。

方法

cmake_minimum_required(VERSION 3.14)

#...諸々のプロジェクトの設定

get_target_property(_qmake_path Qt5::qmake IMPORTED_LOCATION)
get_filename_component(_qt_bin_path ${_qmake_path} DIRECTORY)

find_program(DEPLOYQT NAMES windeployqt HINTS "${_qt_bin_path}")

add_custom_command(
    TARGET ${PROJECT_NAME} POST_BUILD
    COMMAND ${DEPLOYQT} $<TARGET_FILE_DIR:${PROJECT_NAME}>/$<TARGET_FILE_NAME:${PROJECT_NAME}>
        --$<IF:$<CONFIG:Debug>,debug,release> --dir "$<TARGET_FILE_DIR:${PROJECT_NAME}>")
install(CODE "execute_process(COMMAND ${DEPLOYQT} ${CMAKE_INSTALL_PREFIX}/$<TARGET_FILE_NAME:${PROJECT_NAME}>
                              --$<IF:$<CONFIG:Debug>,debug,release> --qmldir ${CMAKE_SOURCE_DIR})")

次のような動作をさせている。

  1. qmakeを探す。
  2. qmakeのディレクトリからwindeployqtを探す。
  3. ビルド後とインストール後にそれぞれ出力された実行ファイルに対してwindeployqtを実行させる。

install(CODE ...)の中でのGenerator Expressionsの使用にはCMake3.14以上が必要であるため、cmake_minimum_required(VERSION 3.14)としている。

閑話

windeployqtを使うと、動作に必須でない大量のdllや実行ファイルまでもがコピーされてしまうのに、肝心のOpenSSLなどはコピーされないという残念極まりない仕様なので、はっきり言って使いにくい。
vcpkgでインストールしたQtを使うと、いちいちwindeployqtなんて面倒なものを使わずとも必要最小限のdllをきっちりコピーしてくれて1助かるのだが、あちらはあちらで膨大なバグを抱え込んでいるので正直まともに使えない。此度、Qt5.15.2とQt WebEngineをvcpkgからインストールしようとしたら、"ファイルパス長すぎ"と文句を言われビルドもできなかった。vcpkgをアップデートしたらQtのビルドでコケた。仕方ないので、vcpkgを無効にしてQtやその他必要なライブラリを独立にインストールした。ホント勘弁してほしい……。


  1. ただしビルド時のみである。インストール時のコピーは自前で行う必要がある。