I am trying to write a Qt .pro file that will run a set of commands, without compiling anything else first. Setting TEMPLATE=aux allows me to run just the script, and with help from this answer I have the following .pro file
# Target and build folders
TARGET = MySuperLibrary.dll
DESTDIR = ../../BuildAll
# Creates a Makefile for not building anything.
TEMPLATE = aux
extralib.target = extra
extralib.commands = echo \"Build the library\";
extralib.depends =
QMAKE_EXTRA_TARGETS += extralib
PRE_TARGETDEPS = extra
The problem is that the script commands are run every time, but I don't want them to run if the target file already exists. How should I modify the file so that the extralib commands are not run if the target file already exists?
Edit 16.01.2021
Following from zgyarmati's answer, I have modified the pro file as follows. Note that the new mytarget.commands actually generates the target dll and gives it a new timestamp. Unfortunately, this modified pro file still generates the dll every time it is run. Naturally the real script I want to run to generate this dll takes about ten minutes, so I really do not want it to run every time I build the project.
TARGET = MySuperLibrary.dll
DESTDIR = ../../BuildAll
# Creates a Makefile for not building anything.
TEMPLATE = aux
DESTDIR_WIN = $${DESTDIR}
DESTDIR_WIN ~= s,/,\\,g
mytarget.target = $${DESTDIR_WIN}\\$${TARGET}
mytarget.commands = echo \"MyDll\" > $${DESTDIR_WIN}\\$${TARGET}
mytarget.depends = mytarget2
mytarget2.commands = #echo Building $$mytarget.target
QMAKE_EXTRA_TARGETS += mytarget mytarget2
PRE_TARGETDEPS += mytarget2
Your script should create the extra file, to flag that it has been run. See https://doc.qt.io/qt-5/qmake-advanced-usage.html#adding-custom-targets
Related
Here's a simple example of adding a custom build step:
mytarget.commands = #echo Testing123
QMAKE_EXTRA_TARGETS += mytarget
PRE_TARGETDEPS += mytarget
This works, and prints the message as expected. However, it also re-makes all targets in my project every time I build, which takes minutes.
If I take out PRE_TARGETDEPS += mytarget, no message is printed and the build succeeds quickly with no changes. But I need the message to print.
I need a pre-build step to execute, but I don't want any other targets to be remade if their dependencies didn't change. How can I achieve this with qt?
You must have a file on disk to make it working:
PRETARGET = .pretarget
!exists($$OUT_PWD/$$PRETARGET):system(touch $$OUT_PWD/$$PRETARGET)
$${PRETARGET}.depends = FORCE # or $${PRETARGET}.CONFIG = phony
$${PRETARGET}.commands = #echo -e \"[\\e[1m\\e[32mTARGET\\e[0m] $$OUT_PWD/$(DESTDIR_TARGET)\"
QMAKE_EXTRA_TARGETS += $$PRETARGET
PRE_TARGETDEPS += $$PRETARGET
I have a Qmake subdirs project and in the top level .pro file, I specify an extra target like so:
gruntbuild.target = gruntbuild
gruntbuild.commands = grunt --gruntfile $$PWD/Gruntfile.js
gui.depends = lib gruntbuild
QMAKE_EXTRA_TARGETS += gruntbuild
I can see in the resulting Makefile that a gruntbuild target is correctly added, however the all target does not reference it, so gruntbuild is not being run when jom.exe is called by QtCreator.
Do I need to add an extra command to ensure the target is run?
I think this is as easy as adding guito QMAKE_EXTRA_TARGETS. In other words, use
QMAKE_EXTRA_TARGETS += gui gruntbuild
The reason is that you have to "export" the modified gui-target to the Makefile too. This will append another depend for the target, but that is apparently legal.
Is there a way to tell qmake to add to Makefile an include directive to include other Makefile.
I need at the beginning of generated Makefile added one line:
include custom.inc
Maybe there is just a way to output text to Makfiles from qmake but I could not find.
You can use the undocumented QMAKE_EXTRA_INCLUDES variable, like
QMAKE_EXTRA_INCLUDES += /path/to/your/file.mk
you can define a new target into make file and then tell what that target does:
mytarget.target = .buildfile
mytarget.commands = make -f AnotherMakeFile
QMAKE_EXTRA_TARGETS += mytarget
PRE_TARGETDEPS += .buildfile
last 2 statements add your target .buildfile to Makefile and mytarget to Qt compiling process
here you can get further info: http://qt-project.org/doc/qt-4.8/qmake-environment-reference.html
I haven't found a way to include a Makefile, but I have had a similar problem where I wanted one file to contain a common set of build variables. The solution I came up with was to use the QMake command include(filename.pro) (see QMake reference page). This causes QMake to include another project file. In my case, that contained all of the common settings.
Before compile my program ,I need to compile a 3rd party library,but it is not writen in QT ,it has a Makefile to build itself . so if I write a pro file like this:
TEMPLATE = subdirs
SUBDIRS += image myapp
(image directory is the 3rd party library)
then qmake,make
it always report "Cannot find file: image.pro"
if I write a pro file inside image, it will create a Makefile which will overwrite the original Makefile.
any suggestions?
Thanks in advance
You could try several things, depending on what you want:
Use QMAKE_MAKEFILE to rename the qmake-generated makefile so that is won't overwrite the other one.
do some fancy stuff to create something like a QMAKE_PRE_BUILD sort of thing (this variable does not exist in qmake):
makefile.target = Makefile
makefile.depends += prebuild
prebuild.target = prebuild
prebuild.depends = FORCE
prebuild.commands = #echo before build (to replace)
QMAKE_EXTRA_TARGETS += makefile
QMAKE_EXTRA_TARGETS += prebuild
Source: http://forum.qtfr.org/viewtopic.php?id=10686 (read post two and three (google translate) and keep in mind that "défaut" wich means defect gets translated as default :) )
These should be able to solve the problem you're having.
Can qmake handle dependencies of generated source files?
We have a prf file like this:
idl_h.name = Generate .H file for ${QMAKE_FILE_BASE}.idl
idl_h.input = IDLS # variable containing our input files
idl_h.variable_out = HEADERS
idl_h.commands = <command that takes .idl and genrates .h>
idl_h.output = $$IDL_GEN_DIR/${QMAKE_FILE_BASE}.h
QMAKE_EXTRA_COMPILERS += idl_h
This generation works fine and creates .h files at make time. The problem is that the input files ($$IDLS) depend on each other, and are not always built in the correct order. We have something like app.idl, containing:
#include "common.idl"
It seems the following should work
idl_h.depend_command = g++ -EE ... $$IDL_GEN_DIR/${QMAKE_FILE_BASE}.h
but apparently the depend_command is not actually executed.
Another idea would be to parse the dependencies out of the original idl:
idl_h.depends = $$system(cat ${QMAKE_FILE_IN} | grep "^#include" | sed -re 's/#include\s+["<]([^.]+)\.idl[">]/\1.h/')
but it seems my qmake syntax is failing me.
Try adding
idl_h.dependency_type = TYPE_C
to your prf, and drop the .depend_command and .depends