Files
42_INT_01_libft/Makefile
2019-11-16 05:14:18 +01:00

490 lines
11 KiB
Makefile

# - - - - - - - - -
# variables names
# - - - - - - - - -
NAME = libft.a
CC = gcc
CFLAGS = -Wall -Wextra -Werror -I. -c
SRCS = ft_atoi.c \
ft_bzero.c \
ft_isalnum.c \
ft_isalpha.c \
ft_isascii.c \
ft_isdigit.c \
ft_isprint.c \
ft_memccpy.c \
ft_memchr.c \
ft_memcmp.c \
ft_memcpy.c \
ft_memmove.c \
ft_memset.c \
ft_strcat.c \
ft_strchr.c \
ft_strcmp.c \
ft_strcpy.c \
ft_strdup.c \
ft_strlcat.c \
ft_strlen.c \
ft_strncat.c \
ft_strncmp.c \
ft_strncpy.c \
ft_strnstr.c \
ft_strrchr.c \
ft_strstr.c \
ft_tolower.c \
ft_toupper.c \
\
ft_itoa.c \
ft_memalloc.c \
ft_memdel.c \
ft_putchar.c \
ft_putchar_fd.c \
ft_putendl.c \
ft_putendl_fd.c \
ft_putnbr.c \
ft_putnbr_fd.c \
ft_putstr.c \
ft_putstr_fd.c \
ft_strclr.c \
ft_strdel.c \
ft_strequ.c \
ft_striter.c \
ft_striteri.c \
ft_strjoin.c \
ft_strmap.c \
ft_strmapi.c \
ft_strnequ.c \
ft_strnew.c \
ft_strsplit.c \
ft_strsub.c \
ft_strtrim.c \
\
ft_lstnew.c \
ft_lstdelone.c \
ft_lstdel.c \
ft_lstadd.c \
ft_lstiter.c \
ft_lstmap.c \
\
ft_any.c \
ft_atoibase.c \
ft_convertbase.c \
ft_foreach.c \
ft_issort.c \
ft_arraymap.c \
ft_putnbrbase.c \
ft_strmultisplit.c
OBJ = $(addprefix $(ODIR)/, $(SRCS:.c=.o))
# - - - - - - - - - -
# rules to execute
# - - - - - - - - - -
# when you write "make" in command line it will execute
# the first rule wrote in the Makefile, wich is ALL by
# convention because usually when you type "make" you
# expect it to build all
# it first verify if ODIR is created and if not create it
# then it calls NAME to create the library
all: $(ODIR) $(NAME)
# ODIR create the folder where the files.o will be stored
$(ODIR):
mkdir -p $(ODIR)
# NAME will create the library libft.a :
# - first it checks if any OBJ (files.o) have more recent
# date of modification than NAME (libft.a), and for each
# it will execute "ar rc $@ £<"
# - "ar rc name.a obj1.o obj2.o ..." create the library
# name.a if it doesn't already exist and add the given
# obj.o inside of it
# - ranlib doesn't need to be seen so it's precedeed by @
# - automatic variables :
# $@ means what's before ":"
# $< means what is after ":" (only first argument)
$(NAME): $(OBJ)
ar -rc $@ $<
@ranlib $@
$(ODIR)/%.o: %.c
$(COMPILE.c) -o $@ $<
clean:
/bin/rm -rf $(ODIR)
fclean: clean
/bin/rm -f $(NAME)
re: fclean all
.PHONY: clean
# ------------------------------------------------------ #
# explication complete etapes par etapes depuis le debut #
# ------------------------------------------------------ #
## SOMMAIRE [140 G]
## 1 - compiler avec gcc [161 G]
# compiler un programme... [165 G]
# compiler en plusieurs fichiers... [190 G]
# les .o : pre-compiler... [238 G]
## 2 - creer une librairie [272 G]
# ar rc [276 G]
# ar rc en plusieurs fois [301 G]
# ranlib [322 G]
## 3 - fichiers .h [335 G]
# ecrir un header []
# comment ca se compile []
## 4 - ecrire un make file... []
# makefile basique []
# ne pas tout recompiler... []
# fichiers .o dans un dossier... []
# make un autre makefile []
## ----------------------
## 1 - compiler avec gcc
## ----------------------
# - - - - - - - - - - - - - - - - - - - - - -
# compiler un programme qui contient un main
# - - - - - - - - - - - - - - - - - - - - - -
# quand on ecrit un programme il contient un main et les
# fonctions dont le main a besoin (ex ft_putchar) :
#
# # #include <unistd.h>
# #
# # void ft_putchar(char c)
# # {
# # write(1, &c, 1);
# # }
# #
# # int main()
# # {
# # ft_putchar('0');
# # return (0);
# # }
#
# on peut compiler ce fichier avec gcc en faisant :
# gcc file.c
# et ca sort un executable a.out
# si on l'execute "./a.out" ca ecrit 0 dans la console
# - - - - - - - - - - - - - - - - - - - - - - -
# compiler un programme en plusieurs fichiers
# - - - - - - - - - - - - - - - - - - - - - - -
# on va vite vouloir mettre chaque fonctions utilisee
# dans un fichier a part afin de mieux gerer les modules
# d'un programme. donc si on sort ft_putchar du fichier :
#
# # int main()
# # {
# # ft_putchar('0');
# # return (0);
# # }
#
# et qu'on execute "gcc file.c" on va avoir une erreur
# car file.c utilise ft_putchar mais gcc ne sait pas ce
# que c'est, donc il faut faire deux choses :
#
# 1 - d'une part indiquer a main() que ft_putchar()
# existe, en ecrivant au dessus non pas toute la fonction
# (puisqu'on veut la mettre dans un fichier a part) mais
# uniquement son prototype :
#
# # void ft_putchar(char c);
#
# 2 - et d'autre part qu'on rajoute le fichier contenant
# la fonction ft_putchar a la compilation :
#
# [ft_putchar.c]
# # #include <unistd.h>
# #
# # void ft_putchar(char c)
# # {
# # write(1, &c, 1);
# # }
#
# [main.c]
# # void ft_putchar(char c);
# #
# # int main()
# # {
# # ft_putchar('0');
# # return (0);
# # }
#
# si on compile les deux ca marche :
# gcc main.c ft_putchar.c
# - - - - - - - - - - - - - - - - - - - - - - -
# les .o : pre-compiler certains fichiers pour
# ne pas les recompiler a chaque fois
# - - - - - - - - - - - - - - - - - - - - - - -
# ca fonctionne mais gcc doit a chaque fois recompiler
# ft_putchar.c alors qu'il n'est pas modifie, donc on peut
# le compiler une bonne fois pour toute et l'ajouter a la
# compilation finale quand on en a besoin sans que l'ordi
# ait a tout retraduire dans son langage
#
# mais si on essaye de compiler ft_putchar seul
#
# # gcc ft_putchar.c
#
# ca nous donne une erreur car pour compiler, gcc a besoin
# de trouver un main !
#
# on va donc utiliser l'option -c pour creer un fichier
# objet .o qui est deja traduit en langue d'ordinateur
# et pret a etre rajoute a la compilation :
#
# # gcc -c ft_putchar.c --> donne ft_putchar.o
#
# qu'on peut compiler avec le fichier contenant le main :
#
# # gcc file.c ft_putchar.o
#
# on va maintenant voir comment faire une libraire qui
# contient tous nos fichiers objets
## ------------------------
## 2 - creer une librairie
## ------------------------
# - - - -
# ar rc
# - - - -
# pour mettre tous les fichiers .o dans un seul fichier .a
# on utilise un programme d'archive ar avec les options rc
# - r indique d'inserer les .o en remplacant si necessaire
# - c de creer une nouvelle archive
#
# le nom de l'archive doit commencer par lib et
# finir par .a :
#
# # ar rc libtest.a ft_putchar.o
#
# on obtient un fichier libtest.a qui contient les
# fichiers objets .o
#
# on peut l'utiliser a la compilation de cette manniere :
#
# # gcc main.c -L. -ltest
#
# -L indique ou est la librairie (ici elle est dans le
# dossier courant .)
# -l indique son nom (TEST car on n'indique pas lib et .a)
# - - - - - - - - - - - - -
# ar rc en plusieurs fois
# - - - - - - - - - - - - -
# on n'est pas oblige de creer une librairie en une seule
# fois, ce qui est bien pratique nottament pour les
# makefiles, on verra ca apres.
#
# ca signifie que si notre librairie contient plusieurs
# fonctions, par exmple la librairie libfruits.a contient
# banane.o et orange.o, on peut creer la librairie
# avec banane.o puis y ajouter orange.o, sans auncune
# manipulation speciale :
#
# # ar rc libfruits.a banane.o
# # ar rc libfruits.a orange.o
#
# revient au meme qu'ecrire :
#
# # ar rc libfruits.a banane.o orange.o
# - - - -
# ranlib
# - - - -
# ranlib creer un index du contenu de la librairie et le
# place dedans, c'est utile des que la librairie est tres
# grande afin que gcc sache acceder rapidement aux
# fonctions dont il a besoin dedans
#
# # ranlib libtest.a
#
# ranlib s'utilise apres avoir creer la lib avec ar rc
## ----------------
## 3 - fichiers .h
## ----------------
# - - - - - - - - - - - -
# ecrire un header
# - - - - - - - - - - - -
# si on utilise une librairie c'est parce qu'on peut avoir
# souvent besoin des memes fonctions dans un programme
# mais si a chaque fois qu'on utilise une fonction de la
# librairie on doit ecrire son prototype, ca va poser deux
# problemes :
#
# le prototype d'une seule fonction peut etre ecrit a
# pleins d'endroits, donc si la fonction change un peu on
# doit retrouver tous les emplacements des prototypes et
# les modifier un par un
#
# et d'autre part, si on utilise pleins de fonctions dans
# l'ecriture d'un programme on va devoir reecrire a chaque
# fois son prototype et c'est tres relou
#
# afin d'eviter ca on ecrit tous les prototypes, ainsi que
# les includes, et les structures, les defines, et autres,
# dans un seul fichier pour tout un programme, ou dans le
# cas present pour toute la librairie, et on l'inclus
# systematiquement au debut d'un fichier contenant des
# fonctions de la librairie, gcc s'occupera de l'expandre
# a la precompilation
#
# #
# #
# #
# #
# #
# #
# #
#
# #
# #
# #
# #
# #
# #
# #
#
# #
# #
# #
# #
# #
# #
#
# #
# #
# #
# #
# #
# #
# #
# #
#
# #
# #
# #
# #
# #
# #
# #
# #
# #
#
# - - - - - - - - - - - -
# comment ca se compile
# - - - - - - - - - - - -
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
## ----------------------------------------------------
## 4 - ecrire un make file pour aider a la compilation
## ----------------------------------------------------
# - - - - - - - - -
# makefile basique
# - - - - - - - - -
# - - - - - - - - - - - - - - - - - - - - - - - - -
# ne pas tout recompiler a la moindre modification
# - - - - - - - - - - - - - - - - - - - - - - - - -
# - - - - - - - - - - - - - - - - - - - -
# mettre les fichiers .o dans un dossier
# - - - - - - - - - - - - - - - - - - - -
# - - - - - - - - - - - -
# make un autre makefile
# - - - - - - - - - - - -
# exemple d'un makefilede basic
#
# # NAME = libtest.h
# # CC = gcc
# # CFLAGS = -I. -c
# # SRCS = example01.c \
# # example02.c
# # OBJ = $(SRCS:.c=.o) |ecrit les fichiers .c en .o
# #
# # all: $(NAME) |make execute sa premiere regle NAME
# # $(NAME): $(OBJ) |NAME execute d'abord OBJ
# # ar -rc $@ $< |
#
# Make a des built-in pattern rules :
# https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html
# par exemple pour construire des .o a partir de .c
# qui sont utilisees par défaut si les variables
# sont bien nomee (genre CC ou CFLAGS)
#
# cependant si on veut mettre les fichiers .o dans un
# sous-fichier BUILDS il n'y a pas de built-in pattern
# il faut donc l'ecrire nous-meme :
#
# # NAME = libtest.h
# # CC = gcc
# # CFLAGS = -I.
# # SRCS = example01.c \
# # example02.c
# # ODIR = ./builds
# # OBJS = $(addprefix $(ODIR)/, $(SRCS:.c=.o))
# #
# # all: $(NAME)
# # $(NAME): $(OBJS)
# # ar -rc $@ $<
# #
# # $(ODIR)/%.o : %.c
# # $(COMPILE.c) -o $@ $<
#
# cette regle est appellee par $(OBJS) puisque
# cette variable appelle la regle $(ODIR/file.o)
#
# COMPILE est une built-in variable qui execute
# les regles CC et CFLAGS avec l'option -c
#
# % = "tout"
# $@ = "la valeur a gauche de :"
# $< = "la premiere valeur a droite de :"
# $^ = "toutes les valeurs a droite de :"
#