Compilation Steps
test.c [Pre-processor] test.i [Compiler (cc)] test.s [Assembler] test.o [Linker (ld)] a.exe
source Intermediate Assembly Object /\
file File Code File libcrypto.a(openssl)
Pre Processoring(*.c → *.i)
-
Converts source-code *.c to Intermidiate files *.i
Functions:
Remove comments from code
Expands include statements, macros. Expands anything else with #
-E Flag Stop after the preprocessing stage; do not run the compiler proper
# gcc -E test.c > m
# cat m
typedef unsigned char __u_char;
...
extern int fprintf (FILE *__restrict __stream,
const char *__restrict __format, ...);
extern int printf (const char *__restrict __format, ...);
...
int main(){
printf("Hello");
}
Compiler ((*.i → *.o))
-
Generates Object files. Only when told compiler generates asm files. Converts Intermediate files to object files.
Compiler is only bothered about function declaration, it does not check definition.
Linking definition to function is task of Linker.
Functions Lexical Analysis, parsing, Semantic Analysis, Verify code syntax
-S Flag Stop after the stage of compilation proper; do not assemble
// Generate Object files.
// Header file paths needed to be passed
// Libraries NOT NEEDED to be passed. -lcrypto(NOT NEEDED)
//-I: gcc Flag to pass path of Header files.
// -fopenmp -O3 -std=c++20 are compiler flags
# g++ -c test.c -I/opt/openssl/include -fopenmp -O3 -std=c++20 -o test.o
# ls
test.o
Linker(ld) (*.o → *[.exe])
-
lets you are working on project having 10 modules, each having seperate *.c file.
All c files create object files and at end you want 1 EXE file. Linker does it. Linker links code from library
Linker Also links from external libraries (eg: openssl)
Linker needs library path & library name(Which contains function definitions)
LIBS = -lcrypto -ldl -lpthread -ldl -lrt //Use libcrypto.a, libpthread.a
OPENSSL_LIBS_PATH = /opt/openssl //contains libcrypto.a, libssl.a
# g++ test.o ${LIBS} -o test-exe -L$(OPENSSL_LIBS_PATH)
# ls
test-exe