CMake 3.17在更新TS文件时删除Qt翻译



更新:简化问题

使用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中固定。感谢大家为解决这个问题所做的贡献。

最新更新