I see some of gcc flags repeated when building C extension for python. When I run:
python setup.py build_ext
The running build command looks like this:
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong -fno-plt -flto=4 -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong -fno-plt -fPIC -I/usr/include/python3.7m -c /tmp/src/source.c -o build/temp.linux-x86_64-3.7/tmp/src/source.o
gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -flto=4 -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now build/temp.linux-x86_64-3.7/tmp/src/source.o -L/usr/lib -lpython3.7m -o build/lib.linux-x86_64-3.7/source.cpython-37m-x86_64-linux-gnu.so
Ok, that's a long one. But, as you can see some flags are repeated. Here is the repetition in the first command:
-O3 repeated 4 times.
-fno-plt repeated 3 times.
-fstack-protector-strong repeated 3 times.
-march=x86-64 repeated 3 times.
-mtune=generic repeated 3 times.
-pipe repeated 3 times.
Beside -Wl,... flags which are passed to linker, does those flags repetition and ordering have any meanings?
It's not unusual to see repetitions of options in GCC commandlines
that have been generated by some tool-stack (frequently an IDE), with
human input "at the top".
None of the repetitions you have spotted makes any difference to the
meaning of the commandline. Usually such repetitions just amount to innocuous
redundancy, and they can have a rational
motive. A tool that is adding something incrementally to a GCC commandline may
wish to ensure that a certain option is in enabled at that point, even if it
might have been somehow disabled by an option appended since the last occurrence that enabled it. Repeating
the option redundantly may be cheaper than checking whether it is redundant.
But repetition is not necessarily innocuous...
If an option OPT occurs at some point in the commandline:
... OPT ...
then replacing that one occurrence with 2 or more will not make a difference.
However, if the commandline is of the form:
... OPT1 ... OPT2 ...
Then adding another occurrence of OPT1 anywhere after OPT2 may well make a
difference. Likewise adding another occurrence of OPT2 anywhere before OPT1.
That is because the order in which options occur very often makes a
difference.
An option is routinely composed of a flag and a value, e.g
-O3 -> Flag = -O, value = 3
-I./inc -> Flag = -I, value = ../inc
Some flags, like -O can take any one of a set of mutually
exclusive values. Call these mutex flags, for short. When a mutex flag occurs repeatedly with
countervailing values, the last in the commandline prevails:
-O1 -O2 -O3 = -O3
-O3 -O2 -O1 = -O1
Others flags, like -I, can take arbitary
non-exclusive values successively that are accumulated, in their order of occurrence, to form a sequence that
is one of the parameters of compilation or linkage. E.g.
-I./foo -I./bar
appends ./foo and then ./bar to the user-specified include-directory
search order for compilation. Call these cumulative flags.
Other flags are boolean and have an enabling form and a disabling
form , e.g. -fstack-protector,
-fno-stack-protector. These can be equated to mutex options with
exclusive possible values True and False.
And yet another kind of flag, like -l, accepts arbitrary non-exclusive values
successively that are not accumulated, but each just becomes the value of the flag
at that point in the commandline. For all I can recall, -l is the only flag of this kind,
which is an anomalous kind: -lfoo isn't really an option so much as a positional argument
to which the flag attaches a method of interpretation. It says that a file
libfoo.{so|a} is to be input to the linkage at this point, whose absolute pathname
the linker is to discover algorithmically (with reference to the -L options). Let's
call such flags positional flags.
For mutex flags, the meaning of a commandline can be changed if an option
occurring somewhere is repeated later. E.g.
-fno-stack-protector -O1 -O3 -fstack-protector
already looks as if too many cooks have been spoiling the broth, and
is equivalent to:
-O3 -fstack-protector
But if we append some repetition:
-fno-stack-protector -O1 -O3 -fstack-protector -fno-stack-protector -O1
it becomes equivalent to:
-O1 -fno-stack-protector
For cumulative flags, it's easier to envisage messing with the meaning
of the commandline by repeating an option before some occurrence than after:
-I./foo -I./bar
means what it says. Whereas
-I./bar -I./foo -I./bar
means the same as:
-I./bar -I./foo
But that sort of messing hardly happens in practice, because repetitions of
options are almost always generated by appending
a repetition to a commandline during incremental construction.
Positional flags are by definition sensitive to order, both amongst themselves
and in relation to other options and positional arguments. Every permutation of
... -lfoo -lbar main.o ...
yields a different linkage. And repetition of options with positional flags
can also easily make a difference. Notoriously,
... -lfoo main.o ...
may well result in a linkage failure, which
... -lfoo main.o -lfoo
would fix.
So emphatically, yes, repetition and ordering of flags can be important.
Related
I'm not a regular Cygwin user. I installed Cygwin and Cygwin64 for testing proposed patches.
Here's the output of a typical make:
User#windows-7-x64 ~/cryptopp
$ make
g++ -DNDEBUG -g -O2 -fPIC -march=native -pipe -c shacal2.cpp
shacal2.cpp:1:0: warning: -fPIC ignored for target (all code is position independent)
// shacal2.cpp - by Kevin Springle, 2003
^
g++ -DNDEBUG -g -O2 -fPIC -march=native -pipe -c seed.cpp
seed.cpp:1:0: warning: -fPIC ignored for target (all code is position independent)
// seed.cpp - written and placed in the public domain by Wei Dai
^
g++ -DNDEBUG -g -O2 -fPIC -march=native -pipe -c shark.cpp
shark.cpp:1:0: warning: -fPIC ignored for target (all code is position independent)
// shark.cpp - written and placed in the public domain by Wei Dai
^
...
Cygwin's make displays the first line of every file it compiles.
Why does Cygwin's make display the first line of every file? How can I stop the behavior?
The output is due to the warning about the -fPIC command line option, just as it says. Remove the -fPIC option from your makefile's CXXFLAGS (or wherever) and it will go away.
I made a simple quick sort algorithm using C language, named test.c
I'm trying to maximize the optimization, so I use -O3 options like belows.
gcc -S -O3 -o test.s test.c
gcc -S -O3 -o test1.s test.s
gcc -S -O3 -o test2.s test1.s
gcc -S -O3 -o test3.s test2.s
.
.
.
But strange thing happens. The more times I did above procedure, the more number of line assembly get.
I don't know why this happens, because I think that I have to get more optimized assembly file that has smaller number of line as I did above procedure.
If this is not right way, using -O3 only one time is the way of the best optimization?
Thanks
Most of the gcc optimizations operate on the representation of C source code in an intermediate language. I'm not aware of any optimization specifically operating at the assembler instruction level other than peephole. But that would also be included in -O3.
So yes, -O3 is supposed to be used only once, when turning C source into object files.
Under GNUStep on Arch Linux, I'm running into an interesting error on a fresh install.
Using my build system I run
gcc `gnustep-config --debug-flags` [other command line args]
in order to build up the command line per the operating system's necessary flags.
This works fine under Ubuntu, but on Arch Linux I'm getting a rather random error:
/usr/include/features.h:328:4: error: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Werror=cpp]
Well, gnustep-config --debug-flags spits out the following:
-MMD -MP -D_FORTIFY_SOURCE=2 -DGNUSTEP -DGNUSTEP_BASE_LIBRARY=1 -DGNU_GUI_LIBRARY=1 -DGNU_RUNTIME=1 -DGNUSTEP_BASE_LIBRARY=1 -fno-strict-aliasing -pthread -fPIC -g -DDEBUG -fno-omit-frame-pointer -Wall -DGSWARN -DGSDIAGNOSE -Wno-import -march=x86-64 -mtune=generic -pipe -fstack-protector-strong --param=ssp-buffer-size=4 -fgnu-runtime -fconstant-string-class=NSConstantString -fexec-charset=UTF-8 -I. -I/home/qix/GNUstep/Library/Headers -I/usr/include -D_FORTIFY_SOURCE=2 -I/usr/include -I/usr/include -I/usr/include -I/usr/lib/libffi-3.1/include/ -I/usr/lib/libffi-3.1/include -I/usr/include/libxml2 -I/usr/include/p11-kit-1
As well, I wish not to have optimizations on my debug builds (and later on I even override GNUStep's -g parameter to -g2).
Is there a way to explicitly undefine -D_FORTIFY_SOURCE later on in the command line, after the call to gnustep-config?
For example, something like
gcc `gnustep-config --debug-flags` -U_FORTIFY_SOURCE ...
where the -U undefines the previously defined macro?
Something to mention; I have -Werror enabled on purpose, and I'd like to keep it.
For now, using sed to work around this works. It appears this is a known issue with _FORTIFY_SOURCE causing issues, and there isn't a straightforward fix.
`gnustep-config --debug-flags | sed 's/-D_FORTIFY_SOURCE=2//g'`
In a particular project, I saw the following compiler options used all at once:
gcc foo.c -o foo.o -Icomponent1/subcomponent1 -Icomponent2/subcomponent1 -Wall -fPIC -s
Are the -fPIC and -s used together contradictory here? If not, why?
-s and -fPIC are two flags used for different purposes. They are not contradictory.
From the gcc manual
-s
Remove all symbol table and relocation information from the executable.
-fPIC
If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC.
In a Makefile of a library I am trying to build, there are a few lines specify the options to gcc:
CFLAGS += -I$(CURDIR) -pedantic -std=c89 -O3
CFLAGS += -Wall -Wno-unused-function -Wno-long-long
CFLAGS += $(if $(DEBUG), -O0 -g)
If DEBUG exists, there will be both -O3 and -O0 -g in CFLAGS. But -O0 and -O3 cannot be used at the same time. Will the one specified later supersede the one earlier?
Thanks and regards!
From the manpage:
If you use multiple -O options, with or without level numbers, the
last such option is the one that is effective.