Skip to content

How many rules????? #28

Description

@Samuel-Muylaert

Quand un programme demande des arguments, la manière simple est d'utiliser Makefile pour compiler les fchiers, puis d'utiliser une deuxième commande afin de lancer le fichier compilé avec les arguments désirés.

Et si cette étape n'était pas nécessaire? En effet Makefile peut tout aussi bien lancer la commande ./Mon_programme
Mais lorsque des arguments entrent en jeu, le nombre de règles peut très rapidement exploser.

Un exemple: trois arguments pour le programme (num_threads, input, output, verbose) et une possibilité d'utiliser time ou valgrind lors de l'exécution de la commande.
En terme de règles, d'une manière naïve, il est possible de créer une règle pour chaque valeur de paramètre.
1-2-4-8-16 threads -> 5 règles.
Deux fichiers input à tester séparément -> 5 * 2 = 10
Mode verbeux optionnel -> 10 * 2 = 20
Exécution simple, avec Time, ou avec Valgrind -> 20 * 3 = 60
60 règles à écrire, et 60 règles à retenir.

Il est possible d'utiliser des variables au sein même des arguments d'une règle Makefile.
Un précédent post indique comment utiliser des règles à l'intérieur du fichier Makefile, je propose d'écrire un post concernant le fait de récupérer les arguments inscrits au terminal lors de l'éxécution de la règle Makefile, et des les inclures à la commande que la règle Makefile exécutera.

De cette sorte, une règle de base seulement existe, et des paramètres viennent rajouter ou modifier des éléments à cette commande.
La commande est donc construite par les arguments passés lors de l'appel de la règle.

Exemple:
RUN_CMD = ./$(TARGET) --dicts $(dicts) --input $(input) --output $(output) --mode $(mode) --threads $(threads)

ifeq ($(extended_verbose),true)
RUN_CMD := $(RUN_CMD) --verbose --extended_verbose
else ifeq ($(verbose),true)
RUN_CMD := $(RUN_CMD) --verbose
endif

ifeq ($(other_algo),true)
RUN_CMD := $(RUN_CMD) --other_algo
endif

execute: all
ifeq ($(prefix),time)
time -f "Compilation time: %e secondes" $(RUN_CMD)
else ifeq ($(prefix),valgrind)
$(VALGRIND) $(RUN_CMD)
else
$(RUN_CMD)
endif

SAMPLE USAGE
make execute prefix=valgrind dicts=dicts input=inputs/input_50l.bin output=build/output mode=detection threads=1 verbose=true

Dans la première ligne, la variable dicts est en fait créé lorsque le terminal appelle la règle avec le parametre dicts=...

Ce post va donc également parler de l'usage de blocks conditionnels dans un Makefile.

J'ai personnellement réduit mon nombre de règles de 60 à 1 dans mon projet grâce à cette méthode.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions