Makefile - .h - .c exemple.
Tags: makefile, c
Published: 2024-07-14 09:36:27

Voici la structure du projet avec l'exemple sans bibliothèque statique en premier, suivi de l'exemple avec bibliothèque statique.

### Structure du Projet

```
/mon_projet
├── Makefile
├── utils.h
├── utils.c
└── main.c
```

### Exemple 1 : Sans bibliothèque statique

#### 1. Fichier d'en-tête : `utils.h`

```c
#ifndef UTILS_H
#define UTILS_H

// Fonction pour additionner deux entiers
int addition(int a, int b);

#endif // UTILS_H
```

#### 2. Fichier source : `utils.c`

```c
#include "utils.h"

// Implémentation de la fonction d'addition
int addition(int a, int b) {
    return a + b;
}
```

#### 3. Fichier principal : `main.c`

```c
#include <stdio.h>
#include "utils.h"

int main() {
    int a = 5;
    int b = 3;
    int result = addition(a, b);

    printf("La somme de %d et %d est : %d\n", a, b, result);
    return 0;
}
```

#### 4. Makefile : `Makefile`

```makefile
# Variables
CC = gcc
CFLAGS = -Wall -g
SOURCES = main.c utils.c
OBJECTS = $(SOURCES:.c=.o)
DEPENDS = $(OBJECTS:.o=.d)
TARGET = mon_programme

# Règle par défaut
all: $(TARGET)

# Lien de l'exécutable
$(TARGET): $(OBJECTS)
	$(CC) -o $@ $^

# Compilation des fichiers .c en .o avec génération des dépendances
%.o: %.c
	$(CC) $(CFLAGS) -MMD -c $< -o $@

# Inclure les fichiers de dépendance
-include $(DEPENDS)

# Déclaration des cibles phony
.PHONY: all clean fclean re

# Nettoyage
clean:
	rm -f $(OBJECTS) $(DEPENDS)

fclean: clean
	rm -f $(TARGET)

re: fclean all
```

---

### Exemple 2 : Avec une bibliothèque statique

#### 1. Fichier d'en-tête : `utils.h`

```c
#ifndef UTILS_H
#define UTILS_H

// Fonction pour additionner deux entiers
int addition(int a, int b);

#endif // UTILS_H
```

#### 2. Fichier source : `utils.c`

```c
#include "utils.h"

// Implémentation de la fonction d'addition
int addition(int a, int b) {
    return a + b;
}
```

#### 3. Fichier principal : `main.c`

```c
#include <stdio.h>
#include "utils.h"

int main() {
    int a = 5;
    int b = 3;
    int result = addition(a, b);

    printf("La somme de %d et %d est : %d\n", a, b, result);
    return 0;
}
```

#### 4. Makefile : `Makefile`

```makefile
# Variables
CC = gcc
AR = ar
CFLAGS = -Wall -g
SOURCES = main.c utils.c
OBJECTS = $(SOURCES:.c=.o)
DEPENDS = $(OBJECTS:.o=.d)
TARGET = mon_programme
LIBRARY = libutils.a

# Règle par défaut
all: $(TARGET)

# Lien de l'exécutable
$(TARGET): $(OBJECTS) $(LIBRARY)
	$(CC) -o $@ $^

# Création de la bibliothèque statique
$(LIBRARY): utils.o
	$(AR) rcs $@ $^

# Compilation des fichiers .c en .o avec génération des dépendances
%.o: %.c
	$(CC) $(CFLAGS) -MMD -c $< -o $@

# Inclure les fichiers de dépendance
-include $(DEPENDS)

# Déclaration des cibles phony
.PHONY: all clean fclean re

# Nettoyage
clean:
	rm -f $(OBJECTS) $(DEPENDS) $(LIBRARY)

fclean: clean
	rm -f $(TARGET)

re: fclean all
```

### Résumé des Exemples

1. **Sans bibliothèque statique** :
   - Compile directement les fichiers source pour créer l'exécutable `mon_programme` sans créer de bibliothèque.

2. **Avec bibliothèque statique** :
   - Crée une bibliothèque `libutils.a` à partir de `utils.o`.
   - L'exécutable `mon_programme` dépend de cette bibliothèque.

### Utilisation

- Pour compiler le programme : `make`
- Pour nettoyer les fichiers objets et la bibliothèque (dans le premier exemple) : `make clean`
- Pour nettoyer complètement : `make fclean`
- Pour reconstruire : `make re`

Ces exemples montrent comment structurer un projet simple avec et sans bibliothèque statique tout en maintenant une clarté et une maintenabilité dans le Makefile.

### Exemple 3 : Avec utilisation d'un autre bibliothèque :

**Note : c'est le Makefile que j'ai créé lors de la réalisation d'un de mes projets.**

```makefile
# Arguments
NAME        = libftprintf.a
CFLAGS      = -Wall -Wextra -Werror -I .

# Sources
SRC_FILES    = ft_printf.c \
               ft_ulitob.c \
               ft_putunbr_fd.c \
               ft_unsigned_lintlen.c \
               ft_lintlen.c \
               ft_print_c.c \
               ft_print_s.c \
               ft_print_p.c \
               ft_print_di.c \
               ft_print_u.c \
               ft_print_x.c

# Objets
OBJ_FILES    = $(SRC_FILES:.c=.o)

# Règle principale
all: $(NAME)

# Création de la bibliothèque
$(NAME): $(OBJ_FILES)
	make -C libft/
	cp libft/libft.a $(NAME)
	ar rcs $(NAME) $(OBJ_FILES)

# Compilation des fichiers source
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

# Nettoyage
clean:
	rm -rf $(OBJ_FILES)
	make clean -C libft/

fclean: clean
	rm -rf $(NAME)
	make fclean -C libft/

re: fclean all

# Commandes indispensables
.PHONY: all clean fclean re
```

### Améliorations Clés

1. **Génération Automatique des Fichiers Objet** : La variable `OBJ_FILES` convertit automatiquement les noms de fichiers source en noms de fichiers objet à l'aide de la substitution de motifs.

2. **Règles de Motif** : L'utilisation de règles de motif (`%.o: %.c`) simplifie les commandes de compilation pour chaque fichier source.

3. **Règles de Nettoyage Organisées** : Les règles de nettoyage sont concises, supprimant les répétitions inutiles.

4. **Facilité de Maintenance** : La structure est claire, ce qui rend les futures modifications plus simples.

Ce Makefile conserve la même fonctionnalité tout en étant plus propre et plus efficace.