Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Integrate Qt4 qm files into binary using cmake and QRC?

I have a Qt4 CMake project and I'd like to integrate the QM files for i18n into the output binary. These are the rules I have so far for generating the TS and QM files:

set(myapp_TRANSLATIONS
    i18n/myapp_de.ts
)

set(FILES_TO_TRANSLATE
    ${myapp_SRCS}
    ${myapp_MOC_HDRS}
)

QT4_CREATE_TRANSLATION(QM_FILES ${FILES_TO_TRANSLATE} ${myapp_TRANSLATIONS})
QT4_ADD_TRANSLATION(QM ${myapp_TRANSLATIONS})

I tried the following to add the QM files to the executable:

add_executable(myapp ${myapp_SRCS} ${myapp_MOC_SRCS} ${myapp_RCC_SRCS} ${QM})

This is the initialization from main.cpp:

QTranslator qtTranslator;
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
app.installTranslator(&qtTranslator);

QTranslator appTranslator;
appTranslator.load("myapp_" + QLocale::system().name());
app.installTranslator(&appTranslator);

However, strings mypp shows that the translations are not going into the binary.

Update: I added each qm file to a i18n/translations.qrc:

<!DOCTYPE RCC><RCC version="1.0">
  <qresource prefix="/resources">
    <file>myapp_de.qm</file>
    <file>  ...   .qm</file>
  </qresource>
</RCC>

and using

QT4_ADD_RESOURCES(myapp_QM_RCC_SRCS i18n/translations.qrc)

and adding myapp_QM_RCC_SRCS to the executable dependencies.

But this fails during build time thanks to the fact that CMake does a shadow build (building outside the source dir) but parses the QRC files for dependencies expecting the referenced files relative to the QRC file (nice feature but there's no make rule how to build the QM file at that location). The QM files are in ${CMAKE_CURRENT_BINARY_DIR} (where they belong using shadow building) but expects it in ${CMAKE_CURRENT_SOURCE_DIR} (where non-generated files should be - so both locations would be correct, depending on situation).

like image 233
hurikhan77 Avatar asked Jun 26 '10 19:06

hurikhan77


2 Answers

I have found a very simple way to do it in CMake 3.0 (and, maybe, earlier) without ADD_CUSTOM_COMMAND and other complications.

First, you should create a QRC file with all .qm files listed ( thanks, the_fly_123 ):

<RCC>
  <qresource prefix="/translators">
    <file>myapp_en.qm</file>
  </qresource>
</RCC>

Then you can copy this QRC file into the output directory using configure_file and use standard Qt routines to build and add it:

# Change lang.qrc to the name of QRC file, created on the previous step
set(lang_qrc "lang.qrc")
configure_file(${lang_qrc} ${lang_qrc} COPYONLY)
qt5_add_translation(myapp_QM ${myapp_TRANSLATIONS})
qt5_add_resources(myapp_QM_RC ${CMAKE_CURRENT_BINARY_DIR}/${lang_qrc})

Then include ${myapp_QM_RC} in add_executable along with other sources.
Note: For Qt4 replace all qt5_ prefixes with qt4_

like image 87
Alexander Shishenko Avatar answered Sep 28 '22 10:09

Alexander Shishenko


My solution is to generate ts.qrc XML file with compiled translations from scratch and then complie it with app.

Here is example:

file(GLOB QRC_FILES *.qrc)
file(GLOB TS_FILES ts/*.ts)
...

# Option for updating translations
option(UPDATE_TRANSLATIONS "Update source translation ts/*.ts files (WARNING: make clean will delete the source *.ts files. Danger!)" OFF)
if(UPDATE_TRANSLATIONS)
qt4_create_translation(QM_FILES ${TS_FILES})
endif()
...
# Compiling translations *.ts -> *.qm
qt4_add_translation(QM_FILES ${TS_FILES})
...
# Create translations QRC file - ts.qrc
set(TRANSLATIONS_QRC "${CMAKE_CURRENT_BINARY_DIR}/ts.qrc")
file(WRITE ${TRANSLATIONS_QRC} "<RCC>\n\t<qresource prefix=\"/ts\">")
foreach(QM_FILE ${QM_FILES})
    get_filename_component(QM_FILE_NAME ${QM_FILE} NAME)
    file(APPEND ${TRANSLATIONS_QRC} "\n\t\t<file alias=\"${QM_FILE_NAME}\">${QM_FILE_NAME}</file>")
endforeach()
file(APPEND ${TRANSLATIONS_QRC} "\n\t</qresource>\n</RCC>")
list(APPEND QRC_FILES ${TRANSLATIONS_QRC})
...
# Compiling *.qrc files
qt4_add_resources(QRC_SRCS ${QRC_FILES})
...
# Add compiled resources to executable dependency list
add_executable(${APP_NAME} ... ${QRC_SRCS})

File tree:

/ - source code root
/rc.qrc - contains app icons etc.
/ts/appname_*.ts - application translations
...
/build - build root
/build/appname_*.qm - compiled translations
/build/ts.qrc - translations rescources
/build/Release/qrc_rc.cxx - compiled icon etc. resources
/build/Release/qrc_ts.cxx - compiled translation resources

Files in ts dir initially generated by lupdate tool.

like image 26
DJm00n Avatar answered Sep 28 '22 08:09

DJm00n