it simply opens the header file MyHeader.h, and cut’n pastes its contents into MyCode.c
// Begin of MyHeader.h#ifndef MYHEADER_H#define MYHEADER_Hvoid FunctionDefinedInHeader(); // Declare the function# endif// End of MyHeader.hvoid main(){ FunctionDefinedInHeader(); // Use it}
Similarly, #defines are cut’n pasted, #ifs are analysed and potentially removed, etc.
At the end of this step we have a preprocessed C++ file, without any #define, #if, #ifdef, #include, and is then ready to be compiled
compiler (gcc -S, g++ -S): takes place on the preprocessed files:
checks the C/C++ syntax
converts the C/C++ code into assembly code
compilation example
The compiler translates C++ code into a representation that the assembler can directly understand. For instance, the following code
int i=3;int j=4*i+2;
will be translated into this : Machine/Assembly Language (here is x86 opcodes)
assembler (as): converts the assembly code to machine code (binary) as object-files (these object-files can refer to functions that are not defined. Also note these object-files can be used as libraries as well)
linker (ld): produces an executable or a library. It links the object files by replacing the undefined functions with the correct addresses. These functions should be defined in other object-files or in libraries (external object files). There are 2 types of external libraries:
static libraries - the linker would copy its contents into the executable
executor: when you launch the executable, the OS will put it in memory. As said earlier, some code isn’t available at this point (i.e. dynamic libraries). But the linker was nice enough to say where to look for it: the executable clearly states which dynamic library the function is defined. The OS will happily open the dynamic library and find the function’s definition
Example - GCC & G++ Breakdown
the command below does the first 4 steps (preprocessor, compiler, assembler, & linker)
gcc -o hello.exe hello.c
if you want to do each step manually:
preprocessing: via the GNU C Preprocessor (cpp.exe), which includes the headers (#include) and expands the macros (#define). The resultant intermediate file “hello.i” contains the expanded source code
cpp hello.c > hello.i
compilation: The compiler compiles the pre-processed source code into assembly code for a specific processor. The -S option specifies to produce assembly code, instead of object code. The resultant assembly file is “hello.s”
gcc -S hello.i
assembly: The assembler (as.exe) converts the assembly code into machine code in the object file “hello.o”
as -o hello.o hello.s
linker: Finally, the linker (ld.exe) links the object code with the library code to produce an executable file “hello.exe”
ld -o hello.exe hello.o ...libraries...
execution:
./hello.exe
Link Separately
// Compile-only with -c option
> gcc -c hello.c
// Link object file(s) into an executable
> gcc hello.o