GNU make --jobs option in QMAKE - qt

I am using qmake to generate MinGW32 Makefiles for a small Qt C++ app we are developing. My problem: all those dual/quad core CPUs are sitting there idly while only one thread is doing the building. In order to parallelize things I tried passing --jobs 4 to make, but the problem is that qmake generates a generic makefile inside of which make gets called again with -f .
Is it possible to force qmake to add options to make when generating the makefile? Or maybe there's another way of setting the option outside of qmake altogether? I can't edit that specific Makefile since it's autogenerated each build.

Abusing $MAKE to pass options does not work in all cases. Oftentimes, (e.g. in the configure script of Qt on Unix), it's enclosed in double quotes ("$MAKE") to allow the command to contain spaces. I know because I used the same trick before it stopped working. Qt Support then suggested (rightfully) to use $MAKEFLAGS as in
set MAKEFLAGS=-j4
make

This works for me:
set MAKE_COMMAND=mingw32-make -j%NUMBER_OF_PROCESSORS%

The generic Makefile uses $(MAKE) when invoking make, so you can overwrite it using environment variables. Something like this should do it:
qmake
make MAKE="mingw32-make -j4"
Replace the values of MAKE as required of course :)

Related

How to pass cmake arguments using Qt Creator interface and settings

I'm trying to figure out how to use Qt Creator's settings and pass some CMake arguments. Let's say I have an app which I can build using the terminal like so:
cmake .. -DQTDIR=/home/myCustomBuildStuff
-DLD_LIBRARY_PATH=/home/myCustomBuildStuff
-DCMAKE_INCLUDE_PATH=/home/myCustomBuildStuff/include
# etc.
As you can see, I'm using my custom built Qt (plus some other libs). When I build using the terminal, everything works.
But now I want to try to use the Qt Creator and pass all the CMake arguments by using the Qt Creator settings.
I tried to use the CMake Configuration settings that can be found in the Kits. I tried to modify the Build Settings, and add my arguments directly to the Build Steps and/or CMake table above. None of that helps and my app fails to include my custom built QtWidgets from main.cpp:
/usr/lib/x86_64-linux-gnu/libQt5Core.so.5:-1: error:
version 'Qt_5.9' not found (required by home/myCustomBuiltStaff/bin/uic)
In the error above the path is obviously wrong (it needs to search in /home/myCustomBuiltStuff/ folder). But how do I pass that path by using the Qt Creator settings?
Note, I cannot touch the content of the CMake file and only want to make it to build as it builds in my terminal when I pass all the paths as arguments to CMake.
So I followed an advice given in the comment, and had to add my own custom build steps in order to make sure I have the wanted CMake arguments passed correctly. I could not find any other way to pass them by using Qt Creator's settings and menus.
This is the list of steps I did:
Go to Projects and chose the Build to edit. If you have several configurations, you will have to repeat the below steps for each.
Disable or delete the default CMake step, normally it would be something like cmake --build . --target all
Chose your Build directory.
Add new Custom process step with Command to be cmake, Arguments to be your CMake arguments; normally you'd leave the Working directory to default.
Add new Custom process step with Command to be make and add any necessary arguments (e.g. LD_LIBRARY_PATH).
Go and edit the Run settings: make sure the Executable points to the one your cmake and make just created. There you can also add any necessary command line arguments.
This is version 4.3.1 I am using. If not yet done you should have the most updated version of qtcreator.
File->Open:
Choose the CMakeLists.txt file of your project. Select your target and you should be able to get the project open at least.
Now click on "Projects". Assure you have selected Build & Run -> Build and under Cmake click on "Add" -> "String" or "Directory". In your case Directory make more sense. On the left you put the define, without "-D" of course and right side the value.
Repeat the step for every variable you want to define and click on "Apply"
If that does not work I would try to set the CMAKE_EXE_LINKER_FLAGS to -L/home/myCustomBuildStuff
Hint: To see if it worked you can pass VERBOSE=1 parameter to toolparameters if you are using makefiles under the section Build steps. That way your output will show if the variable were really passed.
Hint: Remeber to activate the "Advanced" selection so you see more if not all the variables defined fo Cmake.

qmake touch function on windows

The qmake manual documents a touch function to update the time stamp of a file, see: touch(filename, reference_filename). It is recommended here to update the timestamp on a file, e.g.:
version.commands = touch $$version.target
Note: the qmake manual documents two parameters, e.g.:
version.commands = touch $$version.target $$version.depends
However, I can't get the touch function to work on Windows using either call. I suspect that qmake is simply calling the linux touch command, since it works fine on Fedora 23.
A workaround is to create a touch.cmd command file on Windows, e.g.:
#COPY /B %1+,, %1
and use the following in the .pro file:
version.commands = $$system(touch $$version.target)
But I would prefer to use the qmake touch function...
What is the correct way to invoke it in a .pro file so that it works on Windows?
In using qmake, it's critical to remember what things are happening on invocation of qmake and what's happening during the subsequent make/nmake call.
Anything that's specified after version.commands = is going to be executed when make gets invoked.
On the other hand, touch() is a qmake function that will get invoked when you run qmake.
Looking in the Qt source code dev branch as of today, there are just 4 uses of touch() within Qt itself, all in the qtbase/mkspecs/features directory, and none in the context of a .commands construct.

CMake macro to only run lupdate

For a couple of reasons we need the ability to run lupdate on our sources, run a script on the resulting ts files, and then run lrelease. We're using CMake for our builds so a CMake macro would be nice.
But the only ones I see either just run lrelease, or run lupdate followed by lrelease. Is there one I'm missing to just run lupdate?
Thanks.
You should use this guide:
https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/How-To-Build-Qt4-Software
You could add some options in CMake to call only 'lupdate' depending on your requirements.
Note that QT4_ADD_TRANSLATION must be changed to QT5_ADD_TRANSLATION if you are working with Qt 5.

Change gcc compiler executable name in BJam

How to change compiler executable name? I want to perform a "fake build" of some products which are using BJam as build system. (For example: the Boost itself) In this "fake build" I want some special command to be called instead of g++. (with all the options and environment used in real build with real gcc).
How to perform this? Are there any command line switches which already allows me to do what I need or maybe I can somehow modify *.jam files to achieve what I need?
The easiest thing might to just switch your path so gcc refers to what you want to run. Otherwise, the correct way to do it bjam is more finicky. I've never gotten it to successfully, easily work, but here's what the docs suggest:
You'll need to add command to the Jamroot of your project to configure the gcc mocking command. The simplest way is just:
using gcc : : my-gcc ;
But most likely you have another using gcc ; line somewhere in your jam rules (or site-config.jam) and you'll get a complaint about trying to reinitialize a toolset. If so, you'll need to give an explicit version to the toolset like so
using gcc : mywrapper : my-gcc ;
And to use this toolset when compiling use the command bjam toolset=gcc-mywrapper.
Good luck.

tool for building software

I need something like make i.e. dependencies + executing shell commands where failing command stops make execution.
But more deeply integrated with shell i.e. now in make each line is executed in separate context so it is not easy to set variable in one line and use it in following line (I do not want escape char at end of line because it is not readable).
I want simple syntax (no XML) with control flow and functions (what is missing in make).
It does not have to have support for compilation. I have to just bind together several components built using autotools, package them, trigger test and publish results.
I looked at: make, ant, maven, scons, waf, nant, rake, cons, cmake, jam and they do not fit my needs.
take a look at doit
you can use shell commands or python functions to define tasks (builds).
very easy to use. write scripts in python. "no api" (you dont need to import anything in your script)
it has good support to track dependencies and targets
Have a look at fabricate.
If that does not fulfill your needs or if you would rather not write your build script in Python, you could also use a combination of shell scripting and fabricate. Write the script as you would to build your project manually, but prepend build calls with "fabricate.py" so build dependencies are managed automatically.
Simple example:
#!/bin/bash
EXE="myapp"
CC="fabricate.py gcc" # let fabricate handle dependencies
FILES="file1.c file2.c file3.c"
OBJS=""
# build link
for F in $FILES; do
echo $CC -c $F
if [ $? -ne 0 ]; then
echo "Build failed while compiling $F" >2
exit $?
fi
OBJS="$OBJS ${F/.c/.o}"
done
# link
$CC -o $EXE $OBJS
Given that you want control flow, functions, everything operating in the same environment and no XML, it sounds like you want to use the available shell script languages (sh/bash/ksh/zsh), or Perl (insert your own favourite scripting language here!).
I note you've not looked at a-a-p. I'm not familiar with this, other than it's a make system from the people who brought us vim. So you may want to look over that.
A mix of makefile and a scripting language to choose which makefile to run at a time could do it.
I have had the same needs. My current solution is to use makefiles to accurately represent the graph dependency (you have to read "Recursive make considered harmful"). Those makefiles trigger bash scripts that take makefiles variables as parameters. This way you have not to deal with the problem of shell context and you get a clear separation between the dependencies and the actions.
I'm currently considering waf as it seems well designed and fast enough.
You might want to look at SCons; it's a Make-replacement written in Python.

Resources