Compilation and build process
The set of samples showcases different aspects of the compilation process in the Linux environment using various tools such as gcc, make, cmake, etc.
Single file compilation
Consider main.cpp as a source file containing the whole logic of the application:
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}To compile the source code into an executable file execute the following line in the source directory:
g++ main.cpp -o appwhere parameter -o app defines the name of the output file (a.out by default).
If the command completes successfully, the source directory will contain a file called app that is ready to execute as follows:
./appPre-processing a C++ source file
You may want to stop the compiler after the pre-processing phase when all the directives such as include, define, etc. are resolved. In that case you will need to run the pass the -E flag to the compiler as follows:
g++ main.cpp -E > preprocessed-main.cppThe result of the command prints the result on a console by default, hence we redirected the content to be written to file “preprocessed-main.cpp” by using redirection operator (>) of shell.
Translation of the source
You may also want to stop the compiler after the translation phase to get the low-level code in assembler language. For that you need to pass -S flag to the compiler. It will generate a new file with .s extension by default:
g++ main.cpp -SAfter the command is completed successfully you will get a main.s file containing your source in assembler language. The file will contain something like this:
# ... some other things
main:
.LFB1522:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
leaq .LC0(%rip), %rsi
leaq _ZSt4cout(%rip), %rdi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
movq %rax, %rdx
movq _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rax
movq %rax, %rsi
movq %rdx, %rdi
call _ZNSolsEPFRSoS_E@PLT
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
# ... some other thingsAssembling the compiled file
Most commonly, you will need to compile your source file to a binary object file containing your source code in a binary format, but not ready to execute. Object files are generated by passing -c to the compiler. By default a file with “.o” extension will be generated:
g++ main.cpp -c After this command, a file named main.o will be generated.
Linking object files
In most of the cases, you will have many source files compiled into object files separately and after all object files are ready you will link those together and add necessary libraries. For example, if you have files main.o, module1.o and module2.o you will need to link those together into an executable file (or a library):
g++ main.o module1.o module2.oAfter this command, a file named “a.out” will be generated and will be ready to run.
Also, you may want to see the libraries your executable is linked to using the following command:
ldd a.outIn this basic example, your executable will be linked with the standard libraries as follows:
linux-vdso.so.1 (0x00007ffc695fb000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f55b5264000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f55b5072000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f55b4f23000)
/lib64/ld-linux-x86-64.so.2 (0x00007f55b5456000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f55b4f08000)