Generate Makefile with clean rule that removes project executable - qt

I want my QtCreator project to have a Makefile with a "make clean" rule that deletes the executable.
Normally, when making a Makefile for a simple C++ project, I would put this rule in the Makefile, where neatprogram is the executable (on Linux):
clean:
rm -f neatprogram
But QtCreator uses qmake to generate a Makefiles for me. By default, it even adds a clean rule to the Makefile! But it only removes object files and such. How can I make it so the Makefile generated by qmake also removes (deletes) the single executable file for my program?

There's a predefined target distclean which removes all generated files including an executable. But note that Makefile itself will also be removed.
Alternatively, you can define your own target like this:
myproject.pro
QMAKE_EXTRA_TARGETS += myclean
#myclean.target = myclean
myclean.depends = clean
myclean.commands = -$(DEL_FILE) $(DESTDIR_TARGET)

Related

Can I set a standard path to Qt-directory in a .pro file?

is there a way to define the path to the qt directory in a .pro file?
I've tried INCLUDEPATH += and LIB += but after qmake in the makefile always stands /usr/share/qt4 and /usr/include/qt4/ for the path to the directory where qt is installed... Maybe I could say I want to replace /usr/ with /home/ubuntu/Qt5.2.1/5.2.1/gcc or some other stuff.
What #Linville says is right. Use the correct qmake and those paths will be what you want.
Generally you should not need to set QTDIR and just running the correct qmake should work.
eg
export PATH=/home/ubuntu/Qt5.2.1/5.2.1/gcc/bin:$PATH
mkdir -p $HOME/build/myapp && cd $HOME/build/myapp
# check you have the right qmake
which qmake && qmake -query
# shadow build so as to not pollute your source tree
qmake $HOME/source/myapp/myapp.pro
If for some reason you want to refer to the paths listed by qmake -query you can use $$[QT_INSTALL_DATA] for example.
I have issue with header file not found, so I used export path before qmake which solved my problem.

QMake SUBDIRS project: How to call release-clean from top-level Makefile?

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.

What the right variable to use here, that represents the TARGET field in the .pro file

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

Remove unnecessary targets from Makefile

Is there an automated way to remove unnecessary targets from Makefile?
I used ones generated by qmake, but I am to run them on machine doesn't have QT. Since the Makefile generated by qmake, it contains QT-related targets such as 1) "Makefile:" that call "$(QMAKE)" 2) "qmake:" ; as well as QT files in dependencies, such as "/usr/share/qt4/mkspecs/common/g++.conf" and so on.
Makefile: my_project.pro /usr/share/qt4/mkspecs/linux-g++/qmake.conf /usr/share/qt4/mkspecs/common/g++.conf \
/usr/share/qt4/mkspecs/common/unix.conf \
...
$(QMAKE) -spec /usr/share/qt4/mkspecs/linux-g++ -unix CONFIG+=debug -o Makefile my_project.pro
...
qmake: FORCE
#$(QMAKE) -spec /usr/share/qt4/mkspecs/linux-g++ -unix CONFIG+=debug -o Makefile my_project.pro
I have tried to remove those targets by hand and than could successfully compile project with them. The question is if there a simple automated way?
No there isn't. If you are using qmake, it means that you want to use it on computers with qt installed. As far as i know you shouldn't share your sources with Makefile's but with .pro files only. Anyone compiling it for himself should call qmake before make (or 'nmake' if you are using visual).
If you are not using qt at all, and use only qmake to generate Makefile, then there are alternatives (although not as simple as qmake, I admit) such as cmake or autoconf/automake.

Call cmake from make to create Makefiles?

I am using cmake to build my project. For UNIX, I would like to type make from my project's root directory, and have cmake invoked to create the proper Makefiles (if they don't exist yet) and then build my project. I would like the cmake "internal" files (object files, cmake internal Makefiles, etc.) to be hidden (e.g. put in a .build directory) so it doesn't clutter my project directory.
My project has several sub-projects (in particular, a library, a user executable, and a unit test executable). I would like Makefiles (i.e. I type make and this happens) for each sub-project to execute cmake (as above) and build only that sub-project (with dependencies, so the library would be built from the executables' Makefiles, if needed). The resulting binary (.so library or executable) should be in the sub-project's directory.
I made a Makefile which does the main project bit somewhat well, though it feels somewhat hackish. I can't build specific targets using it, because my Makefile simply calls make in cmake's build directory.
Note that because the library is a sole dependency (and probably doesn't need to be build manually, and because I'm lazy) I omitted it in my Makefile.
BUILD_DIR := .build
.PHONY: all clean project-gui ${BUILD_DIR}/Makefile
all: project-gui project-test
clean:
#([ -d ${BUILD_DIR} ] && make -C ${BUILD_DIR} clean && rm -r ${BUILD_DIR}) || echo Nothing to clean
project-gui: ${BUILD_DIR}/Makefile
#make -C ${BUILD_DIR} project-gui
#cp ${BUILD_DIR}/project-gui/project-gui $#
project-test: ${BUILD_DIR}/Makefile
#make -C ${BUILD_DIR} project-test
#cp ${BUILD_DIR}/project-test/project-test $#
${BUILD_DIR}/Makefile:
#[ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}
#[ -f ${BUILD_DIR}/Makefile ] || (cd ${BUILD_DIR} && cmake ${CMAKE_OPTS} ..)
If it helps, here's my project structure (if this is "wrong" please tell me -- I'm still learning cmake):
project/
project/CMakeLists.txt
project/common.cmake
project/Makefile -- see Makefile above for this; should be replaced with something better, building libproject, project-gui, and project-test
project/libproject/
project/libproject/CMakeLists.txt
project/libproject/libproject.so -- after build
project/libproject/Makefile -- doesn't exist yet; should build libproject only
project/libproject/source/
project/libproject/include/
project/project-gui/
project/project-gui/CMakeLists.txt
project/project-gui/Makefile -- doesn't exist yet; should build libproject then project-gui
project/project-gui/source/
project/project-gui/include/
project/project-test/
project/project-test/CMakeLists.txt
project/project-test/Makefile -- doesn't exist yet; should build libproject then project-test
project/project-test/source/
project/project-test/include/
If you haven't caught on yet, I'm basically looking for a way to build the project and sub-projects as if cmake wasn't there: as if my project consisted of only Makefiles. Can this be done? Is the solution elegant, or messy? Should I be trying to do something else instead?
Thanks!
If cmake is generating the makefiles, you can simply include the generated makefile in the master makefile, eg
# makefile
all: # Default
include $GENERATED
$GENERATED:$CMAKEFILE
# Generate the makefile here`
The included files are generated then make is restarted with the new included files. The included files should detail the targets, etc.
You should be able to change the location of used files using the vpath directive, see e.g. the Gnu make manual,
vpath %.o project/.build
else the tedious way is to rewrite the rules making note of the necessary directory.
Ed:
Perhaps we shouldn't use a flat makefile.
Try something like:
# makefile
all: gui test
clean:
$(MAKE) -f $(GUI-MAKE) clean
$(MAKE) -f $(TEST-MAKE) clean
gui:$(GUI-MAKE)
$(MAKE) -f $(GUI-MAKE) all
$(GUI-MAKE):$(GUI-CMAKE)
# Generate
# Same for test
This should work if the $(MAKE) -f $(GUI-MAKE) all command works on the command line, and we've hidden cmake in the generating target. You would have to copy any other targets to the master makefile as well, and take care running make in parallel.
Propagating object files through should involve something like
%.o:$(GUI-MAKE)
$(MAKE) -f $(GUI-MAKE) $#
although you'll probably get errors trying to make test objects

Resources