Makefile renseignements

Le problème exposé dans ce sujet a été résolu.

Bonjour, Ceci étant mon 1 er poste sur ce forum ^^. J’aimerais me renseigner un peux plus sur le moteur make et les makefiles. Je sais que dans les projets monoplateforme l’utilisation de make peut s’avérer une bonne idée, mais dans le cas des projets multiplateforme on préfère passer par CMake/Premake/Autotools, car il n’y a pas de garantie que le projet puisse compiler dans les autres systèmes, pourquoi ? quelle sont ces cas ? pour quelles raisons principales ces outils on été développer ? À part les projets multiplateformes et la complexité d’utilisé soit même un makefile, il existe d’autres raisons pour laquelle il faut recourir À CMake/Premake ?

Merci a vous.

+0 -0

Pour Linux et OS X (et autre BSD-like), un makefile fonctionne très bien. C’est pas très compliqué a utiliser …

Par-contre pour de très gros projets ça peut devenir compliqué à maintenir (notament qui dépends de quoi si ça n’a pas été correctement établie depuis le départ) mais je ne pense pas que ce soit propre aux Makefile.

À propos d’autres outils, je ne connais pas donc je ne m’avancerais pas. Wikipédia a un article pas mauvais au sujet de Make :

https://fr.wikipedia.org/wiki/Make

+2 -0

Salut,

J’aimerais me renseigner un peu plus sur le moteur make et les makefiles. Je sais que dans les projets monoplateforme l’utilisation de make peut s’avérer une bonne idée, mais dans le cas des projets multiplateforme on préfère passer par CMake/Premake/Autotools, car il n’y a pas de garantie que le projet puisse compiler dans les autres systèmes, pourquoi ? quelle sont ces cas ? pour quelles raisons principales ces outils ont été développer ?

Styleoshin

Foncièrement, tu peux employer un Makefile pour un projet multiplateforme, le souci, c’est d’une part que les versions de make diffèrent d’une plateforme à l’autre (les distributions GNU/Linux utilisent le plus souvent GNU make, mais les *BSD emploient le plus souvent leur propre version de make, celle-ci étant liée aux ports(7)) et, d’autre part, qu’il n’y a pas de gestions des dépendances (typiquement, les bibliothèques tierces que requierent ton projet).

En soi, ce n’est pas insurmontable, il y a moyen de construire un Makefile portable en se basant sur la syntaxe de la norme POSIX et de combler d’éventuels manques (comme l’inventaire des fichiers de ton projet) à l’aide d’un préprocesseur comme m4 ou plus simplement des commandes sed ou ed. Quant aux dépendances, il t’est possible de vérifier leur respect en compilant par exemple un code minimal et en essayant ensuite de lier chaque bibliothèque requise.

1
2
3
4
5
.PHONY: testdep

testdep: testdep.c
    $(CC) -c $? -o $@.o
    $(CC) -lm $@.o -o $@

Si une des bibliothèques n’est pas présente, la commande make échouera et indiquera la bibliothèque manquante (ou plutôt l’édition des liens qui a échoué).

C’est pour fournir ces services (et d’autres) directement que les autotools et d’autres outils comme cmake ont été développés. En soi, il n’y a rien qui t’oblige à employer ces outils, mais ils te faciliteront la vie si tu ne souhaites pas gérer les choses à la main. ;)

+2 -0

Salut !

J’ai eu quelques cours sur autotools (les deux autres je ne connais pas mais je suppose que le principe est proche).

L’idée c’est de créer un script qui va tester la configuration du système pour lequel on veut compiler le projet et qui va ainsi générer dynamiquement les makefiles correspondants (et peut aussi modifier le code source en conséquence, par l’ajout des bonnes bibliothèques par exemple). Du coup, pour un projet multiplateformes il n’y a plus besoin de jongler entre différents makefiles, un seul script va (théoriquement) en créer un pour chaque cas.

il n’y a pas de garantie que le projet puisse compiler dans les autres systèmes, pourquoi ? quelle sont ces cas ?

Styleoshin

Les exemples que j’ai vu concernent plutôt les codes en C mais l’idée générale est la même pour d’autres langages.

Certaines bibliothèques peuvent être différentes selon les OS, ne pas se situer aux mêmes emplacements, et les outils de compilation peuvent fonctionner de manière différente.

De même, certaines fonctions n’existent pas sur tous les systèmes, ou peuvent avoir des noms ou des prototypes différents. Leur localisation dans les bibliothèques ou les fichiers d’en-tête peut aussi changer.

Sans utiliser autotools, il faudrait mettre manuellement dans le code plusieurs #define et #ifdef pour s’assurer de la portabilité du programme, mais ça peut vite devenir compliqué quand les plateformes se multiplient.

+0 -0

Je le dis depuis plusieurs années, mais en 2018, on ne devrait plus avoir à écrire de makefile à la main. Make est aux systèmes de build (sur Linux) ce qu’est l’assembleur aux langages de programmation. On y revient toujours. mais rarement à la main. Ca marche mais c’est pas pratique et on a mieux depuis longtemps.

C’est une plaie à écrire (tabulation, variables cryptiques), maintenir, dépourvu d’outils haut niveau et plutôt orienté unixoïde.

Si tu veux ne pas perdre du temps à te prendre la tête sur des choses qui ne devraient pas être des problèmes1, je te conseille de passer à des outils plus évolués comme cmake, scons (pour le C ou le C++). Ils offrent des abstractions de plus haut niveau, des mécanismes pour trouver des bibliothèques, supportent plusieurs système de génération (make, ninja, celui de VS sous windows,…) et sont généralement plus simple à utiliser.



  1. Car oui, si tu codes, c’est que tu as un problème à résoudre. Et dans ce but, le système de build devrait être ton ami et ne pas gêner dans ta tâche. Et écrire des makefile riches à la main c’est un bon moyen de perdre du temps sur des choses qui n’apportent aucune valeur ajoutée. 

+5 -0

Make est aux systèmes de build (sur Linux) ce qu’est l’assembleur aux langages de programmation.

C’est pas très vrai à mon avis, et l’année n’y change rien.

Par contre c’estvrai qu’écrire un grand makefile est inutile. Un makefile doit être très court et auto-explicatif. Si tu commences à devoir gérer des dépendances d’autres projets, le séparer en plusieurs makefiles ou bien utiliser un outil qui fait ça pour toi est plus simple.

Pour comprendre Make, le GNU Make book est une référence. ;)

Je le dis depuis plusieurs années, mais en 2018, on ne devrait plus avoir à écrire de makefile à la main. Make est aux systèmes de build (sur Linux) ce qu’est l’assembleur aux langages de programmation. On y revient toujours. mais rarement à la main. Ca marche mais c’est pas pratique et on a mieux depuis longtemps.

Davidbrcz

Je rejoins ici le point de vue d’unidan : le fait que la commande make ait été conçue il y a maintenant plusieurs dizaines d’années n’a aucune importance dans le choix ou non d’écrire un Makefile à la main. Si tu raisonnes ainsi, tu peux arrêter de suite d’employer un peu près tous les outils de bases sous Unix…

Par ailleurs, la comparaison avec l’Assembleur est de mon point de vue également franchement excessive, tu compares quand même un langage uniquement composé des mnémotechniques d’un processeur avec une commande qui fourni une couche d’abstraction permettant de gérer plus facilement les relations de dépendances entre des fichiers et les programmes qui produisent ces fichiers ou les utilisent pour en produire d’autres.

Pour comprendre Make, le GNU Make book est une référence. ;)

unidan

Pour comprendre GNU make. ;)

+1 -1

une commande qui fourni une couche d’abstraction permettant de gérer plus facilement les relations de dépendances entre des fichiers et les programmes qui produisent ces fichiers ou les utilisent pour en produire d’autres

Je ne sais pas comment on peut décemment dire que make abstrait les relations de dépendances. Il faut les écrire à la main et les mettre à jour à la main. Le moindre ajout d’un fichier dans l’arbre des dépendances qui vient en replacer d’autres est une plaie puisqu’il faut se taper toutes les dépendances de ce fichier à la main, et se taper la réécriture des dépendances des nœuds enfants. La seule chose que Make abstrait, c’est la résolution des dépendances, pas les relations. C’est déjà bien, mais clairement pas suffisant dès qu’on parle d’un projet avec plus de 3 fichiers qui se courent après.

L’argument de Davidbrcz n’a rien à voir avec l’age de Make, vous le comprenez à l’envers. Il a à voir avec l’âge (ou plutôt la maturité) des abstractions autour. Les systèmes de build automatisés sont mûrs depuis une bonne décennie (pour être gentil), on peut faire mieux que de se taper des Makefile sur un environnement de production. Ce qu’il vous dit c’est qu’on sait faire de l’USB depuis longtemps et vous défendez PS/2 en disant que c’est pas parce que c’est vieux que c’est pas bien.

Par-contre pour de très gros projets ça peut devenir compliqué à maintenir (notament qui dépends de quoi si ça n’a pas été correctement établie depuis le départ) mais je ne pense pas que ce soit propre aux Makefile.

Si, c’est propre aux Makefile. Pour avoir écrit from scratch la config CMake d’un projet au boulot (de taille respectable sans être monstrueuse, ~100k lignes sur ~100 fichiers, avec des dépendances externes un peu chiantes et optionnelles), c’est le jour et la nuit avec les Makefiles. Ajouter un fichier dans ce merdier revient à ajouter son nom dans la config CMake vs se retaper l’arbre des dépendances dans le Makefile. Changer de machine et/ou de compilo revient à définir les bonnes variables d’env pour CMake vs se plonger dans le Makefile pour changer les chemins vers les libs et les flags du compilo.

J’ai l’impression que les gens qui disent que tout va bien avec les Makefile sont ceux qui bossent toujours sur la même machine avec quelque pauvres fichiers qui se courent après. Ou alors ce sont des masochistes forcenés.

+3 -0

Je ne sais pas comment on peut décemment dire que make abstrait les relations de dépendances.

Je parlais des règles d’inférences ici, où make déduit seuls les relations et dépendances (j’ai un fichier objet à construire, j’ai un fichier source C, donc je dois compiler le fichier C correspondant ou encore j’ai un fichier Yacc, je dois appilquer Yacc et compiler le fichier C produit).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ cat <<EOF >main.c
int
main(void)
{
    return 0;
}
EOF
$ make main
cc     main.c   -o main
$

Après, oui, il faut bien entendu préciser les fichiers à employer et à obtenir si cela ne peut être inférer (c’est le principe même de la syntaxe d’un Makefile).

J’ai l’impression que les gens qui disent que tout va bien avec les Makefile sont ceux qui bossent toujours sur la même machine avec quelque pauvres fichiers qui se courent après. Ou alors ce sont des masochistes forcenés.

adri1

Ou alors ce sont des gens qui emploient les fonctions plus avancées des implémentations existantes de make (genre comme le système de port des différents *BSD) ou qui recourent à un préprocesseur maison pour se faciliter la vie ? Le monde n’est pas binaire, et heureusement. ;)

+0 -0

Ou alors ce sont des gens qui emploient les fonctions plus avancées des implémentations existantes de make (genre comme le système de port des différents *BSD) ou qui recourent à un préprocesseur maison pour se faciliter la vie ? Le monde n’est pas binaire, et heureusement.

On en revient à mon argument. Avec make, tu es conceptuellement à poil. Tout marche bien à partir du moment où le makefile est déjà écrit et que tu ne dois pas le faire évoluer à la main.

Je le redis mais make est l’assembleur du système de build sous Linux. De la même manière qu’on compile d’un langage haut niveau pour avoir un exécutable, on ne va pas écrire de makefile réaliste/complexe à la main mais utiliser un outil de plus haut niveau qui va le générer pour nous à partir d’une spec de plus haut niveau.

  • Les outils "classiques" (m4, autotools) ne me donnent pas envie de me plonger dedans quand je vois ca.
  • CMake a ses défauts mais reste quand même plus facile d’accès et plus simple à utiliser dans l’immense majorité des cas et devrait être la solution par défaut.

Si tu veux autre chose que CMake, y’a Scons ou Waf.

Je le redis mais make est l’assembleur du système de build sous Linux.

Davidbrcz

De mon point de vue, l’Assembleur du système de build, c’est le shell, parce qu’il est nécessaire de rigoureusement tout spécifier à la main (mais vraiment tout).

Pour le reste et sur le fond, je pense que l’on est globalement d’accord, c’est-à-dire que les outils alternatifs à make rendent indéniablement la vie plus facile. Ce qui me dérange, c’est le fait de balayer la solution d’un revers de la main, comme si personne ne pouvait ou devait s’y intéresser sous le seul prétexte qu’il y a « mieux ».

+1 -0

Précisons quand même quelques points :

  • Je suis d’accord qu’avec un logiciel qui a pleins de dépendances qui ont leur propre système de build et subtilités d’intégration, un outil comme cmake est pratique, mais si on n’est pas dans ce cas-là ça affiche juste des couleurs en plus. Et encore, cmake demande quand même de tout réécrire.

  • J’ai fait des projets full-makefile assez gros, qui compilaient du C pour arm, du C++ pour x86_64 et arm, du rust pour arm, des fichiers objets en notre format d’image interne, du system verilog en C++ puis compilait ce C++ dans plusieurs projets vers un exécutable en liant avec d’autres fichiers, et qui finalement lançait des tests en construisant des fichiers images avec montage et testait avec imagemagik. Il y avait relativement beaucoup de makefile pour la taille du projet parce que chaque partie avait le sien, mais ça revient exactement à la construction du projet cmake d’Adri1. La seule différence c’est qu’ils sont tous trivial à écrire et qu’ils sont tous sous la même forme. En le faisant avec cmake on aurait dû chercher les fonctions à appeler dans la doc.

  • En embarqué, il y a très souvent des makefiles, parce qu’il faut un format commun, modulaire et pratique pour les utilisateurs qui créent ou utilisent une carte.

  • Le gros plus du makefile, c’est la finesse de définition des targets, et si on sait pas utiliser ça et qu’on utilise Make comme on voudrait utiliser CMake c’est assez normal de se retrouver bloqué et de préférer CMake, parce qu’il est bien plus orienté "définition de projet" que Make. C’est aussi un outil qui s’apprend.

  • Pas besoin de préprocesseur pour faire du multiplateforme. Tu peux faire un makefile commun et écrire les différences dans des fichiers séparés pour chaque target finale. L’avantage de CMake/autotools sur Make pour ça, c’est la vérification de l’environnement de compilation, d’où l’utilité pour les gros projets.

Dire que make est l’assembleur du système de build sous Linux, c’est ne pas comprendre comment Make fonctionne pour moi. Je connais pas beaucoup de bout d’assembleur qui équivaudrait à compiler du C++ depuis un makefile inexistant. Dire pourquoi et dans quel contexte un préprocesseur est fondamental pour un projet est déjà beaucoup plus honnête.

Les outils "classiques" (m4, autotools) ne me donnent pas envie de me plonger dedans quand je vois ca.

Le même argument peut s’appliquer à CMake, et c’est même pas comparable ici parce que CMake est plus haut niveau que autotools. Il abstrait aussi les outils comme pkg-config et libtool. Bref, critiquer un outil sans savoir quel problème il peut résoudre, en se basant uniquement sur des idées reçues et son propre goût ça n’avance à rien.

Écrire un système de build pour un logiciel complexe n’est jamais une partie de plaisir, mais savoir choisir des outils adaptés sans idée reçue facilite déjà la tâche.

(Et puis c’est pas parce qu’on est passé en période après 2000 que tout ce qui a été fait avant est obsolète, sinon on ferait du nodeJS au lieu de faire des makefiles).

mais si on n’est pas dans ce cas-là ça affiche juste des couleurs en plus

Je savais pas qu’il y avait une couleur "gestion-de-la-compilation-hors-source-et-gestion-des-dépendances-intra-projet-et-gestion-des-modes-de-compilations-sans-cout". C’est quoi son code hexa ? (Et cette "couleur", c’est pour le projet le plus con du monde, tu as en plus la gestion de plusieurs compilo pour rien non plus…)

Et encore, cmake demande quand même de tout réécrire.

Ouais enfin écrire un CMake pour un projet sans subtilité, c’est le temps d’écrire :r!ls *.c et le nom du projet… :-° Écrire un CMake sera toujours beaucoup plus rapide que d’écrire le Makefile correspondant quelque soit la complexité du projet.

Il y avait relativement beaucoup de makefile pour la taille du projet parce que chaque partie avait le sien, mais ça revient exactement à la construction du projet cmake d’Adri1.

Ouais non, pas du tout justement. CMake t’évite d’avoir à maintenir plein de fichiers différents et abstrait les changements d’environnement pour toi.

Pas besoin de préprocesseur pour faire du multiplateforme. Tu peux faire un makefile commun et écrire les différences dans des fichiers séparés pour chaque target finale. L’avantage de CMake/autotools sur Make pour ça, c’est la vérification de l’environnement de compilation, d’où l’utilité pour les gros projets.

Vraiment ? Tu préfères écrire plein de Makefile (donc plein de trucs similaires à maintenir) qu’une ligne dans un fichier de config CMake ? C’est surréaliste à ce point.

(Et puis c’est pas parce qu’on est passé en période après 2000 que tout ce qui a été fait avant est obsolète, sinon on ferait du nodeJS au lieu de faire des makefiles).

unidan

Déjà répondu, c’est une proposition vraie mais complètement à côté de la plaque. Comme j’aime bien les analogies foireuses, en voici une autre. On te dit qu’on sait faire des radiateurs depuis longtemps, et à ça tu réponds que c’est pas parce que le feu de bois est vieux que c’est pas bien. Ce qu’on dit c’est pas que Make est vieux donc pas bien, c’est que les abstractions autour sont puissantes et stables et qu’il n’y a que très peu de raisons valables de s’en priver.

+2 -0

J’aime bien l’analogie, je vais la pousser et m’arrêter de répondre au topic vu qu’on tourne en rond.

  • Make seul = aller en forêt, couper son arbre, le débarder avec un cheval, le débiter à la main, allumer son feu de cheminée, et asservir la température de sa maison manuellement en jonglant entre l’intensité du bois et l’ouverture des fenêtres.
  • autotools = comme avant mais te donne un camion avec une grue, une carte pour savoir où trouver du bois et une tronçonneuse en plus.
  • CMake = Un professionnel vient chez toi poser tes radiateurs dans toute ta maison. Tu as la choix du modèle et du mode de chauffage (gaz, électricité). Il faut juste indiquer pù on veut poser les radiateurs dans chaque pièce. Il te pose aussi une centrale de contrôle pour réguler la température automatiquement et couper/allumer le chauffage en fonction de l’heure.
+3 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte