Add an extension in a .pro variable - qt

I'm trying to print a message with QMake but I have problems with extensions:
lib_name = $$1
message("test1: $$MYPATH/$$lib_name/src/$$lib_name.pri");
message("test2: $$MYPATH/$$lib_name/src/$$lib_name");
For some reason, test1 doesn't print the correct path. It just prints the path until src/. But, test2 is ok. It prints everything until the value in $$1.
Any workaround?

QMake supports variables (objects) with members that can be used using the dot . operator e.g. target.path for INSTALLS. So, in your case, $$lib_name.pri means that you're accessing the member pri of lib_name which doesn't exist so there's no output.
You need to enclose variables in curly braces for QMake to distinguish them from the surrounding text i.e. $${lib_name}.pri.
Example:
message("test1: $$MYPATH/$$lib_name/src/$${lib_name}.pri");
# ~~~~~~~~~~~~
For more examples of objects, see Adding Custom Target and Adding Compilers sections of QMake's Advanced Usage page.
Here's another relevant SO thread: QMake - How to add and use a variable into the .pro file

Related

ZSH - print java version in right prompt

I have a daily use case where I need to work with projects on different version of Java (8, 11, ...).
I would like to have it displayed in the right side prompt in my shell (ZSH with Oh-My-Zsh). I know of a dummy way (computationally expensive) to do it (just java --version to var and display it). I would like it to have it cached until I don't source a file (which is a specific project file that sets the new env vars for different java versions).
Do you have any ideas how to do this efficiently?
Br,
Stjepan
The PROMPT and RPROMPT variables can have both static and dynamic parts, so you can set the version there when you source the project file, and it will only be calculated one time. The trick is to get the quoting right.
This line goes in the project file that sets the env variables, somewhere after setting PATH to include the preferred java executable:
RPROMPT="${${=$(java --version)}[1,3]}"
The pieces:
RPROMPT= - variable for the right-side prompt.
"..." - the critical part. Variables in double quotes will be expanded then and there, so the commands within this will only be executed when the project file is sourced.
${...[1,3]} - selects the first three words of the enclosed expression. On my system, java --version returns three lines of data, which is way too big for a prompt; this reduces it to something manageable.
${=...} - splits the enclosed value into words.
$(java --version) - jre version info.

How to specify output name for qt5_add_translation?

I want to generate a plenty *.qm for plenty *.ts files for different languages using qt5_add_translation. All the *.ts files are named using *.de_DE.ts/*.fr_FR.ts/etc convention. But qt5_add_translation produce output, using only basename until first ., not the last one.
There is no possibility to pass options to lrelease using qt5_add_translation(QM_FILES "${PROJECT_NAME}.de_DE.ts" OPTIONS -qm "${PROJECT_NAME}.de_DE.qm") syntax.
Also setting OUTPUT_NAME property for source *.ts file is not working:
set_source_files_properties(
"${PROJECT_NAME}.de_DE.ts" PROPERTIES
OUTPUT_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_NAME "${PROJECT_NAME}.de_DE.qm"
)
Producing filename in the case is still "${PROJECT_NAME}.qm", not "${PROJECT_NAME}.de_DE.qm"
How to override producing name for resulting *.qm file?
Surely I can make custom command and use it for my purposes, but I prefer to use ready qt5_add_translation.
EDIT:
Looking at /usr/local/Qt-5.9.2/lib/cmake/Qt5LinguistTools/Qt5LinguistToolsMacros.cmake I conclude, that there is no way to achieve desired using ready to use qt5_add_translation, because of using get_filename_component(qm ${_abs_FILE} NAME_WE) to get filename:
NAME_WE = File name without directory or longest extension
For my purposes there is need to use combination of ABSOLUTE (to get filename w/ full suffix), then to apply multiple times EXT in combination with NAME_WE to extract filename w/o shortest extension.
I ended up with the below custom function add_translation to replace qt5_add_translation:
function(ADD_TRANSLATION _qm_files)
foreach(_basename ${ARGN})
set(qm "${CMAKE_CURRENT_SOURCE_DIR}/${_basename}.qm")
add_custom_command(
OUTPUT "${qm}"
COMMAND "${Qt5_LRELEASE_EXECUTABLE}"
ARGS -markuntranslated "Not translated!" -nounfinished -removeidentical -compress "${CMAKE_CURRENT_SOURCE_DIR}/${_basename}.ts" -qm "${qm}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${_basename}.ts" VERBATIM
)
list(APPEND ${_qm_files} "${qm}")
endforeach()
set(${_qm_files} ${${_qm_files}} PARENT_SCOPE)
endfunction()
It accepts basenames of *.ts files and produces list of resulting *.qm files: both in current source directory.
Please upgrade to Qt 5.9.4 or newer. The handling of .ts files with dots in the name has been fixed there, see also https://bugreports.qt.io/browse/QTBUG-64317 .

Robot Framework : Configuration Profiles

I have a configuration file that I am reading into my robot test cases. This configuration file contains the following variables:
${DATABASE_IP} 127.0.0.1
${ORACLE_SYSTEM_ID} xe
${ORACLE_DATABASE_URL} jdbc:oracle:thin:#${DATABASE_IP}:1521:${ORACLE_SYSTEM_ID}
${ORACLE_DATABASE_USER} cooluser
${ORACLE_DATABASE_PASSWORD} coolpassword
${ORACLE_DATABASE_DRIVER} oracle.jdbc.driver.OracleDriver
One thing I'd like to be able to do is change some of these properties, depending on where the script is executed from. Example: jenkins
A simple way to look at this, is say as follows:
I have a test file called database_test.robot.
If I invoke this file on my local machine, I'd like to pass in an argument to ensure ${DATABASE_IP} equates to 127.0.0.1 . When Jenkins does it, I want that value to point somewhere else.
Something like this already exists with maven, where you can specify a profile at runtime. Ex: mvn verify -Plocal-config ; mvn verify -Pjenkins-config
I have looked through the robot framework documentation, but cannot seem to implement something similar. The only way to swap out properties that I see is to remove the old and replace in the new. Note : I have hundreds of properties that will differ, and several other environments aside form Jenkins and local that would take different values.
Robot gives you at least three ways to solve this: argument files, variable files, and resource files. In each of the cases, you can specify which environment settings to use with a command line argument.
Argument files
Argument files are, as the name implies, files from which robot can read arguments. They are a convenient way to specify a group of command line arguments.
For example, you could create a "environments" folder that contains argument files for each of your environments (production.args, staging.args, local.args) and within the file you would set the values for all of the variables.
For example, you could create a file named local.args with the following contents:
--variable DATABASE_IP:127.0.0.1
--variable ORACLE_SYSTEM_ID:xe
--variable ORACLE_DATABASE_URL:jdbc:oracle:thin:#127.0.0.1:1521:xe
--variable ORACLE_DATABASE_USER:cooluser
--variable ORACLE_DATABASE_PASSWORD:coolpassword
--variable ORACLE_DATABASE_DRIVER:oracle.jdbc.driver.OracleDriver
Then, to run with this configuration you would use the -A or --argumentfile option:
robot --argumentfile environments/local.args ...
The advantage to using argument files is that you can override single values on the command line for times when you need to change just one value:
robot --argumentfile environments/local.args --variable ORACLE_DATABASE_USER:anotheruser
Also, with argument files you can also specify any other command line arguments. For example, if you always want to ignore tests on your CI server that are known to be broken, you could include something like --exclude known-broken (where known-broken is a tag you've applied to one or more tests)
One downside to argument files is that you can't define variables based on the value of previous variables (ie: you can't do --variable FOOBAR=${FOO}bar). I've not found that to be much of a problem.
Variable files
Variable files work in a similar way, but let you define the variables with python. The advantage to variable files is that you can do anything that python lets you do. For example, you could automatically determine the IP of the local database, or selectively turn features on or off based on runtime conditions.
The simplest way to define a variable file is to simply create python variables, which robot will find by importing your file.
For example, the variable file for your variables might look like this:
DATABASE_IP = "127.0.0.1"
ORACLE_SYSTEM_ID = "xe"
ORACLE_DATABASE_URL = " jdbc:oracle:thin:#%s:1521:%s % (DATABASE_IP, ORACLE_SYSTEM_ID)
ORACLE_DATABASE_USER} = "cooluser"
ORACLE_DATABASE_PASSWORD} = "coolpassword"
ORACLE_DATABASE_DRIVER} = "oracle.jdbc.driver.OracleDriver"
Resource Files
Much like the other two solutions, you can have separate resource files for each environment. Since robot allows you to use variables in resource file paths within a suite, you can use a variable to define which resource file to use.
For example, you could import a resource file like this:
# some_tests.robot
*** Settings ***
Resource config/${environment}.robot
You would then create a config file for each environment like you normally would (eg: config/local.robot, config/staging.robot, etc). Then, when you run robot you can tell it which resource file to use:
$ robot --variable environment:local ...
I tried the third option with Resource files but given above command line argument statement:
$ robot --variable environment=local
Didn't work for me. After looking at the robot help file, came to know that variable values should be passed through : and not with =.
So I tried with:
$ robot --variable environment:local
And it worked for me.
The correct way to specify the Resource path for a subdirectory is:
Resource ../config/${environment}.robot
if config is a subdirectory.

Qt Installer Framework : Create shortcut with argument

Does anyone know how to add an argument to a shortcut created by QT IFW?
I need the exe it launches to be passed an argument.
Here's what works (with no argument):
component.addOperation( "CreateShortcut",
"#TargetDir#/MyApp.exe",
"#StartMenuDir#/#ProductName#.lnk",
"workingDirectory=#TargetDir#",
"iconPath=#TargetDir#/MyApp.exe",
"iconId=0");
I want the exe to get something like -c passed to it. I've tried a few approaches, but am not having any luck.
Qt Installer framework documentation is very poor, but you can read in operations the following:
"CreateShortcut" filename linkname [arguments]
Creates a shortcut from the file specified by filename to linkname. On Windows, this creates a .lnk file which can have arguments. On Unix, this creates a symbolic link.
So do it in that way:
component.addOperation("CreateShortcut", "#TargetDir#/Appname.exe", "#DesktopDir#/Appname.lnk", "-param");
Result in lnk target element:
C:\YourAppDirectory\Appname.exe -param
EDIT:
Your case works as well for me:
component.addOperation( "CreateShortcut","#TargetDir#/Appname.exe","#StartMenuDir#/#‌​ProductName#.lnk", "-param", "workingDirectory=#TargetDir#", "iconPath=#TargetDir#/Appnam‌​e.exe","iconId=0");
with -param as the last argument too.

Qt internationalization and CMake: how to update *.ts and don't lose them

I'm having this CMakeLists.txt in directory with translation files (*.ts):
SET(TRANSLATIONS
lang_de.ts
lang_en.ts
)
FIND_PACKAGE(Qt5LinguistTools)
QT5_ADD_TRANSLATION(QM_FILES ${TRANSLATIONS})
SET(QM_FILES ${QM_FILES} PARENT_SCOPE)
ADD_CUSTOM_TARGET (translations ALL DEPENDS ${QM_FILES})
It builds *.qm files from specified *.ts.
But I want to improve this and get two custom targets, which won't built automatically.
One for appending new strings from sources into ts files, and one for refreshing ts. The last one would update ts from sources and remove obsolete strings from ts.
I've tried to add this after lines above:
ADD_CUSTOM_TARGET (
ts_append
COMMAND QT5_CREATE_TRANSLATION(QM_FILES ${CMAKE_SOURCE_DIR}/src/app ${TRANSLATIONS} OPTIONS -I ${CMAKE_SOURCE_DIR}/src)
)
ADD_CUSTOM_TARGET (
ts_refresh
COMMAND QT5_CREATE_TRANSLATION(QM_FILES ${CMAKE_SOURCE_DIR}/src/app ${TRANSLATIONS} OPTIONS -no-obsolete -I ${CMAKE_SOURCE_DIR}/src)
)
but it seems I can't use QT5_CREATE_TRANSLATION macro inside custom target, isn't it?
Maybe I'm on wrong way, how would you solve this problem: easy updating of ts and don't lose them after make clean?
To solve the make clean problem, add a sub directory (ADD_SUBDIRECTORY(translations)) and add SET_DIRECTORY_PROPERTIES(PROPERTIES CLEAN_NO_CUSTOM 1) to the contained CMakeLists.txt.
See here for an example of that.
For the second part of your question there are two possible ways to do it. Either use FILE(WRITE <filename> "QT5_CREATE_TRANSLATION(QM_FILES ${SOURCE_DIR}/src/app ${TRANSLATIONS} OPTIONS -I ${SOURCE_DIR}/src)") and then use COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR} -DTRANSLATIONS=${TRANSLATIONS} <filename> in add_custom_target. I doubt there's a good way of retrieving the contents of QM_FILES though.
The second option is creating two additional sub directories, each with a QT5_CREATE_TRANSLATIONS and a ADD_CUSTOM_TARGET call.

Resources