4

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?

Community
  • 1
  • 1
Jaa-c
  • 5,017
  • 4
  • 34
  • 64
  • 1
    here is [same old question](https://forum.qt.io/topic/2507/qmake-automatically-running-a-command-after-qmake-generates-makefile/4), but without answer. IMO it would be best if you explain why you need this strange feature? Maybe there is an alternative solution? For example `cmake` instead of `qmake`. – Marek R Oct 26 '15 at 18:03
  • 1
    Why not just have a shell script/batch file that runs qmake and then your script? – MrEricSir Oct 26 '15 at 18:06
  • @MarekR: I'm working on a [unity build](http://buffered.io/posts/the-magic-of-unity-builds/) for quite a large project - I need to include all cpp files into one file and only this one file is built. But I also want to include generated moc files, but I don't know if it's possible to know all the moc files before qmake is run. – Jaa-c Oct 26 '15 at 19:29
  • @MrEricSir: It's a big project and it would be currently quite complicated to switch everything from qmake to running some script file. – Jaa-c Oct 26 '15 at 19:31
  • @Jaa-c I think what MrEricSir means is, you are at some point executing 'qmake project.pro', so why not make it 'qmake project.pro && python ./test.py'? – RedOctober Oct 26 '15 at 20:58
  • 1
    @RedOctober: I get that, it's possible, but not very maintainable. Qmake is being run from ide, automated builders, different scripts etc. I would have to change all those cases, which I'd like to avoid, if possible. – Jaa-c Oct 26 '15 at 21:07
  • Since qmake's job is to generate the Makefile, it is unlikely that you can modify it in a safe and maintainable way during the qmake run. Could you tell us what your Python script is doing to the Makefile? Maybe you can achieve the same with qmake commands – Simon Warta Oct 26 '15 at 21:35
  • @SimonWarta: The script is used for [unity build](http://buffered.io/posts/the-magic-of-unity-builds/) - it's creating a single cpp file, which includes all other cpp files (also need to include moc files). Then only this one cpp file is built. I could easily achieve this with qmake without the moc files, but have no idea how to do it with them. – Jaa-c Oct 26 '15 at 21:45
  • @Jaa-c Okay so this is basically an amalgamation script. I would not do that in a development environment because you'll need to re-compile your entire project every time you change a single character in a single source file. Amalgamations only make sense when your're done developing and want to export your project for someone else who than indeed has shorter compile times but only because he does not change the code anymore. – Simon Warta Oct 26 '15 at 21:59
  • @Jaa-c You could use qmake to write the amalgamation and a custom Makefile to a separate folder at `make` time. This way you can use the default unchanged Makefile for development and copy the amalgamation folder for other uses. This can be done using an extra target that depends on the moc target. – Simon Warta Oct 26 '15 at 22:07
  • @SimonWarta Thats true, but the project is modular, it's split to many subprojects, so incremental build is not always so bad. In some situations, this can save half an hour of waiting for build. – Jaa-c Oct 26 '15 at 22:09
  • @Jaa-c Isn't amalgamation the exact opposite of "incremental builds"? – Simon Warta Oct 26 '15 at 22:14
  • @SimonWarta Not exactly. The single cpp file is generated for each subproject, so if you change one cpp, you only rebuild one subproject, which doesn't take that long. But if you're working on a header, that causes rebuild of a larger part of the project (unfortunately we have those), this kind of build can save significant amount of time compared to standard build. – Jaa-c Oct 26 '15 at 22:26
  • @Jaa-c Okay then call moc yourself (moc mywindow.h -o mywindow.moc) for every .h file in your project. You can even write it directly to your amalgamation while generating it. Then you don't need qmake at all because you're going to do dependency generation yourself (amalgamation depends on all .cpp and all headers). One more thing: Qt Creator does not run qmake every time you hit the run button. It is just not made for what you are trying to do. So don't get lost. – Simon Warta Oct 26 '15 at 23:24

3 Answers3

3

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.

Jaa-c
  • 5,017
  • 4
  • 34
  • 64
1

The following has worked well for me for several years.

  1. Create a .cmd or .sh script that invokes qmake, and then your script:

    %QTDIR%\bin\qmake %* python.exe test.py

  2. Save the script where it can be found via the PATH environment
  3. In your .pro file add the following:

    QMAKE_QMAKE = myqmake

  4. 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.

Jason
  • 389
  • 2
  • 6
-1

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.

Simon Warta
  • 10,850
  • 5
  • 40
  • 78
  • Thanks, but I don't want to use cmake only for this. Also, my version of scu is a little more complex that just one big single compilation unit... – Jaa-c Dec 22 '15 at 14:19