Skip to content
Snippets Groups Projects
Verified Commit f6bbc9c4 authored by orestis.malaspin's avatar orestis.malaspin
Browse files

added two latest classes

parent afb4450e
No related branches found
No related tags found
No related merge requests found
......@@ -8,6 +8,7 @@
PDFOPTIONS = -t beamer
PDFOPTIONS += --pdf-engine=xelatex
PDFOPTIONS += -F mermaid-filter
PDFOPTIONS += --default-image-extension=pdf
PDFOPTIONS += -V theme:metropolis
PDFOPTIONS += -V themeoptions:numbering=none -V themeoptions:progressbar=foot
......
---
title: "Plus de Makefiles"
date: "2023-02-24"
---
# `make` avancé
## Rappel: utilité
- Automatiser le processus de conversion d'un type de fichier à un autre, en *gérant les dépendances*.
- Effectue la conversion des fichiers qui ont changé uniquement.
- Utilisé pour la compilation:
- Création du code objet à partir des sources.
- Création de l'exécutable à partir du code objet.
- Tout "gros" projet utilise `make` (pas uniquement en `C`).
- Un `Makefile` bien écrit ne recompile que ce qui est **nécessaire**!
- Il existe d'autres outils pour le `C` et d'autres langages (`cmake`, `meson`, `maven`, `cargo`, ...).
# Utilisation de `make`
:::::::::::::: {.columns}
::: {.column width="60%"}
## `Makefile` simple
```bash
galaxy: galaxy.o stars.o vec.o
gcc -o galaxy galaxy.o stars.o \
vec.o
galaxy.o: galaxy.c stars.h
gcc -c galaxy.c
stars.o: stars.c stars.h vec.h
gcc -c galaxy.c
vec.o: vec.c vec.h
gcc -c vec.c
clean:
rm -f *.o galaxy
```
:::
::: {.column width="40%"}
## Terminal
```bash
$ make
gcc -c galaxy.c
gcc -c stars.c
gcc -c vec.c
gcc -o galaxy galaxy.o
stars.o vec.o
$ make clean
rm -f *.o galaxy
```
:::
::::::::::::::
**Dessinez le diagramme de dépendances de ce `Makefile`**.
# Diagramme de dépendances
~~~{.mermaid format=png}
graph TD;
galaxy.o --> galaxy
stars.o --> galaxy
vec.o --> galaxy
galaxy.c --> galaxy.o
stars.c --> stars.o
stars.h --> stars.o
stars.h --> galaxy.o
vec.h --> stars.o
vec.h --> vec.o
vec.c --> vec.o
~~~
# `Makefile` plus complexe (1/3)
```makefile
# Un Makefile typique
# Le compilateur
CC = gcc
# La variable CFLAGS contient les flags de compilation:
# -g compile avec les infos de debug
# -Wall Plein de warning
# -Wextra Encore plus de warnings
# -pedantic Warning lvl archimage
# -O0 Option d'optimisation (0,1,2,3)
# -std=c11 Utilisation du standard c11
# -fsanitize=address Utilisation des sanitizers
CFLAGS = -g -Wall -Wextra -pedantic -O0 -std=c11 -fsanitize=address
```
# `Makefile` plus complexe (2/3)
```makefile
# La variable LDFLAGS contient les flags pour l'éditeur
# de liens:
# -lm dit d'éditer les liens avec la lib math
# -lSDL2 dit d'éditer les liens avec la lib SDL2
LDFLAGS = -lm -lSDL2
# Définition des sources
SOURCES = galaxy.c stars.c vec.c
# OBJECTS contient SOURCES avec .c qui devient .o
OBJECTS = $(SOURCES:.c=.o)
# galaxy sera l'exécutable (galaxy.c contient le main)
TARGET = galaxy
# Jusqu'ici on a aucune cible.
```
# `Makefile` plus complexe (3/3)
```makefile
# TARGET est la première cible et sera donc exécuté à
# l'invocation de `make`. Elle dépend de OBJECTS
$(TARGET) : $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
# $@ : la cible, $ˆ : la liste des dépendances
# PHONY signifie qu'on ne crée rien avec les cibles
# mentionnées. Ici clean est la cible utilisée pour
# enlever tous les fichier .o et l'exécutable
# exécute toujours clean, même si un ficher `clean` existe
.PHONY: clean
clean: # aucune dépendance
rm -f $(TARGET) $(OBJECTS)
```
# Gestion implicite (1/2)
## Question
Pourquoi n'a-t-on pas besoin de générer les `OBJECTS`?
## Réponse
`make` possède une série de règles implicites (voir [ce lien](https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_10.html#SEC95) pour une liste).
## Fonctionnement
Si `make` rencontre une dépendance sans règle, il va voir dans sa liste de règles implicites pour la générer.
```makefile
galaxy: galaxy.o stars.o vec.o
gcc -o galaxy galaxy.o stars.o vec.o $(CFLAGS) $(LDFLAGS)
# implicitement pour galaxy.c, stars.c et vec.c
$(CC) -c $< $(CFLAGS) -o $@
```
# Gestion implicite (2/2)
## Question
Et pour les dépendances des cibles implicites ça se passe comment?
## Réponse
On peut définir individuellement les dites dépendances!
## Fonctionnement
Quand `make` rencontre une dépendance sans règle, il va voir dans sa liste de règles implicites pour la générer.
```makefile
# pas besoin des .c qui sont implicites
galaxy.o: stars.h vec.h
stars.o: *.h
vec.o: vec.h
```
# On peut faire mieux
Il est possible de prendre **tous** les fichiers `.c`
```makefile
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
```
Ou encore mieux
```makefile
OBJECTS := $(patsubst %.c,%.o,$(wildcard *.c))
```
# That escalated quickly: `*`, `%`, `:=`, ...
```makefile
# version "longue"
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
# version "courte"
OBJECTS := $(patsubst %.c,%.o,$(wildcard *.c))
```
Let's take one step at a time:
* Les `*`{.makefile},
* Les `%`{.makefile}, et leurs différences.
* Les fonctions, ici `wildcard`{.makefile} et `patsubst`{.makefile} (voir respectivement [ce lien](https://www.gnu.org/software/make/manual/html_node/Wildcard-Function.html) et [ce lien](https://www.gnu.org/software/make/manual/html_node/Text-Functions.html)).
* Le symbole `:=`{.makefile} vs `=`{.makefile}.
# Le symbole `*`
## `make` peut "développer" (expand) des `wildcards` (`*`)
* dans les recettes le `*` est géré par le shell
```makefile
clean:
rm -f *.o galaxy
```
* dans les dépendances
```makefile
galaxy.o: *.h
```
mais des fichiers `.h` doivent exister sinon il interprète `*.h` le nom du fichier.
## Par contre ile ne peut pas
```makefile
OBJECTS = *.o
# il faut utiliser
OBJECTS := $(wildcard *.o) # retourne tous les fichier .o
```
# La différence entre `*` et `%`
* Le symbole `*`{.makefile} sert à générer une *liste* d'objets.
* Le symbole `%`{.makefile} sert comme *emplacement* (placeholder).
## Exemple
```makefile
%.o: %.c # % est la partie avant .c
$(CC) -o $@ -c $< $(CFLAGS) # la règle pour chaque `%.c`
# équivalent à
galaxy.o: galaxy.c
stars.o: stars.c
vec.o: vec.c
```
## Application
```makefile
$(patsubst # Substitution de texte pour chaque
%.c,\ # Le pattern "avant" le .c
%.o,\ # Le pattern "avant" le .o
$(wildcard *.c)\ # Tous les fichiers .c
)
```
# Le symbole `:=`{.makefile} vs `=`{.makefile} (1/2)
Deux façon (flavors) d'assigner des variables (voir [ce lien](https://www.gnu.org/software/make/manual/html_node/Flavors.html#Flavors)):
## Le symbole `=`
* Façon **récursive**:
```makefile
foo = $(bar)
bar = $(ugh)
ugh = Huh?
```
ici `foo` vaut `Huh?`.
* Valeurs remplacées "récursivement".
* Variables remplacées à chaque appel (lent + imprédictible!).
# Le symbole `:=` vs `=` (2/2)
Deux façon (flavors) d'assigner des variables (voir [ce lien](https://www.gnu.org/software/make/manual/html_node/Flavors.html#Flavors)):
## Le symbole `:=`
* Façon **simplement développée** (`Simply expanded variable`):
```makefile
x := foo
y := $(x) bar
x := later
```
ici `y` vaut `foo bar` et `x` vaut `later` (avec des `=`, `y` vaudrait `later bar`).
* Les variables se comportent comme en `C`.
* En particulier dans les *longs* `Makefile` le comportement est plus prédictible.
---
title: "Pointeurs avancés"
date: "2023-02-28"
---
# Pointeurs et `const`
\footnotesize
- Le mot-clé `const` permet de déclarer des valeurs **constantes** qui ne changeront plus en cours d'exécution du programme.
```C
const int a = 1;
a = 2; // interdit, erreur de compilation!
```
## Deux niveaux de constance
- Mais qu'est-ce que cela veut dire pour les pointeurs?
* Constance de la valeur de l'adresse? de la valeur pointée? des deux?
```C
int n = 12;
const int *p = &n; // la valeur *p est const, p non
int const *p = &n; // la valeur *p est const, p non
int *const p = &n; // la valeur p est const, *p non
const int *const p = &n; // la valeur p et *p sont const
```
# Pointeurs et `const`
## Exemples
```C
int n = 12; int m = 13;
const int *p = &n; // la valeur *p est const, p non
*p = m; // erreur de compilation.
p = &m; // OK
int const *p = &n; // la valeur *p est const, p non
*p = m; // erreur de compilation.
p = &m; // OK
int *const p = &n; // la valeur p est const, *p non
*p = m; // OK
p = &m; // erreur de compilation.
const int *const p = &n; // la valeur p et *p sont const
*p = m; // erreur de compilation.
p = &m; // erreur de compilation.
```
# Pointeurs et `const`
## Fonctions
```C
void foo(int *a);
void foo(const int *a); // on pourra pas changer *a
void foo(int *const a); // inutile on peut pas changer a
void foo(const int *const a); // identique à ci-dessus
```
## Mais.....
```C
const int a = 0;
int *b = (int *)&a;
*b = 7;
printf("a = %d\n", a); // affiche quoi?
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment