We have a fairly large code-base. The vast majority of the code is compiled using qmake to produce the makefiles. However, there are some sub-projects that get produced by running batch files or running other programs.
I'd like to be able to have everything compiled using qmake, but I can't figure out how to get qmake to simply run a script.
One thing that I've tried is using QMAKE_EXTRA_TARGETS in my pro file, like so:
TEMPLATE = lib
SOURCES = placeholder.cpp
CONFIG += no_link staticlib
batch_runner.target = placeholder.cpp
batch_runner.commands = my_batch_file.bat
QMAKE_EXTRA_TARGETS = batch_runner
I then have to have the batch file produce placeholder.cpp like so:
# do the real work here
# ...
# create placeholder.cpp so qmake and nmake are happy
echo // dummy >> placeholder.cpp
This seems to work fine. The trouble is that it is somewhat hokey. If I don't specify batch_runner.target (i.e. I leave it blank) or don't put placeholder.cpp in SOURCES then the batch file never gets run. This is because qmake isn't making batch_runner.commands the action for any other dependency in the Makefile.
Is there any better way to get QMake to construct a Makefile such that a script is run when the Makefile executes?
You could use the SUBDIRS configuration to run multiple different targets, even from the same makefile. This might work especially well with your extra targets, as a subdir configuration can specific a specific target in the makefile to run (see undocumented qmake for details). In this case, I would put all of the "regular" build commands in one .pro file, the external build commands in another, and a subdirs .pro file to build all of them. I haven't tested anything quite like this, but it should work.
regular.pro:
external.pro:
do_it_all.pro:
It looks like QMAKE_POST_LINK works well for this sort of thing.
This seems to get the job done. my_batch_file.bat runs when nmake runs (rather than when qmake runs) and I don't need to do anything funny with placeholder targets or files.
It's quite likely that I don't need all of the items listed in 'CONFIG'.
Here is another solution:
The template
aux
basically produces a makefile which does nothing when run without specifying a target. TheOBJECTS_DIR
andDESTDIR
variables are set to the current directory to prevent that qmake creates thedebug
andrelease
directories (it's important to set them to./
and not just to.
; at least on Windows). Then, usingQMAKE_EXTRA_TARGETS
, we redefine the targetfirst
to run the custom command when the makefile is invoked without target.It's a bit hacky but it gets the job done.
Addition: If you want to prevent the generation of three makefiles (
Makefile
,Makefile.Debug
,Makefile.Release
), you can addHowever, if you use this and depending on how the makefile is invoked (always invoked manually, invoked by parent directory's "subdirs" *.pro file, ...), it might be necessary to create fake
debug
andrelease
targets to avoid "no rule to make target..." errors. For example:Try the system() command. For example: