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.
Related
Is it possible to use both command line parameters to the configure script, ala:
../configure CXXFLAGS=-O0 -g -foo -bar -bat
while simultaneously keeping any options that are passed to AM_INIT_AUTOMAKE in the configure.ac file? e.g.:
AM_INIT_AUTOMAKE([-Wall -Werror])
My desired result is that ALL of the above flags are passed along, e.g.:
-O0 -g -foo -bar -bat -Wall -Werror
It appears that specifying CXXFLAGS on the command line either ingores or overwrites what is passed into AM_INIT_AUTOMAKE. If anyone knows of a way to do the union of the two sets, that would be extremely helpful. Thx!
The -W warning categories options have nothing to do with C[XX]FLAGS. These are command line arguments used when invoking automake.
Conversely, the AM_INIT_AUTOMAKE options like -Wall don't affect the compiler flags. It's just the decision to use these switch names that is resulting in the confusion. They have a similar meaning, e.g., -Werror will treat automake warnings as errors, but are totally unrelated.
In short, you have to pass -Wall, etc., in C[XX]FLAGS to influence the compiler. And add -Wall to AM_INIT_AUTOMAKE to enable all warning categories when automake is invoked.
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
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. ....."
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."
I see that VC++ includes an option called /show include to list you the hierarchy of include files in each translation unit. This seems to be a very helpful option - to optimise/improve the compilation time in a large scale project.
Question
Is there any equivalent option in GNU g++ compiler to get these (similar output)?
gcc -H
will print the names of header files as they are used.
There's a variety of options for controlling this.
-MD will list files, -MMD will list non-system files as side effects of compilation
-M, -MM will generate lists instead of compiling.
-MQ, -MG, -MP and -MT generate makefile target fragments. -MF allows you to specify an output filename.