Qmake debug_and_release conflict in unix makefiles
-
I have the following qmake project which is configured as debug_and_release.
When I generate the makefiles, I get the following output files.
The project generated unix makefiles for a shared library.Project.pro Makefile-linux-x86-g++ Makefile-linux-x86-g++.Debug Makefile-linux-x86-g++.Release
My problems begin when I try to compile the debug version at the same time as the release version.
I get truncated output files when I compile both versions at the same time.I properly set the following variables in order to specify different output directories based on the debug or release configuration:
- OBJECTS_DIR
- MOC_DIR
- UI_HEADERS_DIR
- RCC_DIR
- TRANSLATION_DIR
- DESTDIR
I ended up finding that the temporary library and its symlinks are created in the current folder before being copied over to the DESTDIR. This creates a clash when the dbg and the rls version of the following targets are executed at the same time:
all: Makefile-linux-x86-g++.Release ../../../output/linux-x86-g++/rls/$(TARGET) ../../../output/linux-x86-g++/rls/$(TARGET): $(OBJECTS) $(SUBLIBS) $(OBJCOMP) @$(CHK_DIR_EXISTS) ../../../output/linux-x86-g++/rls/ || $(MKDIR) ../../../output/linux-x86-g++/rls/ -$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) $(OBJCOMP) -ln -s $(TARGET) $(TARGET0) -ln -s $(TARGET) $(TARGET1) -ln -s $(TARGET) $(TARGET2) -$(DEL_FILE) ../../../output/linux-x86-g++/rls/$(TARGET) -$(DEL_FILE) ../../../output/linux-x86-g++/rls/$(TARGET0) -$(DEL_FILE) ../../../output/linux-x86-g++/rls/$(TARGET1) -$(DEL_FILE) ../../../output/linux-x86-g++/rls/$(TARGET2) -$(MOVE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) ../../../output/linux-x86-g++/rls/
I am using qmake from qt 4.8.4. I looked at the code of qmake in 5.7 and the routine that generates this piece of makefile does the same job as the 4.8.4 version.
Has anyone found a clean way of specifying a temporary output folder for the link and symlinks commands?
Thank you!
-
Hi and welcome to devnet,
The current method to build projects is rather to use "shadow builds" folders, one for each type of build. This avoids clashes and leaves the source tree clean.
-
Our build system is quite complex and mature. Introducing the concept of shadow builds could be challenging in the short term.
I didn't find any qmake documentation about shadow build. Would you happen to know a good source of information on how to implement that?
Another point, when using debug_and_release and shadow build, won't I get the same problem where the debug and the release makefiles will be generated in the same folder and will use it as a temp folder to generate the shared object lib and its symlinks? I understand that the makefiles are going to be generated outside of the source tree, but how would that fix this particular problem?
Thank you!
-
Basically:
mkdir myproject_build_release myproject_build_debug pushd myproject_build_release qmake ../myproject CONFIG+=release make -jX where X = 2 * core + 1 popd pushd myproject_build_debug qmake ../myproject CONFIG+=debug make -jX where X = 2 * core + 1 popd
-
Just building on what @SGaist said, the basic issue in my opinion is that qmake's
DESTDIR
default value is platform dependant, and on Linux uses the same directory for both debug and release builds (so those builds clash), whereas, for example it defaults to separate directories on Windows (and Mac OSX if I recall correctly).To get around that (and generally provide more consistent output, which helps with CI tests and such), I like to do this in my
*.pro
files:CONFIG(debug,debug|release): DESTDIR = debug CONFIG(release,debug|release):DESTDIR = release MOC_DIR = $$DESTDIR/$$TARGET-tmp OBJECTS_DIR = $$DESTDIR/$$TARGET-tmp RCC_DIR = $$DESTDIR/$$TARGET-tmp
Then, instead of running qmake twice as @SGaist showed above (which works too), I do:
mkdir myproject_build pushd myproject_build qmake CONFIG+=debug_and_release ../myproject make all popd
Of course, the difference is just a matter of personal preference :)
One small tip: you can skip the pushd and popd commands by using qmake's
-o
and make's-C
options (handy for keeping build scripts neat and tidy) such as:mkdir -p some-new-build-dir qmake -o some-new-build-dir CONFIG+=debug_and_release project-dir make -C some-new-build-dir all
Unfortunately, Windows' nmake.exe has no
-C
equivalent :(Cheers.
-
Thank you guys for your answers!
Paul, I am already setting the DESTDIR differently for debug and release builds. Unfortunately, The piece of generated makefile I posted doesn't execute in the DESTDIR. It executes where the makefiles were generated, thus the clash in the symlink commands. But thanks for the tips!If I understand correctly, if I want to fix this, I need to build release and debug in different makefiles tree using shadow builds.
This would change the structure of our projects a lot for now. I won't be able to implement that without affecting a whole bunch of other scripts relying on the current build structure. I think that qmake should have used a unique tmp folder for performing this symlink creation operation. This really looks like a bug in the unix makefiles generation for shared objects.Thank anyway guys!