Access variables from custom process step command - qt

In Qt Creator, I would like to configure a custom process step to build the project, which needs to access project variables, or at least the path to the .pro file.
When I run the built-in qmake, the .pro file is passed as first parameter, but when using custom step, it does not pass it.
E.g: Built-in
C:\...\bin\qmake.exe
C:\...\mywidget.pro
-r
-spec
win32-msvc2013
CONFIG+=debug
E.g: Custom
C:\...\bin\qmake.exe
-r
-spec
win32-msvc2013
CONFIG+=debug
When I set up the command, how to access these information?
I already tried with several options without success:
command: C:\...qmake.exe
Arguments: $$TARGET $TARGET $(TARGET) ${TARGET} %{TARGET}% %%{TARGET}%%

You can use %{sourceDir}\mywidget.pro as an argument. Looks like only %{buildDir} and %{sourceDir} are available which are project specific.
Of course, you cannot use values that are defined in the .pro file such as TARGET because those are only evaluated while qmake is running.

Related

Building Qt from source, qmake is invoke by their script with invalid parameters?

I am trying to get a boot2qt build environment setup. It's for an iMX53 - not that it should really matter when it comes to answering my question...
So, as part of the process I run their script called "build_qt.sh". That calls a nested configure script with a big pile of parameters. That script, in turn, builds qmake from source, and then tries to use the new qmake to build the rest of qt (from what it looks like?).
After a long battle, I got it to successfully create the qmake binary, but then the script ends by invoking that with all the parameters passed to the configure script. Qmake then fails because most of these parameters are not valid qmake options!
Here's an excerpt from build_qt.sh:
CONFIGURE_ARGS="${CONFIGURE_ARGS} \
-commercial -confirm-license -release \
-device ${DEVICE} \
-device-option CROSS_COMPILE=${WORKDIR}/tmp/sysroots/x86_64-linux/usr/bin/${COMPILER} \
-sysroot ${WORKDIR}/toolchain/sysroots/${SYSROOT} \
-no-xcb -separate-debug-info -silent -nomake examples -nomake tests -tslib -no-pch -v"
...
./configure ${CONFIGURE_ARGS}
At the end of the that configure script, it does this:
"$outpath/bin/qmake" "$relpathMangled" -- "$#"
Note the $#. That's where all those config arguments end up, which blows it up. Specifically, it complains about the first argument it gets that isn't intended for qmake.
Here's the actual statement it tries to execute:
/home/osboxes/Qt/Boot2Qt-2.x/imx53qsb-eLinux/build-imx53qsb/bin/qmake /home/osboxes/Qt/Boot2Qt-2.x/imx53qsb-eLinux/build-imx53qsb/qt5-src -- -commercial -confirm-license -release -device linux-imx53qsb-hf-g++ -device-option CROSS_COMPILE=/home/osboxes/Qt/Boot2Qt-2.x/imx53qsb-eLinux/build-imx53qsb/tmp/sysroots/x86_64-linux/usr/bin/armv7ahf-vfp-neon-poky-linux-gnueabi/arm-poky-linux-gnueabi- -sysroot /home/osboxes/Qt/Boot2Qt-2.x/imx53qsb-eLinux/build-imx53qsb/toolchain/sysroots/armv7ahf-vfp-neon-poky-linux-gnueabi -no-xcb -separate-debug-info -silent -nomake examples -nomake tests -tslib -no-pch -v
And this is the result:
ERROR: Unknown command line option '-commercial'.
Here is the actual qmake binary help output, which defines the expected syntax:
Usage: ./bin/qmake [mode] [options] [files]
QMake has two modes, one mode for generating project files based on
some heuristics, and the other for generating makefiles. Normally you
shouldn't need to specify a mode, as makefile generation is the default
mode for qmake, but you may use this to test qmake on an existing project
Mode:
-project Put qmake into project file generation mode
In this mode qmake interprets files as files to
be built,
defaults to *; *; *; *.ts; *.xlf; *.qrc
Note: The created .pro file probably will
need to be edited. For example add the QT variable to
specify what modules are required.
-makefile Put qmake into makefile generation mode (default)
In this mode qmake interprets files as project files to
be processed, if skipped qmake will try to find a project
file in your current working directory
Warnings Options:
-Wnone Turn off all warnings; specific ones may be re-enabled by
later -W options
-Wall Turn on all warnings
-Wparser Turn on parser warnings
-Wlogic Turn on logic warnings (on by default)
-Wdeprecated Turn on deprecation warnings (on by default)
Options:
* You can place any variable assignment in options and it will be *
* processed as if it was in [files]. These assignments will be *
* processed before [files] by default. *
-o file Write output to file
-d Increase debug level
-t templ Overrides TEMPLATE as templ
-tp prefix Overrides TEMPLATE so that prefix is prefixed into the value
-help This help
-v Version information
-early All subsequent variable assignments will be
parsed right before default_pre.prf
-before All subsequent variable assignments will be
parsed right before [files] (the default)
-after All subsequent variable assignments will be
parsed after [files]
-late All subsequent variable assignments will be
parsed right after default_post.prf
-norecursive Don't do a recursive search
-recursive Do a recursive search
-set <prop> <value> Set persistent property
-unset <prop> Unset persistent property
-query <prop> Query persistent property. Show all if <prop> is empty.
-qtconf file Use file instead of looking for qt.conf
-cache file Use file as cache [makefile mode only]
-spec spec Use spec as QMAKESPEC [makefile mode only]
-nocache Don't use a cache file [makefile mode only]
-nodepend Don't generate dependencies [makefile mode only]
-nomoc Don't generate moc targets [makefile mode only]
-nopwd Don't look for files in pwd [project mode only]
Note that the parent build_qt.sh script runs Make after this. Also, the qmake "default mode" is -makefile which will Put qmake into makefile generation mode (default). So, I'm pretty certain this command that is failing to execute is supposed to be writing a makefile (essentially this is a "configure script" inside another one).
Does anyone know what that command should be here?
Could someone run a similar instance of build_qt.sh for me and post what command is run here by their functional script? That would likely go a very long ways towards solving this.
Turns out the parent build_qt.sh script and the configure script come from different versions of Qt. They are not compatible! Older versions of Qt don't have this troublesome line:
"$outpath/bin/qmake" "$relpathMangled" -- "$#"
Instead they look like this:
"$outpath/bin/qmake" "$relpathMangled"
Which makes way more sense! I don't know why the current configure file has that funkiness in it, but it doesn't matter for me at the moment.

Qt: How to create a directory in project file?

I just want to crossplatform make a single directory from *.pro file. I use some commands like $(COPY_DIR) and $(COPY_FILE) well. And I saw in internets a many examples with command $(MKDIR) but it did not work for me.
It prints:
C:/Projects/installer/installer.pro(24): Extra characters after test expression.
when I used $$(MKDIR) on line 24.
Or:
C:/Projects/installer/installer.pro(24): '$' is not a recognized test function.
when I $(MKDIR).
What the proper way to create a directory in qmake projects?
Short answer
Use QMAKE_MKDIR like so:
mytarget.commands += $${QMAKE_MKDIR} $$shell_path($${OUT_PWD}/foo)
Long answer
qmake provides variables holding useful commands. Take a look at Undocumented QMake article on Qt Wiki. The one you are looking for is QMAKE_MKDIR, but you might also be interested in QMAKE_CHK_DIR_EXISTS.
If the values given by qmake do not suite you, you can use the environment to retrieve the mkdir command:
$(MKDIR) $$shell_path($${OUT_PWD}/foo)
$$(MKDIR) $$shell_path($${OUT_PWD}/foo)
The $(...) syntax retrieves the environment variable when make (or nmake...) is run while $$(...) retrieves it when qmake is run.
Also the mkdir command should be call in the context of a "make target" declared with QMAKE_EXTRA_TARGETS. See Adding custom targets in qmake documentation.

QMake SUBDIRS project: How to call release-clean from top-level Makefile?

I am using a Qt .pro file using the SUBDIRS template (mainly following this answer).
Furthermore I am building my solution using qmake -recursive MyProject.pro and nmake Release.
Now I want to supply a separate batch file for cleaning up the release output and meta files (not the debug ones though).
The problem is that for the top-level Makefile, only clean and distclean is generated by qmake while for the subdirectories, there are also release-clean and debug-clean (also the folders contain an additional Makefile.Debug and Makefile.Release).
What I want to do is calling
nmake Makefile release-clean
from the batch script. However the top-level makefile does not contain this configuration.
Now I could call the equal line for every subproject manually but this is obviously my least favoured option.
Is there a way to either get qmake to generate a release-clean target for the top-level makefile or is there another way to simply clean release files?
PS: I'm using nmake, so yes I'm on Windows (XP) and using MSVC (2008)
The following batch script does the job :
REM set up environment
SET VISUALDIR=C:\PROGRA~1\MICROS~1.0
PUSHD %VISUALDIR%\VC
CALL vcvarsall.bat x86
POPD
REM clean solution
msbuild yoursolution.sln /p:Configuration=Release /t:clean
REM and you may want to add a build command :
msbuild yoursolution.sln /p:Configuration=Release
Ever tried nmake Makefile.Release clean, that should do the job.

What the right variable to use here, that represents the TARGET field in the .pro file

I would like to add a custom command, that will work on the generated binary file (The target field in *.pro file),
But what should I use here, in the Command arguments
I'm afraid this is not possible. QtCreator only handles source and build directory. The QtCreator documentation says:
The following Qt Creator variables are available:
%{buildDir}
%{sourceDir}
Note that the target even doesn't have to be in the build directory. The build directory is where qmake is ran, typically resulting in the target being put there, because in the .pro file one typically specifies TARGET = projectName.
Further note that the QtCreator build steps configuration only works within QtCreator. This should not be used when your custom build steps are needed for other people working without QtCreator (they should only run qmake and make to build your application).
This being said and assuming that you want to define a post-build step, you should look for a solution to define such in the .pro file (by using the $${TARGET} variable) so that qmake will put your buildstep into the Makefile after the linking step.
If you want to execute a command after linkage, let's say call a custom script (batch script on Windows, otherwise a bourne shell script) with the TARGET as an argument, add the following to your .pro file:
win32 {
poststep.commands = #myScript.bat $${TARGET}
}
!win32 {
poststep.commands = #./myScript.sh $${TARGET}
}
QMAKE_EXTRA_TARGETS += poststep

Overriding build rules in make

I'm using a Makefile to build an embedded project. I've inherited the project from numerous previous developers who haven't been using Make to its full potential, and I'd like to be able to specify the project version in the makefile using defines on the build command. However, there's already a build rule that builds all the object (.o) files. Is there any way to override that build rule for a specific object file so that I can add -D flags to the compiler ?
Another reason I'd like to be able to specify the project version in the makefile is so that I can have it generate artifacts with the build version in the names of the resulting files produced by the build process.
Yes, you can override a pattern rule (which is what I bet your .o rule is), just by having a specific rule (and the order of the rules doesn't matter):
%.o:
do_generic_things
x.o:
do_specific_things -Dproject_version
Yes, you can put a build version in a file name. There's more than one way to do it-- the best is probably to put it in the target name:
%$(B_VERSION).o: %.c
$(CC) -c -DBUILD_VERSION=$(B_VERSION) -Whatever $&lt -o $#
If you are using GNU make and you only want to change compiler options, you can use target-specific variables, like so:
x.o: CFLAGS += -DEXTRA_SYMBOL_FOR_X
This also works recursively, i.e. the target-specific value for x.o also is in effect for all targets which x.o depends on, meaning that if you build multiple executables in your makefile, you can set a target-specific variable on the executable itself, which will be in effect for all the object files:
foo: CFLAGS += -DEXTRA_SYMBOL_FOR_FOO_APP

Resources