CPPFlags in config.mk - linux

In Arch Linux PKGBUILD for surf browser, there is:
sed -i 's/CPPFLAGS =/CPPFLAGS +=/g' config.mk
sed -i 's/CFLAGS =/CFLAGS +=/g' config.mk
sed -i 's/LDFLAGS =/LDFLAGS +=/g' config.mk
Why must the flags be changed from
CPPFLAGS = -DVERSION=\"${VERSION}\"
to
CPPFLAGS += -DVERSION=\"${VERSION}\"
I've looked into google, but don't see anything there about this. Can someone please explain and tell me where to read more about these flags?

I did quite a lot of googling and found that this pattern (Surf's is here) seems fairly common in Arch Linux PKGBUILD files. Another example was in DWM's PKGBUILD.
Obviously it is patching the config.mk file so that when make is called, the values are appended to the flags instead of overriding the flags (which must already be set elsewhere). So there must be existing settings that need to be retained. This seems to just be done by default by the package builders so it was hard to find the reason.
Looking further I found this bug report relating to DWM's config.mk file, where the author notes that a version of that file was overriding flags set in makepkg.conf which is the main configuration file for makepkg, which allows tuning compilation settings per machine. This seems like a reasonable explanation for what you found. From that page, a default value for CFLAGS would be something like this:
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe"
So the patched config.mk file would result in the following when building the package:
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -std=c99 -pedantic -Wall -Os -I. ....."

Related

How do I correctly link a shared object (.so file) in a makefile when cross-compiling?

I have some C++ code on an openSuse platform that I need to compile to be executed on a different linux-based target. Part of the code is a dynamic library libfoo.so. I compile everything with make and then copy the compiled executable prog together with the libfoo.so to the target. When I then run the executable, I get some errors indicating the libfoo could not be initialized. I've tried everything I could find to tell the executable where it can find the libfoo.so but I still get the error.
Could anybody tell me what I am doing wrong here? I feel like it could be an error in the Makefile.
I am very new to C++ and using Makefiles in general, and on top of it all, the target runs kind of a proprietary linux version, so I cannot provide much information about it. I do have the appropriate compiler for it though.
My directory structure on the openSuse platform:
|src
|--Foolib
|----foolib.h
|----libfoo.so
|--Otherlib
|----otherlib.h
|----otherlib.hpp
|---+OtherlibSrcDirectory
|--bar.cpp
|--bar.h
|--Makefile
Directory structure on the target:
|program
|--libfoo.so
|--prog
My Makefile:
LIBS = -LFoolib -lfoo
INC = -I OtherLib -I Foolib
CXXFLAGS += -lpthread -std=c++11 -D_GLIBCXX_USE_NANOSLEEP $(INC)
LDFLAGS = '-Wl,-rpath,$$ORIGIN'
SRC_FILES = bar.cpp
OBJ = $(SRC_FILES:%.cpp=%.o)
prog: $(OBJ)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIBS) -o $# $^
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(LIBS) -c $<
Basically, bar.h includes Foolib/foolib.h as well as Otherlib/OtherlibSrcDirectory and bar.cpp includes bar.h. Then some functions from foolib.h are called in bar.cpp and they return error values. If necessary I can provide some more insights into the code but I'll leave it out for now to keep it a bit shorter.
Any help would be highly appreciated!
Found my mistake.
libfoo.so was already on the target machine and it was located in the correct folder (/lib). My program had been able to find it without problems.
My mistake: I executed my program on the target machine without root permissions.
Without root permissions, I am not allowed to initialize Foolib.
sudo ./prog fixed everything.

Using two or more optimize option with GCC command

I am trying to compile a opensource component from source code. I am compiling all C files in that component using gcc command.
When I pass options in order -O2 -Os, binary is in few KB's. But when I pass options in order -Os -O2 binary size is large.
I do know that order matter in case of including sub-directories or Linking libraries in gcc command.
Why order matters for optimization arguments of gcc command ?
I am using gcc version 4.9.1.
Because it's just using the last1 option it sees.
1. From the man page: If you use multiple -O options, with or without level numbers, the last such option is the one that is effective.
From the GCC man page:
If you use multiple -O options, with or without level numbers, the last such option is the one that is effective.
You can't combine -O2 and -Os on the command line.
But here's the description of -Os:
Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.
Looks like -Os is already doing what you want.

How to set GCC_COLORS in gcc4.9 to emit colorizing diagnostics messages?

gcc4.9 supports the colorizing diagnostics for compiler warning/error messages.
We can enable it for a particular program using the option "fdiagnostics-color". Currently I am using gcc4.9.1 and I append this particular option in my makefile as follows:
CC = /home/mantosh/gcc-4.9.1/bin/g++ -std=c++1y -Wall -pthread
DFLAG = -g -gdwarf-2 -fdiagnostics-color=always
OUTFILE = test
$(OUTFILE): test.cpp
$(CC) $(DFLAG) -o $(OUTFILE) test.cpp
clean:
rm -f *.o $(OUTFILE)
If I compile a *.cpp file a get the following nice coloured message. This is really great feature added by GCC.
While reading the GCC offical link, it seems that this setting can permanently enabled using the GCC environmental variable "GCC_COLORS".
Could somebody explains how to set/change/customize this particular environment variable?
I am using Ubuntu12.04/GCC4.9.1.
just add this line to your ~/.bashrc file:
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
You can then reload it with source ~/.bashrc so you don't have to logout/login.

scons: changing compilation flags for a single source file

I have a fairly complex scons system with several subdirectories, with many libraries and executables.
Currently, every SConscript gets its own cloned environment, so I can easily change CFLAGS (or any other wariable) on a per-SConscript basis, but I'd like to change it per-target, and even per-object-file within a target.
I created a simple example SConscript and SConstruct to explain the problem, as follows.
SConstruct:
env = Environment()
env['CFLAGS'] = '-O2'
env.SConscript('SConscript', 'env')
SConscript:
Import('env')
env=env.Clone()
env.Program('foo', ['foo.c', 'bar.c'])
If I run scons, both foo.c and bar.c compile with -O2 flags. I could easily change flags SConscript-wide by just adding env['CFLAGS'] = '...' within the SConscript, but let's say that I want to compile foo.c with -O2, but bar.c with full debugging, -O0 -g. How do I do that (in the simplest possible way)?
The example uses gcc, but I'd like something that can be used with any compiler.
This happens frequently with performance-sensitive projects where compiling everything without optimization would result in unacceptable performance, but there is a need to debug one single file (or a subset of them).
The simplest one-liner answer is probably just to replace your Program line with this:
env.Program('foo', ['foo.c', env.Object('bar.c', CFLAGS='-g')])
because Program can take Object nodes as well as source files, and you can override any construction variable(s) in any builder (here, we override CFLAGS in the Object builder call). If you want to break out the Object into its own line for clarity:
debug_objs = env.Object('bar.c', CFLAGS='-g')
env.Program('foo', ['foo.c', debug_objs])
and of course taking that to the limit you get a system like Avatar33 showed above.
I suppose this is a bit harder in scons than it would be in make where you could just clean the required target and rebuilt with debug flags. Which would then just rebuild a specific object.
The solution to your particular project depends on it's size and how much effort the developer is prepared to put in.
So here's a rough solution where you specify source files on the command line that you want to be compiled with debug and no optimization, the rest will be compiled with -O2.
In your SConsctruct one additional line to get source files that we want to compile with debug from a command line option:
env = Environment()
env['CFLAGS'] = '-O2'
AddOption('--debug-targets', dest='debug-targets', type='string')
env.SConscript('SConscript', 'env')
And now in the SConscript file:
Import('env')
env=env.Clone()
debug_env = env.Clone()
debug_env['CFLAGS'] = '-g -O0'
normal_src = ['foo.c', 'bar.c']
debug_src = []
#Add src specified via the command line to the debug build
if GetOption('debug-targets'):
for x in GetOption('debug-targets').split(','):
if x in normal_src:
normal_src.remove(x)
debug_src.append(x)
normal_obj = env.Object(normal_src)
debug_obj = debug_env.Object(debug_src)
all_obj = normal_obj + debug_obj
env.Program('foo', all_obj)
Running our scons with out our debug-targets flag:
scons -Q
gcc -o bar.o -c -O2 bar.c
gcc -o foo.o -c -O2 foo.c
gcc -o foo foo.o bar.o
But now we want to compile bar.c with debug info:
scons -Q --debug-targets=bar.c
gcc -o bar.o -c -g -O0 bar.c
gcc -o foo foo.o bar.o
So that adds a bit of complexity to your build system, but if you don't need to specify debug targets from the command line like that, then the developer can obviously just cut and past sources from the normal_src list to debug_src.
There's probably many ways to improve and fine tune this for your specific environment

autoconf & automake versus -O2 versus -O3

My configure.ac contains
AC_PROG_CXX
and my Makefile.am contains
AM_CXXFLAGS= -Werror -O3
and the resulting 'configure' script keeps on adding -O2 to the mix in addition to O3.
I have this suspicion that I'm supposed to do something in configure.ac to declare my preference for O3, but I can't find it in the doc. How do I tell it that I want to control the optimization level?
No, you are not supposed to add anything to configure.ac to indicate a preference for -O3. That sort of thing belongs in a user's CONFIG_SITE, not in configure.ac
However, if you insist on breaking the convention, you can do something like:
: ${CXXFLAGS=-Werror -O3}
Note that this line must appear before AC_PROG_CXX (or any macro that AC_REQUIRES it, such as LT_INIT, as that will cause AC_PROG_CXX to be emitted into the configure script before this line.)
The prior answer is correct in that it should be the installer's choice what flags are used. If you're still wondering where the -g -O2 comes from (likely), it is described at http://www.gnu.org/s/hello/manual/autoconf/C_002b_002b-Compiler.html.
That page does suggest "If your package does not like this default, then it is acceptable to insert the line ‘: ${CXXFLAGS=""}’ after AC_INIT and before AC_PROG_CXX to select an empty default instead."

Resources