I want qmake to run a (python) script automatically. This script modifies the makefiles, so it has to be executed after qmake generates the makefiles but before make.
So far I've only found 2 ways to run a script from qmake:
Using system() in my .pro file, but this runs before qmake - too soon:
win32: PYTHON=python.exe
else: PYTHON=python
system($$PYTHON ./test.py)
or via custom build target using QMAKE_EXTRA_TARGETS, but this is invoked by make (too late).
Is there any way to run a script from qmake after it generates the makefiles?
Since we are using TEMPLATE = subdirs for our project, I solved this by creating new subdir, that is parsed by qmake as a last one. In its pro file I'm using TEMPLATE = aux and running the script by system() call.
It's not the best solution, but it works quite well.
The following has worked well for me for several years.
Create a .cmd or .sh script that invokes qmake, and then your script:
%QTDIR%\bin\qmake %*
python.exe test.py
Save the script where it can be found via the PATH environment
In your .pro file add the following:
QMAKE_QMAKE = myqmake
Then simply invoke myqmake rather than qmake
If the script will be run outside the Qt enviornment, (such as from an IDE), then it may need to define the QTDIR and QMAKESPEC environments.
Cotire (compile time reducer) for CMake might me your friend.
It has the following the feature you're looking for to speed up builds:
Automatically generates a single compilation unit (aka unity source file) for a CMake target.
I did not use it but it is recommended in a C++ best practice list.
Related
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.
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.
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
What changes must I make to the .pro file if I want to execute chmod command, execute the output binary file, or do some other operations.
I had a similar problem. I wanted a special tool (versioner) to run over the code every time the Makefile was executed. Here's the solution:
(to be read in the Qmake Manual, Configuring qmake's Environment, Section: Customizing Makefile Output)
Create you own Makefile target. Specify the command etc.
mytarget.target = .buildfile
mytarget.commands = touch $$mytarget.target
QMAKE_EXTRA_TARGETS += mytarget
This way, you have an extra target you can call with make mytarget for example. If you want to tie it together to the actual buildtarget you'll have to add:
POST_TARGETDEPS += mytarget
Hope that helps.
Best regards
D
Another way to make things in given order is to use empty "super" target:
super.depends = target_pre first target_post
QMAKE_EXTRA_TARGETS += super
Where first - is default qmake target, and target_pre and target_post some custom targets. Now make super just do the thing.
EDIT: looks like in last versions of Qt build of dependencies is running in paralell so this solution wouldn't work.
If you are using Qt Creator, you can add custom build steps in the Projects panel: http://doc.qt.nokia.com/qtcreator-2.1/creator-build-settings.html#adding-custom-build-steps
The right answer depends on exactly what you want, and when. However, as seen in some previously posted comments here QMAKE_POST_LINK is probably what you want rather than POST_TARGETDEPS.
Check out this related post:
QMake: execute script after build
For one, when you use POST_TARGETDEPS that fires off BEFORE your exe is created (in Windows) or BEFORE it is recreated (in Linux)! QMake works differently depending upon the platform and the complier.
I needed to do some "symbols processing" on an exe when it was recompiled. POST_TARGETDEPS gave me problems in both Windows (using mingw) and Linux (using gcc). In Windows, it executed my script prematurely, and in Linux it overwrote my exe after I had modified it (i.e. added back my debugging info to the exe after I had stripped it in my external script). QMAKE_POST_LINK worked perfectly, however, in both cases. It's also short, sweet, and more clear by comparison!
I am trying to add a unit test to a group of other tests. All the tests are in their own subdirectories, each with it's own .pro file and the .cpp file which contains the tests themselves. Running qmake in one of the subdirectories creates a Makefile, and then running make runs the compiler to make the TARGET. The tests are actually run by the 'check' target - ie with 'make check'.
The test I'm trying to add is different, but it is trying to pretend to behave the same way.
It is different because it is a perl script and so doesn't need to be compiled. It does, however, need to be run - so 'make check' needs to work.
I had a .pro file working for the most part - 'qmake', 'make', 'make check', and 'make clean' would work, but 'make distclean' removed my script (since it assumes it can be regenerated by compiling something).
So, the question is, how do I stop it from removing my script?
Perhaps there's some other approach I should be taking. I had tried the 'subdirs' TEMPLATE, but that does more than just remove the line in Makefile that deletes the TARGET.
Ideas?
Using Ubuntu Linux with Qt 4.6.0.
I would look into the custom target capabilities for your script. Maybe something like this:
check.commands = <scriptname>
check.depends = <any dependencies>
QMAKE_EXTRA_TARGETS += check
Doing things this way will run the check command when the dependencies change, but as long as you don't specify check.target then it shouldn't remove anything. (If your script does produce output, then perhaps that should be in check.target.) Also, since it is specified as an "extra" command, qmake shouldn't create commands to delete your script in a distclean.
This is assuming that your script is in its own subdirectory (which you state), and is the only "check" command that needs run in that subdirectory (kind of implied by the question, but not directly stated).