How to debug a program compiled with 'make'? - linux

Tutorials for gdb suggest compiling with 'gcc -g' to compile the program with debug symbols.
However, I want to debug a program compiled with make. How can I instruct make to compile with debugging symbols?
Thanks.

In order to change your compile options you need to edit the file 'Makefile' in the directory from which you run 'make'. Inside that file look for one of the following things:
The variable which defines you compiler, probably something like:
CC='gcc'
The actual line where your compiler gets called (more likely in hand-made Makefiles).
Variables called CFLAGS or CXXFLAGS
In the first two cases, just add '-ggdb' after 'gcc', in the third case it's even easier just add '-ggdb' like:
CFLAGS='-ggdb'

The makefiles I have to deal with (created by others) frequently don't make it easy to change the options to the compiler. Simply setting CFLAGS on the command line is easy but clobbers many other important compilation options. However, you can often deal with the issues by overriding the compiler macro on the make command line:
make CC="gcc -g" ...other arguments...
You need to ensure everything you're interested in debugging is compiled with the debug flag. You might use make cleanup or make clean to clear the debris, or you might resort to simpler measures (rm *.o *.a *.so or its equivalent). Or, if you have GNU Make, then use -B or --always-make to force it to rebuild everything.
If you have multi-directory builds, you need to do this in all the relevant directories.

Related

Add linker flag during conan install

I'm working in a project that uses a number of external libraries. These libraries are included using Conan. The project is primarily written for Unix, but it also need to compile and run on Windows.
My current problem is that Windows defaults fopen() to be O_TEXT, while Unix expects this to be O_BINARY. I have a fix that works for my own code, simply include binmode.obj when linking to change this default to O_BINARY.
The problem is that this does not affect my third party libraries. Googling for this didn't turn up much, most suggestions seems to be based on where you are creating your own package and want flags added, rather than how to add flags when using other's packages.
What I have tried so far:
Make binmode.obj come before libraries, in case the linking order matters. Made no difference.
Added --env 'CL=link binmode.obj' to conan install, but this flag did not end up as part of the compile flags nor link flags.
Any suggestions for what I could try?
EDIT: I was wrong about "CL" taking no effect. This was caused by confusing output. But I did observe that CL seems to be applied for both compiler and linker, which makes it somewhat challenging what flags to give. Using "/link" prefix makes it work with compiler, but does not work with linker.
EDIT 2: More confusions... I didn't realize that the syntax of the CL value was: "<compile flags> /link <link flags>". It affected compile, but not link, however. So this environment variable apparently can't be used to make Conan add a linker flag for autotools based packages.
Hi Mats L welcome to our community!
I once had a similar problem and what I end up doing was quite hacky but quite simple also:
On my conan profile located at ~/.conan/profiles/default or any other profile actually I added an enviromental variable as such:
CXX=/usr/bin/clang++ -fms-compatibility. This one made me compile all the c++ sources with this flag (that can understand windows specific code).
So in your case you can run which c++ to find the location of your compiler
and edit the CXX environmental variable in the conan profile you use your final file will probably look like :
[settings]
os=Macos
os_build=Macos
arch=x86_64
arch_build=x86_64
compiler=clang
compiler.version=11
compiler.libcxx=libc++
build_type=Release
[options]
[build_requires]
[env]
CXX=c++ --required_flag
Some additional notes: You might also want this flag set on your CC enviromental variable .
It's preferable to not change the default profile but copy it (lets say on a file named default_edited_copy) and then invoke the other profile with conan ... --profile default_edited_copy

Is there any target on Automake that is executed before the automake Makefile rules?

I've been trying to generate Makefile rules that execute before the
automake Makefile rules. I've seen I can define "all-local" and "hooks" rules, but these are executed after the "all" and other
rules, for instance.
Is there any way that I could execute a code of mine before the
automake added rules? I want to automatically generate files in a
directory, but the compilation process through make always tries to
compile programs following automake Makefile rules. If I could add a
"pre-" rule, I could generate the needed files, then let the normal
compilation process to run.
I know about BUILT_SOURCES, but I'm trying not to use it
Is that possible?
Thanks!
There isn't a way to do this.
In general in a Makefile, if you want to do this, you should instead consider adding proper dependencies where needed.
Makefiles can have the same target with different prerequisites, in which case the prerequisites will be merged:
# The following will be equivalent to 'target: prerequisite1 prerequisite2'
target: prerequisite1
target: prerequisite2
This can be inferred from the GNU make manual (really bad explanation there, but I did not find anything better).
You can leverage this feature in your own Makefile.am:
all: all-prehook
all-prehook:
echo Prehook called here
.PHONY: all-prehook
Be careful automake will complain (Warning: overrides Automake target or something similar). You could shut it up by using -Wno-override: if your are using autoconf, just add it to your AM_INIT_AUTOMAKE call.

how can I check Linux kernel compiler optimisation level

I'm trying to verify which optimisation level (-O?) is my linux kernel built. How can I do that?
The only thing I can find is CONFIG_CC_OPTIMIZE_FOR_SIZE=y in the kernel config file. Does it imply -Os? Does it override anything (having multiple optimisations in one gcc line makes the last -O the winner)? I have found some parts of the kernel built with -O2, but too few lines for all of the kernel.
Where is such optimisation centrally set?
Note: I'm using CentOS 5.5.
Run with make V=1 and you can see the command lines in all their glory.
If your kernel config contains CONFIG_CC_OPTIMIZE_FOR_SIZE you may assume it was compiled using -Os see the kernel makefile e.g. at http://lxr.linux.no/linux+v3.12/Makefile#L573 for the place where this get set this also shows that if CONFIG_CC_OPTIMIZE_FOR_SIZE is not set that -O2 is used.
As blueshift already said, building with make V=1 forces make to display the full compiler output including optimization flags.

How to use ccache selectively?

I have to compile multiple versions of an app written in C++ and I think to use ccache for speeding up the process.
ccache howtos have examples which suggest to create symlinks named gcc, g++ etc and make sure they appear in PATH before the original gcc binaries, so ccache is used instead.
So far so good, but I'd like to use ccache only when compiling this particular app, not always.
Of course, I can write a shell script that will try to create these symlinks every time I want to compile the app and will delete them when the app is compiled. But this looks like filesystem abuse to me.
Are there better ways to use ccache selectively, not always?
For compilation of a single source code file, I could just manually call ccache instead of gcc and be done, but I have to deal with a complex app that uses an automated build system for multiple source code files.
To bypass ccache just:
export CCACHE_DISABLE=1
For more info:
man ccache
...
If you set the environment variable CCACHE_DISABLE then ccache will just call the real
compiler, bypassing the cache completely.
...
What OS? Linux? Most packaged versions of ccache already put those symlinks into a directory, for example on my Fedora machine they live in /usr/lib64/ccache.
So you could just do
PATH=/usr/lib64/ccache:${PATH} make
when you want to build with ccache.
Most packages also install a file in /etc/profile.d/ which automatically enables ccache, by adding it to the PATH as above.
If that's the case on your system, just set CCACHE_DISABLE=1 (see man ccache for more info) in your environment to disable ccache - ccache will still be run, but will simply call the real compiler.
I stumbled across this for so many times now. For me the best solution was to do this:
export CCACHE_RECACHE=1;
From the ccache manpages:
Corrupt object files
It should be noted that ccache is susceptible to general storage problems. If a bad object file sneaks into
the cache for some reason, it will of course stay bad. Some possible reasons for erroneous object files are
bad hardware (disk drive, disk controller, memory, etc), buggy drivers or file systems, a bad prefix_command
or compiler wrapper. If this happens, the easiest way of fixing it is this:
1. Build so that the bad object file ends up in the build tree.
2. Remove the bad object file from the build tree.
3. Rebuild with CCACHE_RECACHE set.
The alternative to creating symlinks is to explicitly use ccache gcc as the C compiler and ccache g++ as the C++ compiler. For instance, if your Makefile uses the variables CC and CXX to specify the compilers, you can build with make CC="ccache gcc" CXX="ccache g++" or set it up at configure time (./configure CC="ccache gcc" CXX="ccache g++").

Globally use Google's malloc?

I'd like to experiment with Google's tcmalloc on Linux... I have a huge project here, with hundreds of qmake generated Makefile's... I'd like to find a way to get gcc to globally link against tcmalloc (like it does with libc)... Is this possible? Or will I have to edit every Makefile?
(I'd prefer not to edit all the pro files as there are hundreds of them)
(Also, we've already tried the LD_PRELOAD method and it's not working quite right)...
How do your makefiles access the compiler (gcc/g++/cc/c++)?
If it's just by name (g++), and not by explicit path (/usr/bin/g++), you can simply create a replacement g++ in whatever directory you prefer, and prepend that directory to your path.
E.g.: Create a ~/mytmpgccdir/g++ file:
#!/bin/tcsh -f
exec /usr/bin/g++ -Lfoo -lfoo $*:q
Adding whatever extras (-Lfoo -lfoo) you like, either before or after the other arguments ($*:q).
Then pre-pend it to your path and make normally.
#tcsh version
% set path = ( ~/mytmpgccdir/ $path:q )
% make clean
% make
p.s. If it is by explicit name, you may be able to override it on the command line. Something like: make all GCC=~/mytmpgccdir/gcc
p.p.s If you do use LD_PRELOAD, you might want a script like this to setenv LD_PRELOAD before running your program. Otherwise it's easy to wind up LD_PRELOAD'ing on every command like /bin/ls, make, g++, etc.
First, check the qmake documentation. There is an easy way to specify (in a .pro file) that a certain library should always be linked in.
Also, since you are just experimenting, simply use LD_PRELOAD - no recompilation necessary:
LD_PRELOAD="/usr/lib/foo/libtcmalloc.so" ./your_program
You do not have to have linked "your_program" against google's tcmalloc library.

Resources