Banana Extension Package with CMake

Documentation •
In this article

The CMake is a utility that allows to build the Extension package.

  • It automatically call the rcc compiler and compile the .qrc description file and create an .sbaa file. 

Introduction of CMake

CMake is a cross-platform build system that allows you to generate, configure and manage the compilation process of software written in various languages, such as C, C++ and others. CMake uses text files called CMakeLists.txt that contain the commands and instructions to define the project, its dependencies, its options and its build rules. CMake can produce native build files for different platforms, such as Visual Studio, Xcode and others. CMake is used by many open source and commercial projects.

CMake is a powerful and flexible build system that offers many advantages, such as:

  • Portability: CMake can work on different operating systems, such as Windows, Linux, MacOS, and others;
  • Modularity: CMake allows you to organize the project into subprojects, libraries, modules and packages;
  • Configurability: CMake allows you to customize the project with variables, options, cache and scripts;
  • Automatic generation: CMake can automatically generate the build files, the configuration files, the test files and the installation files, using the configure file, enable testing, add test and install commands.

CMake project file

A CMakeLists.txt project file is needed to extract all strings marked for translation from .js and .qml files and build the .sbaa extension's package.

The rcc compiler, needed to compile the qrc, is distributed with the Banana Accounting file. So you already have all the tools needed to build the qrc.
See also Build the package with Banana Accounting.

Below is a template of a project file for translating an extension, you can copy it and modify it:

  • copy the example and save it as CMakeLists.txt in your project folder;
  • add source files as needed to the main target by modifying the qrc file. 

 

cmake_minimum_required(VERSION 3.16)
project(simpleproject)
set(EXTENSION_ID "ch.banana.sample.simpleproject")
# CMake options
# Create a file .vscode/settings.json with the following content to set the options, 
# adapt the path to your environment
# {
#     "cmake.configureSettings": {
#         "BAN_QT_RCC": "C:/users/user_name/AppData/Local/Programs/BananaPlusDev/rcc.exe",
#         "BAN_EXE_PATH": "C:/users/user_name/AppData/Local/Programs/BananaPlusDev/BananaPlusDev.exe",
#     }
# }
set(BAN_QT_RCC $ENV{BAN_QT_RCC} CACHE FILEPATH "Path to Qt rcc executable")
set(BAN_EXE_PATH $ENV{BAN_EXE_PATH} CACHE FILEPATH "Path to BananaPlus executable, used to run tests")
# This target is used to build the extension to a sbaa package
add_custom_target(${PROJECT_NAME}
    COMMAND ${BAN_QT_RCC} -o ${EXTENSION_ID}.sbaa --binary ${EXTENSION_ID}.qrc
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    SOURCES ${EXTENSION_ID}.qrc
)
# This target is used to run the tests of the extension
add_custom_target(test
    COMMAND ${BAN_EXE_PATH} -cmd=runtestsapps -cmd_exit=1 -cmd_p1=${CMAKE_SOURCE_DIR}/${EXTENSION_ID}.sbaa -cmd_op=A
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)

 

Parts to configure 

  • project(simpleproject) 
    Rename simpleproject of name of your project.
  • set(EXTENSION_ID "ch.banana.sample.simpleproject") 
    Rename "ch.banana.sample.simpleproject" of name of your extension id. The name of extension id is the same name of .qrc file.

Environment Variables

In order to build cmake need the following variables. 

  • BAN_QT_RCC
    path to the Qt rcc tool. The rcc Tool is used to compile the extension to a sbaa package.
    The rcc tool is distributed also with Banana Accounting.
  • BAN_EXE_PATH
    path to the BananaPlus executable. The BananaPlus executable is used to run the tests defined in the project.
 
To make the cmake definition file portable is better that you define the environment variable with the OS or specifying it in your IDE. 
But you can also enter the path directly in the cmake file  
  • set(BAN_QT_RCC $ENV{BAN_QT_RCC} CACHE FILEPATH "Path to Qt rcc executable") 
    C:/users/user_name/AppData/Local/Programs/BananaPlusDev/rcc.exe", rename usern_name with yours.
  • set(BAN_EXE_PATH $ENV{BAN_EXE_PATH} CACHE FILEPATH "Path to BananaPlus executable, used to run tests") 
    Path example: "C:/users/user_name/AppData/Local/Programs/BananaPlusDev/BananaPlusDev.exe",  rename usern_name with yours.


For VS Code you can set the environment variables in the file .vscode/settings.json :

Copy

{
   "cmake.configureSettings": {
       "BAN_QT_RCC": "C:\Programms\BananaPlusDev\rcc.exe",
       "BAN_EXE_PATH": "C:\Programms\BananaPlusDev\BananaPlusDev.exe",
   }
}

 

Cmake Project File With Translations

A CMakeLists.txt project file is needed to extract all strings marked for translation from .js and .qml files and build the .sbaa extension's package.

You also need the QT utilities Lupdate and Lrelease that not included in Banana Accounting. You need to download and install the free QT Creator from https://www.qt.io.

Below is a template of a project file for translating an extension, you can copy it and modify it:

  • copy the example and save it as CMakeLists.txt in your project folder;
  • rename the project name translations_project to your desired name;
  • rename the extension id ch.banana.translations to your desired id; 
  • add the desired languages under the variable translations_files;
  • add source files as needed to the main target; 
cmake_minimum_required(VERSION 3.16)
project(translations_project)                      # <!-- CHANGE THE PROJECT'S NAME
set(EXTENSION_ID "ch.banana.translations")         # <!-- CHANGE THE EXTENSION'S ID
# CMake options
# For VS Code create a file .vscode/settings.json with the following content to set the options, 
# adapt the path to your environment
# {
#     "cmake.configureSettings": {
#         "BAN_QT_RCC": "C:\users\user_name\AppData\Local\Programs\BananaPlusDev\rcc.exe",
#         "BAN_EXE_PATH": "C:\users\user_name\AppData\Local\Programs\BananaPlusDev\BananaPlusDev.exe",
#         "BAN_QT_LUPDATE": "C:\Qt\6.5.2\macos\bin\lupdate",
#         "BAN_QT_LRELEASE": "C:\Qt\6.5.2\macos\bin\lrelease"
#     }
# }
set(BAN_QT_RCC $ENV{BAN_QT_RCC} CACHE FILEPATH "Path to Qt rcc executable")
set(BAN_EXE_PATH $ENV{BAN_EXE_PATH} CACHE FILEPATH "Path to BananaPlus executable, used to run tests")
set(BAN_QT_LUPDATE $ENV{BAN_QT_LUPDATE} CACHE FILEPATH "Path to Qt lupdate executable")
set(BAN_QT_LRELEASE $ENV{BAN_QT_LRELEASE} CACHE FILEPATH "Path to Qt lrelease executable")
# This target is used to build the extension to a sbaa package
add_custom_target(translations_project ALL         # <!-- CHANGE THE PROJECT'S NAME
   COMMAND ${BAN_QT_RCC} -o ${EXTENSION_ID}.sbaa --binary ${EXTENSION_ID}.qrc
   WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
   SOURCES ${EXTENSION_ID}.qrc
)
add_dependencies(${PROJECT_NAME} lrelease) #build .qm files when building the sbaa package
# The variable translations_files contains the list of translations files
set(translations_files
   translations/translations_de.ts
   translations/translations_it.ts
   translations/translations_fr.ts
   #translations/translations_xx.ts               # <!-- ADD LANGUAGES AS NEEDED
)
# The target lupdate is used to update *.ts translations files
set(lupdate_commands)
foreach(tr_file ${translations_files})
 list(APPEND lupdate_commands
   COMMAND ${BAN_QT_LUPDATE} ${EXTENSION_ID}.qrc -ts ${tr_file})
endforeach()
add_custom_target(lupdate
   ${lupdate_commands}
   WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
# The target lrelease is used to compile *.ts files to *.qm files
set(lrelease_commands)
set(lrelease_files)
string(REPLACE ".ts" "" lrelease_files "${translations_files}") #remove file extension
foreach(tr_file ${lrelease_files})
 list(APPEND lrelease_commands
     COMMAND ${BAN_QT_LRELEASE} ${tr_file}.ts -qm ${tr_file}.qm)
endforeach()
add_custom_target(lrelease
   ${lrelease_commands}
   WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)

Supplementary Environment Variables for Translation

In order to build cmake need the following variables. 

  • BAN_QT_LUPDATE
    path to the Qt lupdate tool. The lupdate tool is used to update the translations, it will search for text to translate in the code and update the content of *.ts files. If you don't have translations, this options is not necessary.
  • BAN_QT_RELEASE
    path to the Qt lrealease tool. The lrelease tool is used to compile the translations, the compiled translation are integrated in the package.If you don't have translations, this options is not necessary.
 
For VS Code you can set the environment variables in the file .vscode/settings.json :

Copy

{
   "cmake.configureSettings": {
       "BAN_QT_RCC": "C:\Programms\BananaPlusDev\rcc.exe",
       "BAN_EXE_PATH": "C:\Programms\BananaPlusDev\BananaPlusDev.exe",
       "BAN_QT_LUPDATE": "C:\Qt\6.5.2\macos\bin\lupdate",
       "BAN_QT_LRELEASE": "C:\Qt\6.5.2\macos\bin\lrelease"
   }
}

 

Add translations to resource file

Add the *.qm files to the resource *.qrc file.

<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>manifest.json</file>
<file>translations/translations_de.qm</file>
<file>translations/translations_fr.qm</file>
<file>translations/translations_it.qm</file>
</qresource>
</RCC>

Using translation's files in the extension

Translations are automatically loaded by the application.

Translations are provided as *.qm binary files located in the extension's subfolder /translations.

sample_extention.js          // extension
translations/
   translations_de.qm.       // translation's files
   translations_it_CH.qm
   translations_it.qm
   ...

Translations files have the following naming convention:

   translations_lang[_country].qm

Before the execution of the extension the application loads the translation corresponding to the application's language and country. For example if the application has the locale fr_FR the application looks for the following files, the first file found is taken.

   translations_fr_FR.qm
   translations_fr.qm​​​

 

Cmake Project File With Translations

 

Translate strings

  1. Create a folder /translations in your repository;
  2. Open the CMakeLists.txt project file with QtCreator;
  3. Build in QtCreator the target lupdate (figure 1);
  4. Open the generated translations/*.ts files with QtLinguist and enter the translations (figure 2)

Keep the generated translations/*.ts files in the repository, as they are needed for updating the translations after one or more strings are changed or modified in the code.

Update translations

Add translations to resource file

Add the *.qm files to the resource *.qrc file.

XML

Copy

<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>manifest.json</file>
<file>translations/translations_de.qm</file>
<file>translations/translations_fr.qm</file>
<file>translations/translations_it.qm</file>
</qresource>
</RCC>

Build and deploy

  1. Build the extension;
  2. The translations files *.qm are automatically released and included in the package;
  3. Copy the generated *.sbaa file to the destination folder;
  4. Add the extension in Banana AccountingPlus (see installing an'extension);
  5. Test it;

Build the extension

Implementation details

Loading of translation's files

Translations are automatically loaded by the application.

Translations are provided as *.qm binary files located in the extension's subfolder /translations.

sample_extention.js          // extension
translations/
   translations_de.qm.       // translation's files
   translations_it_CH.qm
   translations_it.qm
   ...

Translations files have the following naming convention:

   translations_lang[_country].qm

Before the execution of the extension the application loads the translation corresponding to the application's language and country. For example if the application has the locale fr_FR the application looks for the following files, the first file found is taken.

   translations_fr_FR.qm
   translations_fr.qm​​​
Tell us how we can help you better
If the information on this page is not what you're looking for, is not clear enough, or is not up-to-date, let us know.

Share this article: Twitter | Facebook | LinkedIn | Email