qmakeからcmakeへの移行(挫折)
Apple SiliconでQt6 の続きです。
cmake への移行
前回までで一応qmakeでビルドも通って動いているのですが、Qt6 は cmake をデフォルトに持って行きたいようなので cmake への移行を試みます。
結論から言うと、うまく行っていません。
参考: Building a QML application | Build with CMake 6.3.0
とりあえずできたもの
なんか、target_link_libraries のところのコードハイライトが変ですが。
cmake_minimum_required(VERSION 3.16)
project(ComicsViewer LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 COMPONENTS Quick Widgets LinguistTools REQUIRED)
find_package(QuaZip-Qt6)
qt_standard_project_setup()
set(CMAKE_AUTORCC ON)
if(APPLE)
set(MACOSX_BUNDLE_ICON_FILE ComicsViewer.icns)
set(app_icon "${CMAKE_CURRENT_SOURCE_DIR}/ComicsViewer.icns")
set_source_files_properties(${app_icon} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
elseif(MINGW)
set(app_icon "${CMAKE_CURRENT_SOURCE_DIR}/ComicsViewer.rc")
endif()
add_executable(ComicsViewer
main.cpp
comicmodel.cpp
pageitem.cpp
qml.qrc
${app_icon}
)
qt_add_translations(ComicsViewer
TS_FILES i18n/ComicsViewer_ja.ts)
target_link_libraries(ComicsViewer PRIVATE Qt6::Widgets Qt6::Quick QuaZip::QuaZip)
set_target_properties(ComicsViewer PROPERTIES
WIN32_EXECUTABLE ON
MACOSX_BUNDLE ON
)
悩んだところとか
- ドキュメントのQMLアプリでは Quick と Gui を Qt の COMPONENT として find_packageしろと書いてあるのですが、それだと QApplicationが使えないので Gui の代わりに Widgets を使います。
- qt_add_translations をただ書くと、そんなの知らないって言われるので、LinguistTools も find_package します。
- qt_add_translations を使わずに、add_executable に Qt5 から使っている i18n.qrc を書いても動きます。
- qml.qrc も、add_executable に書く代わりに qt_add_qml_module を使うことができる(この場合linterとかかけてくれるらしい)のですが、URI が空にできないのでソースを修正する必要があります。なので、今回は qrc ファイルをそのまま使うことにしました。
- deploy とかも cmakeで対応できるようですが、面倒なので今回はそこまでやっていません。
- Macでしか動作確認していません。
駄目なところ
翻訳リソースの ComicsViewer_ja.qm が読み込めません。
読んでいるところ
QTranslator myappTranslator;
if (myappTranslator.load(":/i18n/ComicsViewer_" + QLocale::system().name())) {
app.installTranslator(&myappTranslator);
} else {
qDebug() << "can't load translator for" << QLocale::system().name();
}
ここで、QLocale::system().name()
が ja_JP
を返してくれることを期待しているのですが、cmakeでビルドすると何故か en_JP
になります。qmake でビルドしたときは正しく ja_JP
が返ります。
また、直接 myappTranslator.load(":/i18n/ComicsViewer_ja")
とか書くと読むことができます。
qmake したときのビルドコマンドラインと cmake したときのものを比較したり一部入れ換えたりしたのですが、どうしても解決できませんでした。
ちょっとお手上げなのでcmake対応はここで止まっている状態です。
ここまでの内容は引き続き github のqt6ブランチに入っています。
追記
今どきはi18nの作法が変わっているのかも知れないと思って、公式ドキュメントを確認してみました。
すると、実装例が以下のようになっています。
QTranslator myappTranslator;
if (myappTranslator.load(QLocale::system(), u"myapp"_qs, u"_"_qs, u":/i18n"_qs))
app.installTranslator(&myappTranslator);
これに合わせて、上のリソースのロード部分を以下のように変えてみました。
if (myappTranslator.load(QLocale::system(), "ComicsViewer", "_", ":/i18n")) {
app.installTranslator(&myappTranslator);
} else {
qDebug() << "can't load translator for" << QLocale::system().name();
}
ちなみに、ドキュメントでは文字列リテラルをQStringにするのに u"myapp"_qs
のように書いていますが、普通に文字列リテラルを書いても暗黙で変換してくれるようです。(ASCIIの範囲外の文字とかあると違うのかも。面倒なので未確認)
これで、無事に日本語リソースを読んでくれました。
これは、文字列として ComicsViewer_ja
を渡すのではなく QLocale を渡すことで、en_JP の JP の部分から適当に補完してくれるんだと思います。
その証拠に、日本語のリソースは読めるようになりましたが、ファイルダイアログを開くと qmake の方は日本語UIなのに、cmake の方は英語UIで表示されます。
ん〜、謎は深い。
追記その2
試しに、QtCreator でコンソールアプリを新規作成して実行してみたところ、普通に ja_JP と表示されました。
#include <QCoreApplication>
#include <QLocale>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << QLocale::system().name();
return 0;
}
cmake_minimum_required(VERSION 3.14)
project(localetest2 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core)
add_executable(localetest2
main.cpp
)
target_link_libraries(localetest2 Qt${QT_VERSION_MAJOR}::Core)
もう何もわからない・・・。
追記その3
この後、QtCreatorが作った CMakeLists.txt を少しずつ自分のものに似せていって、何が悪いのかを調べる作業に。
いろいろ試していって、最終的に以下があるとまずいことがわかりました。
set_target_properties(ComicsViewer PROPERTIES
MACOSX_BUNDLE ON
)
これがあると、ComicsViewer.app/Contents/Info.plist が作られるのですが、中に以下の記述があります。
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
qmakeで作った方には CFBundleDevelopmentRegion
はありません。
この2行を消してあげると、QLocale::system() は ja_JP になりました。
しかし、QMLから開くファイルダイアログは英語のまま・・・。
試しに MACOSX_BUNDLE を消して実行ファイルを作っても、ファイルダイアログは英語のままでした。
奥が深い。
Discussion