Qt Creator: technical differences between Release and Debug builds - gdb

A bunch of questions concerning the build process using QtCreator:
In QtCreator, you can differ between a Release, a Debug and a Profiler build. C. f. the following image:
What do these things exactly (!) do? I was not able to find and answer in the internet.
Especially, I am interested in whether the Debug mode adds the item "debug" to the qmake variable "CONFIG", the "-g" switch to ask g++ to add debugging information for gdb (my debugger) etc.
Which debugger is meant by "CONFIG += debug": the "normal" debugger GDB (in my case) or the QML Debugger?
Why is it so common to use "+=" in the project file and not "*="? The second variant does not add an item to the qmake Variable if it is already present. Does this mean that multiple equal items in the qmake special variables are harmless?
Many thanks in advance!

You can see what they do by observing the qmake command line that gets invoked in the "Compiler Output" window pane:
Release: qmake MyProject.pro "CONFIG+=qtquickcompiler"
Debug: qmake MyProject.pro "CONFIG+=debug" "CONFIG+=qml_debug"
Profile: qmake MyProject.pro "CONFIG+=qml_debug" "CONFIG+=qtquickcompiler" "CONFIG+=force_debug_info" "CONFIG+=separate_debug_info"
gdb has no -g option, did you mean gcc? The effect of CONFIG+=debug is to pass the -g option to gcc, as you can see from this line in Qt/mkspecs/common/gcc-base.conf:
QMAKE_CFLAGS_DEBUG += -g
Compiling a debug build just means your compiled libraries and executables will be unoptimised and contain extra information useful to debuggers. There is no requirement to execute in a specific debugger, or indeed any debugger at all. You could also run a release build in a debugger, although you might find the results less reliable.
Multiple equal items in qmake special variables are usually harmless, and in the case of CONFIG they can even be meaningful. For example, it is legal for CONFIG to contain both debug and release. In this case, the last one in the list will take effect. Consider the difference between += and *= in the following examples:
CONFIG = debug
CONFIG += release
CONFIG += debug # now CONFIG = debug release debug, so debug is the effective mode
CONFIG = debug
CONFIG += release
CONFIG *= debug # now CONFIG = debug release, so release is the effective mode
There is another reason why *= might not be favoured on the command line: many shells will treat any argument containing * as a file glob/wildcard to be expanded unless it is escaped or quoted.

Related

Makefile deferred compilation

I have a simple makefile with a variable for the compiler flags, it also contains some targets that modify that variable and append some flags.
My point with it is to be able to run, for example:
make debug perf
that would in turn add to the variable the flags required to build under that configuration. The problem is that if I run it, it does compile the executable with the debug info, and then tries to compile with the performance tools, and obviously does nothing. Can make only execute the compilation step after both targets run?
Makefile:
CFLAGS = -std=c11 -Wall -pedantic -D_GNU_SOURCE
executable: gcc $(CFLAGS) main.c -o exe
debug: CFLAGS += -g
debug: executable
perf: CFLAGS += -D__PERF__
perf: executable
Make version 4.2.1
One approach is to have different executable files for different flag combinations, ie
executable # default to release build
executable.dbg # with -g
executable.perf # with -D__PERF__
executable.dbgperf # with both
The two advantages are
you're never unsure how some executable file was built, and you never accidentally test the wrong thing / waste time trying to debug something with no debug symbols, etc.
Make's file dependency logic actually works correctly
This does assume you have a manageable number of flag combinations. If there are too many, the profusion of targets may make your Makefile impractical.
I exactly have the same requirements! :-) As this, I compile my executables with all the options in the filename like: myprog-debug-coverage and so on. All the object files goes to a directory like build-myprog-debug-coverage as example. All this has the advantage that there is no need to recompile all if you need it once for debug, do a change and compile for coverage and after next change for debug again.
The first thing you must do is to filter out all non-targets which are needed for the options like debug with:
debug:
#:
to simply do nothing.
In addition, you filter out the non-targets with something like:
export FOUND_ACTIONS=$(filter $(ACTIONS), $(MAKECMDGOALS))
and process these variables later on into the flags you need for compilation like:
$(eval $(call CHECK_FOR_CMDGOAL,debug,export LCXXFLAGS+= -DDEBUG -DGDB_HELPER -g,build_dir_ext=$(build_dir_ext)-debug))
and after that you can write your standard recipes with the found flags from the variables.
I can't give you a ready to use Makefile here as my one is a bit larger while processing a lot of flags like different compilers, memory debug libraries as efence, build for coverage and much more.
I'm in hope that you can catch the idea how to process the pseudo targets for flags and the real targets and how a Makefile can split both.
And yes, that is not how a Makefile works typically. But I believe it is really convenient at the end of the day. Giving manual CXXFLAGS and so on did not the job, as you as a user have a complete list of flags, libs and options on the comand line, which is a nightmare.
This makes no sense to me. Why would you want to compile file(s) as debug, generating a program executable that is built with debug, then in the same make command recompile the same file(s) with optimization, generating a program executable that is built with optimization.
In a single directory there can be only one file named executable, so how can you build the same file twice and have two different versions at the same time? How do you intend to run the debug executable versus the perf executable?
You either need to build different files, or you need to build them into different directories (one for debug and one for perf). I recommend the latter.
But to answer your specific question: it is not possible in make to build the same target multiple different times in the same invocation of make. Once a single make invocation tries to build a target named foo, it will never try to build that target again no matter how many other targets might list it as a prerequisite. If you re-run make again, it will try again to build foo (one time).

Build multiple versions of a binary with qmake

I want to build two versions of my program, a "normal" version, and one in which the address sanitizer has been activated. As of now, I have this in my QSoas.pro
sanitizer {
message("Activating the address sanitizer code")
OBJECTS_DIR = build-snt
QMAKE_CXXFLAGS += -fno-omit-frame-pointer -fsanitize=address
LIBS += -fsanitize=address
TARGET = $$join(TARGET,,,-snt)
}
This way, I can do:
~ qmake
~ make
to get the normal version, and
~ qmake CONFIG+=sanitizer
~ make
to get the version with the address sanitizer.
This is fine, but a little cumbersome, especially since I need in fact many other configuration options on the qmake command-line. Is there a way to have two targets, so that I could simply run
~ qmake
~ make
~ make my-sanitized-exe
The most natural way, IMO, is an out-of-source build. That is, create a subdirectory called "sanitizer", go into it, and build your Makefile(s) the same way you do it with cmake, meson etc.:
mkdir sanitizer
cd sanitizer
qmake CONFIG+=sanitizer ../Qsoas.pro
QMake natively supports out-of-source builds, so everything should be fine. However, if you need to distiguish between the source and build directories, you can use the variables $$PWD and $$OUT_PWD.
See also qmake's manual for shadowed() function to translate the paths automatically.
This is my proposal on how you can achieve the desired behavior. The idea is using two (or more) different Makefiles that will tell the make tool what to do. To create a set of Makefiles I would do this (roughly):
~ qmake -o ./normal/Makefile
to create a normal version, and:
~ qmake CONFIG+=sanitizer -o ./sanitizer/Makefile
to create a Makefile for sanitizer.
Now, if I want to build a normal version I call:
~ make -f ./normal/Makefile
and
~ make -f ./sanitizer/Makefile
to build an alternative version.
Hopefully this will work.

In CMake, how do you change default compiler flags for a build type on a per-user basis? [duplicate]

This question already has answers here:
Change default value of CMAKE_CXX_FLAGS_DEBUG and friends in CMake
(2 answers)
Closed 5 years ago.
In cmake, the default release compiler flags for gcc are -O2 -DNDEBUG. I want them to be -Ofast -NDEBUG. And I want that to be true for every project I do things with in cmake without imposing that choice on any other consumers of my project.
How do I do that?
I could edit them into that project's CMakeLists.txt file. But then I'm forcing other people to agree with my choice. Also, I have to be really careful about how I do it to make sure that I only affect compilers for which that is a valid set of flags to use.
I could use ccmake on every project every time I check out a new tree or create a new build environment. But that's a huge hassle when I want to set the flags to the same thing every time.
Is there a way to set it up so that for me, personally, the default compiler flags for clang and gcc for the various build types are what I want them to be?
Similarly, it's noticing I have ccache and gcc. And that's fine. But it might be nice to force a different default choice for compiler as well, but just for me personally, not for anybody else who chooses to use my project.
Is this possible?
I normally set compiler flags in cmakelists.txt by adding an environment variable into my build script, then referencing that in cmakelists.txt.
#build.sh
export MY_CXXFLAGS="-std=gnu++11 -Ofast -NDEBUG -Wall -Wno-unused-function -Wno-unknown-pragmas"
cmake `pwd` -Dtest=ON
make -j9
Then in my CMakeLists.txt, I'll have the following line:
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{MY_CXXFLAGS}")
It's simple then to pass arguments to build.sh, which is just a bash script, to change the content of MY_CXXFLAGS, based on the users needs. (E.g. build.sh -b DEVELOP|DEBUG|RELEASE etc).
My current answer to this question is to create a global ~/.config/Kitware/default.cmake file that contains initial cache settings and to use cmake -C <path to default.cmake> ... remainder of cmake options ... to run cmake.
In the process of figuring this out I initally named the file ~/.config/Kitware/CMakeCache.txt and found something quite odd that appears to be a bug in cmake. I posted this question about it: Why does this cmake initial cache file result in such strange errors?

Qt Creator error endless loop

When I try to create a project which was developed by someone working in a different country and timezone I keep getting the following error in my console. He had mentioned this problem is because of the Data/Time being different from his computer to mine. I'm not sure if that is true, if it is, there has to be a solution for that without having to change my computer time to match his. I'm not sure what else to post that would be helpful in trouble shooting this, if there is just let me know and I'll update. I'm a bit new to C++/Qt Creator. Why is this happening. It seems to never finish, it just endlessly prints this to the console.
Compile Output Console
Running steps for project Nexus...
Configuration unchanged, skipping qmake step.
Starting: "C:\Qt\Tools\mingw492_32\bin\mingw32-make.exe"
C:\Qt\5.5\mingw492_32\bin\qmake.exe -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" -o Makefile ..\Nexus\Nexus.pro
C:\Qt\5.5\mingw492_32\bin\qmake.exe -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" -o Makefile ..\Nexus\Nexus.pro
C:\Qt\5.5\mingw492_32\bin\qmake.exe -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" -o Makefile ..\Nexus\Nexus.pro
C:\Qt\5.5\mingw492_32\bin\qmake.exe -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" -o Makefile ..\Nexus\Nexus.pro
General Message Output Console
Warnings while parsing QML type information of C:/Qt/5.5/mingw492_32/qml:
<dump of C:\Qt\5.5\mingw492_32\qml>:1:24: Reading only version 1.1 parts.
<dump of C:\Qt\5.5\mingw492_32\qml>:10:5: Expected only Component and ModuleApi object definitions.
Pro file
#-------------------------------------------------
#
# Project created by QtCreator 2016-02-29T21:37:32
#
#-------------------------------------------------
QT += core gui xml
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
include(core/core.pri)
include(node/node.pri)
include(librarybox/librarybox.pri)
include(blockeditor/blockeditor.pri)
include(propertyeditor/propertyeditor.pri)
include(lib/lib.pri)
TARGET = Nexus
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui \
virtualnamepropertyitem.ui
RESOURCES += \
nexus_resources.qrc
RC_FILE = nexus.rc
This can happen if your .pro file (or any other file) has a timestamp from the future. The Makefile generated by qmake contains a rule that will generated the Makefile anew when its older than the .pro file. Since the new Makefile is still older than its counterpart from the future, this will go on till you actually reach the correct time.
There are two ways to get rid of this behavior:
Wait till the .pro file's timestamp is in the past (not recommended)
Edit the .pro file. Even a trivial edit like a new comment should be enough.
Had the same problem with latest version of QtCreator (3.6.1 with Qt 5.6.0).
Answer proposed by "Zeta" did not help.
Disabling "Shadow build" in project options fixed the problem for me. That's a good workaround.
Finally shorten file names (somes where huge) to fix the issue:
Shortened project names (.pro) (file name and path, removed a few caracters)
Shortened resources names (.qrc) (file name and path, removed a few caracters)
Issue then disappeared (even with shadow build, it's probably related as shadow-builds are using an output folder with a very long name).
There's apparently a bug when file paths are too long (>~170, found a post on a forum reporting that).
An alternative is also to change the pattern used by QtCreator for shadow builds. This can be modified from the QtCreator options and you can then make the name shorter, this is another way to quickly and easily fix the issue.
I wrote a python script that loops through recursively through all the files of the project and simply just resaves the files. That updated the timestamp and corrected the QMake Infinite loop. It now compiles correctly.

Why doesn't GDB recognize my library's symbols?

I have a project hierarchy similar to the following:
src/
code.c
ext/
lib/
lib.c
lib.a
bin/
bin-code (+x)
obj/
code.o
lib.c compiles into lib.a using the -g2 flag and then ar.
code.c compiles into bin/obj/code.o using the -g2 flag.
lib.a and code.o are then linked into binary bin-code.
I'm facing a bug within bin-code and I'm trying to use GDB to load the symbols/source for lib so I can examine it with TUI.
I'm adding a breakpoint for a function inside lib.c, which it seems to find as it echos out an address and says it successfully set the breakpoint.
When I run the program and hit the breakpoint, I open TUI with CtrlX / CtrlA, but it claims no source could be found.
Two things worth mentioning:
I have used set substitute-path due to the fact my build system (Tup) uses a FUSE filesystem to enforce read/write operations.
I have tried adding directory entries to the search paths, to no avail.
Am I missing something here? Is there a command I can issue GDB in order for it to rescan directories or something? I can't get the library's source to show up, even though it appears symbols have been loaded.
Most likely gdb fails to find sources of you static library and can't show it's source code.
This may happen if binary was moved to another machine after it was built or sources were moved to another directory. In this case you should properly set substitute-path. You can see where gdb tries to find sources of static library (lib.c) using info sources command. Compare this path with the one where lib.c is actually located and this should help to set proper path substitution.