How to run QT's `lupdate`-tool with a `qmake CONFIG`? - qt

This question has been posted before in the qt community: https://forum.qt.io/topic/106930/how-to-run-lupdate-with-a-qmake-config
I use such a construct in my project files:
LANGUAGES = de
TRANSLATION_NAME = authorization
include(../../gen_translations.pri)
where gen_translations.pri looks like so:
# parameters: var, prepend, append
defineReplace(prependAll) {
for(a,$$1):result += $$2$${a}$$3
return($$result)
}
TRANSLATIONS = $$prependAll(LANGUAGES, $$PWD/libs/$$TRANSLATION_NAME/translations/lib$${TRANSLATION_NAME}_, .ts)
TRANSLATIONS_FILES =
qtPrepareTool(LRELEASE, lrelease)
for(tsfile, TRANSLATIONS) {
qmfile = $$shadowed($$tsfile)
qmfile ~= s,.ts$,.qm,
qmdir = $$dirname(qmfile)
!exists($$qmdir) {
mkpath($$qmdir)|error("Aborting.")
}
command = $$LRELEASE -removeidentical $$tsfile -qm $$qmfile
system($$command)|error("Failed to run: $$command")
TRANSLATIONS_FILES += $$qmfile
}
for(qmentry, $$list($$TRANSLATIONS_FILES)) {
qmpath = $$OUT_PWD/../translations
qmpathname = $$replace(qmpath,/,)
qmpathname = $$replace(qmpathname,\.,)
qmpathname = $$replace(qmpathname,:,)
qmpathname = $$replace(qmpathname," ",)
qmentity = qmfiles_$${qmpathname}
eval($${qmentity}.files += $$qmentry)
eval($${qmentity}.path = $$qmpath)
INSTALLS *= $${qmentity}
}
It generates the *.qm files for me and moves them to a defined location with make install.
I do not want qmake to execute that whole stuff for each build on my developing machine. Therefore I want to make it conditional by wrapping it for qmake:
translate{
LANGUAGES = de
TRANSLATION_NAME = authorization
include(../../gen_translations.pri)
}
That way I can decide when I want to get *.qm files and when not.
But then I am unable to run lupdate on the project file beforehand because it is blocked by that conditional.
I am sure, that someone has a better idea to accomplish the task.
Thanks in advance.

I'm sharing here my recipe for the vmpk project. I've borrowed it from the Arora project (I think). It is much simpler than yours, and I let qmake to decide if it is necessary regenerate any .qm files when the output has been erased or the input .ts has changed, like any other compiler does.
updateqm.pri
# update translations
isEmpty(QMAKE_LRELEASE) {
win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\\lrelease.exe
else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease
!exists($$QMAKE_LRELEASE) { QMAKE_LRELEASE = lrelease }
}
updateqm.input = TRANSLATIONS
updateqm.output = $$OUT_PWD/${QMAKE_FILE_BASE}.qm
updateqm.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm $$OUT_PWD/${QMAKE_FILE_BASE}.qm
updateqm.CONFIG += no_link target_predeps
QMAKE_EXTRA_COMPILERS += updateqm
project.pro:
TRANSLATIONS += \
translations/project_en.ts \
translations/project_cs.ts \
translations/project_de.ts \
translations/project_es.ts \
translations/project_fr.ts \
translations/project_ru.ts
include(updateqm.pri)
With this project file you can do, as always:
lupdate project.pro
Anyway, Qt5 has a builtin CONFIG+=lrelease option that makes "updateqm.pri" deprecated.

Related

Copy files to output directory QT

I'm currently struggling to get a sub folder of my project to copy to the out directory. I had thought i had it all set up correctly but i guess i'm missing a step. When I run the make i get a "No rule to make target 'copyfiles'" message.
I know I could just make a new build step with a OS specific method, but i was hoping to avoid it cause I would like to build and run on a different OS eventually.
Edit:
Yes this question has been asked before. However the solutions given in those questions have not worked for me. They throw errors or simply do nothing.
CONFIG(release, debug|release): DESTDIR = $$OUT_PWD/release
CONFIG(debug, debug|release): DESTDIR = $$OUT_PWD/debug
copytarget.path = $$DESTDIR/etc
copytarget.files += $$files(etc/*)
## === os specific dir separator ===
win32 {
copytarget.files ~= s,/,\\,g
copytarget.path ~= s,/,\\,g
}
message("found files for copytarget: "$$copytarget.files)
message("found files destination: "$$copytarget.path)
## === copy compiler for makefile ===
DirSep = /
win32: DirSep = \\
for(f,copytarget.files) tmp += $$PWD$$DirSep$${f} ## make absolute paths
copycompiler.input = tmp
isEmpty(DESTDIR):DESTDIR=.
copycompiler.output = $$DESTDIR$$DirSep${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
copycompiler.commands = $(COPY_FILE) ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copycompiler.CONFIG = no_link no_clean
## other CONFIG options are: depends explicit_dependencies target_predeps
copycompiler.variable_out = QMAKE_DISTCLEAN
QMAKE_EXTRA_COMPILERS += copycompiler
## == makefile copy target ===
copyfiles.recurse_target = compiler_copycompiler_make_all
copyfiles.depends = $$copyfiles.recurse_target
copyfiles.CONFIG += recursive
MAKE_EXTRA_TARGETS += copyfiles
POST_TARGETDEPS += copyfiles ## copy files after source compilation
INSTALLS += copytarget

qmake and generated qm files

What is the best (proper) way to organize compiled translations (*.qm) into resources?
*.qm files referred in qrc file and generated by two (three) extra targets this way:
trans_update.commands = lupdate $$_PRO_FILE_
trans_update.depends = $$_PRO_FILE_
trans_release.commands = lrelease $$_PRO_FILE_
trans_release.depends = trans_update $$TRANSLATIONS
translate.depends = trans_release
QMAKE_EXTRA_TARGETS += trans_update trans_release translate deploy
CONFIG(release, debug|release) {
DESTDIR=release
PRE_TARGETDEPS += translate
}
but the problem is at the moment qmake runs first time, there're no qm files generated yet and make prints errors like:
RCC: Error in 'qml.qrc': Cannot find file ...
I don't like an idea of saving compiled qm files into VSC.
Is there a way to organize it nicely?
I like to point out a solution which I use in some projects. It might be far from perfect, but it works out nicely.
CONFIG(release, debug|release) {
TRANSLATION_TARGET_DIR = $${OUT_PWD}/release/translations
LANGUPD_OPTIONS = -locations relative -no-ui-lines
LANGREL_OPTIONS = -compress -nounfinished -removeidentical
} else {
TRANSLATION_TARGET_DIR = $${OUT_PWD}/debug/translations
LANGUPD_OPTIONS =
LANGREL_OPTIONS = -markuntranslated "MISS_TR "
}
isEmpty(QMAKE_LUPDATE) {
win32:LANGUPD = $$[QT_INSTALL_BINS]\lupdate.exe
else:LANGUPD = $$[QT_INSTALL_BINS]/lupdate
}
isEmpty(QMAKE_LRELEASE) {
win32:LANGREL = $$[QT_INSTALL_BINS]\lrelease.exe
else:LANGREL = $$[QT_INSTALL_BINS]/lrelease
}
langupd.command = \
$$LANGUPD $$LANGUPD_OPTIONS $$shell_path($$_PRO_FILE_) -ts $$_PRO_FILE_PWD_/$$TRANSLATIONS
langrel.depends = langupd
langrel.input = TRANSLATIONS
langrel.output = $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm
langrel.commands = \
$$LANGREL $$LANGREL_OPTIONS ${QMAKE_FILE_IN} -qm $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm
langrel.CONFIG += no_link
QMAKE_EXTRA_TARGETS += langupd
QMAKE_EXTRA_COMPILERS += langrel
PRE_TARGETDEPS += langupd compiler_langrel_make_all
There might be a sensful tweak to lupdate options because the various builds (release and debug) generate different *.ts files which then trigger a change in the used VCS.
I also like to guide the tended reader to an example where experts use it.
The recommended way -- which may not have been available at the time this question was originally asked would be to use
TRANSLATIONS += <your *.ts files>
CONFIG += lrelease embed_translations
If you really need/want to build the qm files separately, I'd point to what qmake does with the above config and adapt it according to your needs. See https://github.com/qt/qtbase/blob/5.15.2/mkspecs/features/lrelease.prf
(Basically, it creates and adds a list of resources to RESOURCES).

Add static lib(file .lib) in .pro to compile a application Qt/Android

I have a problem to compile a project Qt/Android, because of the use of some static libs(windows .lib). The current situation of .pro file is this:
android {
QT += androidextras
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/native
ANDROID_DEPLOYMENT_DEPENDENCIES = \
$$PWD/../../../libraries/protobuf/vsprojects/Release/libprotobuf.lib \
$$PWD/../../../libraries/log4qt/lib/liblog4qtd.lib
}
However this not solve the problems, i not know what make =/

qmake copy files created while building

I've got a library qmake project:
QT += gui
TARGET = qturtle
TEMPLATE = lib
DEFINES += QTURTLE_LIBRARY
SOURCES += qturtle.cpp
HEADERS += qturtle.h\
qturtle_global.h
docMake.commands = doxygen;
QMAKE_EXTRA_TARGETS += docMake
PRE_TARGETDEPS += docMake
QMAKE_DISTCLEAN += $$PWD/html/ -r
QMAKE_DISTCLEAN += doxygen_sqlite3.db
unix {
docInstall.path = /usr/share/doc/qturtle
docInstall.files = $$PWD/html/
headerInstall.files = $$HEADERS
headerInstall.path = /usr/include/qturtle
target.path = /usr/lib
INSTALLS += docInstall
INSTALLS += target
INSTALLS += headerInstall
}
docMake runs doxygen in the project directory, and creates the 'html' directory and its contents ( during build!)
'html' and its contents now should be copied to /usr/share/doc/qturtle, using the INSTALL variable.
BUT: qmake doesn't generate any code for docInstall install, because $$PWD/html and its contents do not exist during makefile generation. Could anybody tell me how to avoid this problem, or do I have to use cp?
Thanks in advance,
Marius
There are two approaches to address this problem.
Not to check againt the initially empty directory
docInstall.CONFIG += no_check_exist directory
Since this directory will be created on the fly, I would personally opt for this.
Create the directory explicitly
createDirs.commands = $$QMAKE_MKDIR $$PWD/html
This could be done either in a target or even in a system("$$QMAKE_MKDIR $$PWD/html") call, depending on your needs.

How it's better to add generatable sources files to qmake project?

There is somefile.h.in and script somefile.h.pl which generates number of files like "somefile.h.gen" or "somefile_other.cpp.gen2".
How to add source generation phase in qmake? In plain Makefile I'd just put things like
somefile.o: somefile.cpp somefile.h somefile.h.gen
...
soemfile.h.gen: somefile.h.in somefile.h.pl
./somefile.h.pl < somefile.h.in # writes somefile.h.gen and friends
I need to use QMAKE_EXTRA_COMPILERS feature:
PREPROCESS_FILES = somefile.h.in
preprocess.name = Generate various files based on somefile.h.in
preprocess.input = PREPROCESS_FILES
preprocess.output = ${QMAKE_FILE_BASE}.gen
preprocess.commands = perl $$PWD/somefile.h.pl $$PWD/somefile.h.in
preprocess.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += preprocess
PRE_TARGETDEPS += somefile.h.gen

Resources