Is there any situation in which flags such as -ansi, -Wall, and -pedantic might be relevant during the linking part of the process?
What about the -O optimization flags? Are they only relevant during the compile steps or are they also relevant during linking?
Thanks!
In practice, no - but in theory, -ansi is a dialect option, so it could conceivably affect linking. I've seen similar behaviour with older versions of clang that use libc++ or libstdc++, when using C++11 or C++03 respectively. I find it easier to put these flags in the CC variable: CC = gcc -std=c99 or CC = gcc -std=c90 (ansi).
I just invoke C++ (or C) with $CXX or $CC out of habit. And they are passed by default to configure scripts.
I'm not aware of this being an issue with C, as long as the ABI and calling conventions haven't changed. C++, on the other hand, requires changes to the C++ runtime to support new language features. In either case, it's the compiler that invokes the linker with the relevant libraries.
There is link-time optimization in gcc:
-flto[=n]
This option runs the standard link-time optimizer. When invoked
with source code, it generates GIMPLE (one of GCC's internal
representations) and writes it to special ELF sections in the
object file. When the object files are linked together, all the
function bodies are read from these ELF sections and instantiated
as if they had been part of the same translation unit.
To use the link-time optimizer, -flto needs to be specified at
compile time and during the final link.
Related
I'm new to GNU and GCC, sorry if my question sounds dumb.
We know that GCC stands for GNU Compiler Collection, so I think gcc is just a compiler (from a compiler collection).
But I also read that gcc is a compiler driver which contains Pre-processor (cpp), Compiler (cc1), Assembler (as) and Linker (ld).
So it looks that GCC is not a compiler, but why wiki says:
"GCC is a key component of the GNU toolchain and the standard compiler for most projects related to GNU and Linux"
and what does "1" means in cc1, why it is called cc1, not cc2, cc3 ...etc?
In most cases you (a little inaccurately) call gcc the compiler. A reason is that you can run the whole tool chain, at least for simple projects, with a single gcc command. Let's say you have this main.c
// main.c
#include <stdio.h>
int main(void)
{
printf("Hello, world!\n");
}
and compile it with
gcc main.c
Then everything you mentioned, cpp, cc1, as and ld will be involved in creating the executable a.out. Well, almost. cpp is old and newer versions of the compiler has the preprocessor integrated.
If you want to see the output of the preprocessor, use gcc -E main.c
As I mentioned, the preprocessor and the compiler is integrated nowadays, so you cannot really run cc1 without the preprocessor. But you can generate an assembly file with gcc -S main.c and this will produce main.s. You can assemble that to an object file with gcc -c main.s which will produce main.o and then you can link it with gcc main.o to produce your final a.out
https://renenyffenegger.ch/notes/development/languages/C-C-plus-plus/GCC/cc1/index (Emphasis mine)
cc1 is also referred to as the compiler proper.
cc1 preprocesses a c translation unit and compiles it into assembly code. The assembly code is converted into an object file with the assembler.
Earlier versions of cc1 used /usr/bin/cpp for the preprocessing stage.
https://renenyffenegger.ch/notes/Linux/fhs/usr/bin/cpp (Emphasis mine)
The preprocessor.
cpp is not bo be confused with c++.
The preprocessor is concerned with things like
macro expansion
removing comments
trigraph conversion
escaped newline splicing
processing of directives
Newer version of gcc don't invoke /usr/bin/cpp directly for preprocessing a translation unit. Rather, the preprocessing is performed by the compiler proper cc1.
I would almost consider this as a dup of this, but it's impossible to create cross site dupes. Relationship between cc1 and gcc?
Related: 'Compiler proper' command for C program
and what does "1" means in cc1, why it is called cc1, not cc2, cc3 ...etc?
Don't know. My first guess was that they just added a 1 to cc which was and is the standard compiler on Unix (excluding Linux) systems. On most Linux system, cc is just a link to gcc. But another good guess is that it stands for the first phase in compilation. Have not found a good source though.
A function, before being used, needs to be declared either in a included header or otherwise (though not a good practice). The header file describes the functions and variables that may be found in a library or an object file and the compiler can create (as of yet) unreferenced symbols to be resolved later whilst linking.
However, my compiler (gcc based toolchain called esp-open-sdk (xtensa CPU)) continues despite finding no reference to a function in the headers and only in the linking stage does the linker intimate of an `undefined reference to <-function-name->'.
Another strange behaviour is that the compiler says nothing if there is no return statement, and the function is not "void".
My question is: What is causing this behaviour? I think it's unlikely but is it some compiler flag?
My compiler flags are:
CFLAGS = -Os -g -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH
and the linker flags are:
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static
Probably you use an old version of gcc. Before version 5.x, gcc defaults to a non-standard called "gnu90", which is a non-standard version of the obsolete C90 standard. There is no reason to ever use gnu90 unless you are maintaining some old Linux code. To avoid this, compile with:
-std=c11 -pedantic-errors
-std=c11 meaning you want the compiler to use the current C standard, without involving gnus or other strange animals. -pedantic-errors means that you want it to actually follow the standard and not just pretend to do it.
In order to get the warning for no return from functions, you need to use the option -Wreturn-type, which is included by using -Wall. Always compile with
-Wall -Wextra
Note that "Wall" does not stand for "all warnings", as it leads you to believe. Rather, -Wall means a fistful of warnings and -Wextra means a few warnings more.
In c we can enble the optimization setting by enabling the flag -O for enable all the possible optimization and -O0 will disable all enabled optimization.
My question is that this flags are message to whom?means to compiler or kernel?
All command line arguments you supply are interpreted by the compiler (or compiler driver, in the case of some compilers like gcc). They may then be passed on to other programs that the compiler (or compiler driver) executes to complete particular tasks.
Incidentally, -o is not an optimisation setting with quite a few compilers. It usually specifies the name of an output file. For example, gcc -c file.c -o anotherfile.o compilers file.c and produces an object file named anotherfile.o.
The optimisation setting is usually -O (for example -O3). Note the uppercase O. It won't necessarily be passed to every program executed by the compiler/driver. For example, gcc -O3 file.c -o program compiles file.c with optimisation setting -O3 and produces an output executable named program. To do that, the linker is invoked, as well as various compilation phases (preprocessor, compiler proper, etc). -O3 will not normally be passed to the linker - it is a compilation option which linkers normally do not understand.
The O flags are passed to the compiler, not the kernel. The kernel has nothing to do with compilation. These flags determine how aggressively the optimizer will do it's job. A practical example would be clang -O3 WannabeObjectFile.c.
Edit: I made a mistake, the lower case o flag is used to specify the output file. The uppercase O is used to specify optimization level.
I would like to know how to link a pgc++ compiled code (blabla.a) with a main code compiled with c++ or g++ GNU compiler.
For the moment linking with default gnu c++ linker gives errors like:
undefined reference to `__pgio_initu'
As the previous person already pointed out, PGI supports G++ name mangling when using the pgc++ command. Judging from this output, I'm guessing that you're linking with g++ rather than pgc++. I've had the most success when using pgc++ as the linker so that it finds the PGI libraries. If that's not an option, you can link an executable with pgc++ -dryrun to get the full link line and past the -L and -l options from there to get the same libraries.
Different C++ compilers use different name-mangling conventions
to generate the names that they expose to the linker, so the member function
name int A::foo(int) will be emitted to to the linker by compiler A as one string
of goobledegook, and by compiler B as quite a different string of goobledegook,
and the linker has no way of knowing they refer to the same function. Hence
you can't link object files produced by different C++ compilers unless they
employ the same name-mangling convention (and quite possibly not even then: name-mangling
is just one aspect of ABI compatibility.)
That being said, according to this document,
PGC++ supported name-mangling compatibility with g++ 3-and-half years ago, provided that PGI C++ compiler was invoked with precisely the command pgc++ or pgcpp --gnu. It may be that the library you are dealing with was not built in that specific way, or perhaps was built with an older PGI C++ compiler.
Anyhow, if g++ compiles the headers of your blabla.a and emits different
symbols from the ones in blabla.a, you can't link g++ code with blabla.a.
You'd need to rebuild blabla.a with g++, which perhaps is not an option.
We're facing an interesting topic. Lets say we have a special-functions.c file, basically a library.
We need to optimize the code as getting rid of all unused/unreferenced functions during the build process on-the-fly.
I'm not searching for generally unused (dead) code: some parts will be "dead" in case of compiling to one of the architectures, but it's going to be used in an other architecture build.
Does anybody knows of flags, tools, methods, tricks to do this?
The compiler is standard gcc with ansi 99 C code.
EDIT
I know, this is mainly the part of the linker, but using gcc, the process is not really split into two parts.
From http://embeddedfreak.wordpress.com/2009/02/10/removing-unused-functionsdead-codes-with-gccgnu-ld/ :
Compile with -fdata-sections to keep the data in separate data
sections and -ffunction-sections to keep functions in separate
sections, so they (data and functions) can be discarded if unused.
Link with --gc-sections to remove unused sections.
For example:
gcc -Os -fdata-sections -ffunction-sections test.c -o test -Wl,--gc-sections
I think that a recent GCC (i.e. 4.6) should do that if you compile and link with the -flto flag (link time optimization). I would imagine that having hidden or internal visibility should be relevant (at least for non-static functions).
To my knowledge, the GNU binary utils (ld, in this case) already remove unusesd references on static link