understand C compilers and build system and debugers

  • CMake — build system generator
    • You use this define how to compile your code
  • gcc/g++/clang/clang++ — compilers
    • compilers turn your code into binaries
    • gcc and g++ are the GNU C and C++ compilers, respectively
    • clang and clang++ are the LLVM compilers, respectively
    • Use CMake to define how to invoke compilers on the source code files
  • gdb/lldb — debuggers
    • gdb is a debugger provided by GNU
    • lldb is a debugger provided by LLVM
    • Use these to detect issues when running your binaries
    • It generally does not matter which compiler was used to generate the binary, i.e. you can use LLDB to debug a code compiled with a GNU compiler or vice versa

diffrence between make and cmake

Make (or rather a Makefile) is a buildsystem – it drives the compiler and other build tools to build your code.

CMake is a generator of buildsystems. It can produce Makefiles, it can produce Ninja build files, it can produce KDEvelop or Xcode projects, it can produce Visual Studio solutions. From the same starting point, the same CMakeLists.txt file. So if you have a platform-independent project, CMake is a way to make it buildsystem-independent as well.

If you have Windows developers used to Visual Studio and Unix developers who swear by GNU Make, CMake is (one of) the way(s) to go.

cmake -G"MSYS Makefiles"  when compiling for MinGW
cmake -G "Visual Studio 16 2019" -A Win32  when compiling for vs
cmake -G "Visual Studio 16 2019" -A x64 when compiling for vs

for more about cmake

GCC and G++

The GNU C and C++ compiler are called gcc and g++, respectively.

// Compile and link source file hello.c into executable a.exe (Windows) or a (Unixes)
> gcc hello.c
// (Unixes / Mac OS X) In Bash shell
$ gcc -o hello hello.c
$ chmod a+x hello
$ ./hello

// (Windows) In CMD shell
> g++ -o hello.exe hello.cpp
   // Compile and link source hello.cpp into executable hello.exe
> hello
// Execute under CMD shell

// (Unixes / Mac OS X) In Bash shell
$ g++ -o hello hello.cpp
$ chmod a+x hello
$ ./hello
$ g++ -Wall -g -o Hello.exe Hello.cpp
-o: specifies the output executable filename.
-Wall: prints "all" Warning messages.
-g: generates additional symbolic debuggging information for use with gdb debugger.
// Compile-only with -c option
> g++ -c -Wall -g Hello.cpp
// Link object file(s) into an executable
> g++ -g -o Hello.exe Hello.o
-c: Compile into object file "Hello.o". By default, the object file has the same name as the source file with extension of ".o" (there is no need to specify -o option). No linking with other object files or libraries.
Linking is performed when the input file are object files ".o" (instead of source file ".cpp" or ".c"). GCC uses a separate linker program (called ld.exe) to perform the linking.

Suppose that your program has two source files: file1.cppfile2.cpp. You could compile all of them in a single command:

g++ -o myprog.exe file1.cpp file2.cpp 

However, we usually compile each of the source files separately into object file, and link them together in the later stage. In this case, changes in one file does not require re-compilation of the other files.

> g++ -c file1.cpp
> g++ -c file2.cpp
> g++ -o myprog.exe file1.o file2.o
gcc program.o -llib1 -Wl,-Bstatic -llib2 -Wl,-Bdynamic -llib3 // link dynamic and static filels and object to executable file
> cpp hello.c > hello.i //preprocessing 
> gcc -S hello.i //compilation generate assembly code
> as -o hello.o hello.s //assembler generate machine code 
> ld -o hello.exe hello.o ...libraries... linker and generate excutable machine code
g++ --std=c++2a test2.cpp -o test2 //select c++ version

GNU Make

First Makefile By Example

// hello.c
#include <stdio.h>
int main() {
    printf("Hello, world!\n");
    return 0;
all: hello.exe

hello.exe: hello.o
	 gcc -o hello.exe hello.o

hello.o: hello.c
	 gcc -c hello.c
	 rm hello.o hello.exe

Run the “make” utility as follows:

> make
gcc -c hello.c
gcc -o hello.exe hello.o