更新:简化问题
使用CMake 3.16.8或更低版本时,以下工作流程正常工作,但3.17+删除了Qt的TS文件。这个想法取自Craig Scott 的《专业CMake》第7版
要求
cmake 3.17+,Qt 5.9+,忍者
概念
要更新Qt的翻译文件,可以启用UPDATE_TRANSLATIONS
。完成后,禁用它。CMake 3.17+删除更新的TS文件。
调整脚本update_translation.sh
中的路径以自动执行工作流。
复制步骤
git clone https://github.com/Macintron/QtTranslationDemo.git # or create files from below in QtTranslationDemo.
mkdir build # NOT in QtTranslationDemo
cd build
cmake -G Ninja -DCMAKE_PREFIX_PATH=[pathToQtDir/5.15.1/clang_64] ../QtTranslationDemo
ninja
./demo
输出应为:
Demo
de.qm: 85 bytes
Language: 'Deutsch'
greeting: ''
en.qm: 85 bytes
Language: 'English'
greeting: ''
现在问题开始了:
cmake -DUPDATE_TRANSLATIONS=ON ../QtTranslationDemo
ninja demoTranslations
cmake -DUPDATE_TRANSLATIONS=OFF ../QtTranslationDemo
# new strings ("greeting") should haven been added to the ts files, but TS files are deleted instead!
为什么删除TS文件?这是CMake 3.17+中的错误还是我的工作流程中的错误?
生成信息
生成目录不得位于源中。
源文件
CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
project(QtTranslationDemo LANGUAGES CXX)
find_package(Qt5
COMPONENTS
LinguistTools Core
REQUIRED
)
option(UPDATE_TRANSLATIONS "Enable rescanning sources to update .ts files" OFF)
set(_tsFiles en.ts de.ts)
if(UPDATE_TRANSLATIONS)
message("** parse sources for new translations")
qt5_create_translation(_qmFiles
main.cpp
${_tsFiles}
)
else()
message("** update qm files")
qt5_add_translation(_qmFiles
${_tsFiles}
)
endif()
add_custom_target(demoTranslations DEPENDS ${_qmFiles})
add_executable(demo
main.cpp
${_qmFiles}
)
target_link_libraries(demo
PUBLIC
Qt5::Core
)
main.cpp
#include <QTranslator>
#include <QDir>
#include <QStringList>
static const char* language = QT_TRANSLATE_NOOP("@default", "Language");
static const char* greeting = QT_TRANSLATE_NOOP("@default", "greeting"); // not in ts files now!
int main(int argc, char *argv[])
{
qDebug("Demo");
QStringList qms = QDir("./").entryList({"*.qm"});
for (const auto& qm: qms) {
qDebug("%s: %lld bytes", qPrintable(qm), QFileInfo("./" + qm).size());
QTranslator appTranslator;
if (appTranslator.load(qm, "./")) {
qDebug(" Language: '%s'", qPrintable(appTranslator.translate("@default", language)));
qDebug(" greeting: '%s'", qPrintable(appTranslator.translate("@default", greeting)));
} else {
qWarning("Failed to load %s", qPrintable(qm));
}
}
return 0;
}
en.ts
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en" sourcelanguage="en">
<context>
<name>@default</name>
<message>
<source>Language</source>
<translation>English</translation>
</message>
</context>
</TS>
de.ts
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de" sourcelanguage="en">
<context>
<name>@default</name>
<message>
<source>Language</source>
<translation>Deutsch</translation>
</message>
</context>
</TS>
update_translation.sh
#!/bin/sh
set -e
thisdir=$(dirname $0)
qt_root=/usr/local/Trolltech/Qt5.15/5.15.1/clang_64
#cmaketool=/usr/local/Cellar/cmake/3.16.8/bin/cmake
cmaketool=cmake
# easier setup
rm -Rf en.qm de.qm CMakeFiles CMakeCache.txt cmake_install.cmake build.ninja .ninja_* > /dev/null 2>&1
git checkout $thisdir/de.ts $thisdir/en.ts # restore files
$cmaketool --version
$cmaketool -G Ninja -DCMAKE_PREFIX_PATH=$qt_root ../QtTranslationDemo
ninja
./demo
rm -f demo
echo "Starting CMake with DUPDATE_TRANSLATIONS..."
$cmaketool -DUPDATE_TRANSLATIONS=ON $thisdir
echo
echo "Updating translation files..."
ninja demoTranslations
echo
echo "Restore CMake configuration..."
$cmaketool -DUPDATE_TRANSLATIONS=OFF $thisdir
ninja
./demo
exit 0
这是一个通用的CMake问题,由cleandead特性引起。它应该在CMake 3.19.2中固定。感谢大家为解决这个问题所做的贡献。