I am learning about compiling process and I know that linking is mainly used to link a binary file which contains a \'main\' function with other binary files that contain ot
Read Levine's Linkers & Loaders.
Read about ELF.
Try compiling with gcc -v (you'll see what are the actual programs used: cc1 to compile C code into some assembler, as to assemble that into some object file, ld & collect2 to link). Look also at the generated assembler file with gcc -S -fverbose-asm -O. Notice that gcc knows about (and compiles specially) the main function. And the starting point of your executable is provided by some crt0, etc (it is not main but some _start routine coded in assembler which calls your main....).
Object files are not the same as executables. The executable contains stuff like crt0 and the C standard library, or some way to dynamically link it as a shared object (and you need to link your source.o -compiled from your empty main in source.c- into an executable because of that).
On Linux, play with objdump(1) & readelf(1) (on some existing binaries, and also on your source.o object file)
See also elf(5), execve(2), ld-linux(8), Linux assembly howto, syscalls(2), Advanced Linux Programming, Operating Systems: Three Easy Pieces, and (to understand about libc.so) Drepper's How To Write Shared Libraries, the Dragon Book ...
(you need to read entire books to understand the details; I gave some references)
Look also into Common Lisp & SBCL. Its compiler has a very different model (really different from C).