Files
web/content/notes/compiling.md

114 lines
2.9 KiB
Markdown

---
title: Compiling [MAKE / GCC]
description:
draft: false
tags:
- c
- programming
author: TrudeEH
showToc: true
---
A compiler converts `C` code into machine code in 4 steps:
1. **Preprocessing** (Convert all preprocessor instructions (`#…`) to C code.)
2. **Compiling** (Convert `C` code to assembly.)
3. **Assembling** (Compile the necessary libraries.)
4. **Linking** (Merge the compiled code with the compiled libraries.)
## Libraries
Libraries are pre-written collections of code that can be reused in other programs. On *UNIX* systems, they are usually located in the `/lib/` and `/usr/include` directories.
### Math.h
For example, `math.h` is very useful to implement complex arithmetic operations.
```C
#include <math.h>
double A = sqrt(9);
double B = pow(2, 4);
int C = round(3.14);
int D = ceil(3.14);
int E = floor(3.99);
double F = fabs(-100);
double G = log(3);
double H = sin(45);
double I = cos(45);
double J = tan(45);
```
### Using Libraries
To use a library, we first have to include it in the `C` code.
```C
#include <cs50.h> // cs50.h library will be included.
```
Then, the library must be linked at compile time (unless it is part of the C standard).
```Shell
gcc -o hello hello.c -lcs50
./hello
```
## Optimization Flags
- `-O2` Optimize for speed
- `-O3` Optimize for speed aggressively
- `-Os` Optimize for size
- `-Og` Optimize for debugging
- `-Oz` Optimize for size aggressively
## Make
`Make` Is a build automation tool that automates the process of compiling, linking and building executables.
An example `Makefile` (for an app using `GTK4`) could be as follows:
```Makefile
CC = gcc
CFLAGS = $(shell pkg-config --cflags gtk4)
LIBS = $(shell pkg-config --libs gtk4)
hello: hello.c
$(CC) $(CFLAGS) -o hello hello.c $(LIBS) -O2
debug: hello.c
$(CC) $(CFLAGS) -o hello hello.c $(LDFLAGS) -Wall -Wextra -Og -g
clean:
rm -f hello
```
```Shell
make # Compiles hello.c
make debug # Compiles hello.c using debug flags
make clean # Removes the executable (hello) generated by the make command.
```
## Meson
While `make` automates compiling, on larger projects, makefiles can grow hard to read quickly, and dependency resolution has to be done using external tools (such as `pkg-config`).
Meson is a more modern alternative, which is faster, and uses declarative syntax (describe *what* to build, instead of *how* to build it). Meson can automatically manage dependencies, header files, and compiler flags.
When `meson` is executed, it generates a `ninja.build` file, which is then parsed by `ninja`, a lower-level build tool.
```meson.build
project('hello', 'c')
gtk4_dep = dependency('gtk4')
executable('hello', 'hello.c',
dependencies: gtk4_dep)
```
```bash
mkdir build
meson setup build # Generate files for Ninja in the build dir
meson compile -C build # Compile the project (same as `ninja -C build`)
./build/hello
ninja clean -C build # Clean executable files in the build directory
```