salut,
je n'ai jamais regardé de pres comment make fonctionnait et je m'y met
jai regardé de la doc en anglais mais je n'ai pas tout compris
https://www.gnu.org/software/make/manual/make.pdf
du coup j'ai besoin de quelques explications et quelques revisions du shell:
à quoi sert le @ dans une sequence make? par exemple
id :
@echo blabla
ensuite le .PHONY: element1, element2
de ce que j'ai compris cela sert à "éviter" des élements dans l'execution d'une sequence du fichier ?
est ce que le .PHONY s'applique uniquement au bloc d'instruction qui le suit? (par exemple s'il y a un .PHONY avant un bloc et un .PHONY apres un bloc)
qu'est ce qu'un bloc entre define endef?
qu'est ce que %.zip? (le signe % designe quoi?) et est ce que ca peut faire office de *?
par exemple que produit ce bout de code dans un make:
%: %.xml
@cp $< file.xml
enfin les variables $ imbriquées:
par exemple quelles déclarations de variables nécessite le code suivant?
export $(word 1, $(subst =, , $(1))) := $(word 2, $(subst =, , $(1)))
merci
# ?
Posté par kr1p . Évalué à 2. Dernière modification le 04 octobre 2020 à 09:49.
Pas bcp de réponses.. bon j'ai trouvé de la doc en francais que je vais lire.
http://homepages.laas.fr/matthieu/cours/make/tpp.pdf
Mais mon objectif ici nest pas de faire un fichier make mais de bien comprendre un fichier makefile qui utilise make.
Existerait il un utilitaire qui recrée la serie de commande shell qu'un fichier makefile produit?
merci
[^] # Re: ?
Posté par AncalagonTotof . Évalué à 4.
0) des fois que tu serais passé à côté : trouve un éditeur qui préserve les tabulations. Quand on écrit du code source, on bannit les tabulations généralement, mais dans un Makefile, c'est indispensable de les préserver. Je dis ça juste pour être certain de pas passer à côté.
1) pas beaucoup de réponse, certes. Je me demande si on est pas tous démangés par un RTFM … En moins méchant, il y aurait ça makefile tutorial
Le tuto que tu as trouvé n'est pas trop mal, mais un peu aride. La syntaxe des Makefile est tellement vaste que ça n'est pas sur un seul résultat de recherche que tu apprendras tout. Évidemment, c'est mieux de savoir produire un exécutable à la main pour comprendre l'intérêt de l'automatisation par Makefile (même si make peut servir à plein de chose qui n'ont rien à voir avec la production d'exécutable).
2) essaye ça :
Ça pourrait t'afficher ce qui se passe sans le faire réellement. Cf point suivant pour l'usage du conditionnel.
3) ça fait longtemps, très longtemps, que je n'ai pas écrit un Makefile à la main. Le plus souvent, j'utilise Qt et son qmake, un générateur de Makefile, à partir d'une description plus simple du projet. Il existe plein d'autres solutions, mais c'est quand même bien de savoir comment fonctionne un Makefile, en cas de pépin, ça permet d'en trouver la cause.
4) pratique, teste, essaye, bricole. Ce genre de trucs ne vient qu'avec le temps. Quand j'ai vu make, awk et cie à la fac, j'ai pas pigé l'intérêt par rapport à la complexité. Maintenant, je ne peux plus m'en passer et je trouve ça simple. L'expérience ne peut pas venir en 5 minutes.
[^] # Re: ?
Posté par BAud (site web personnel) . Évalué à 3.
chez moi,
man make
m'indique que la doc' est plus complète avec uninfo make
:-)mais, oui,
make
soit tu pratiques, soit tu le fais générer (non, je ne vais pas suggérerautogen
/autoconf
/automake
ce serait sadique :D).PHONY
: c'est pour indiquer que ce n'est pas un fichier mais, par exemple, une commande qui suit[^] # Re: ?
Posté par kr1p . Évalué à 1.
merci pr le -n --just-print ca fonctionne bien!
[^] # Re: ?
Posté par chimrod (site web personnel) . Évalué à 2.
Moi ça m'arrive très souvent en fait. Je trouve ça plus pratique de lancer juste un
make
dans un répertoire, sans avoir à me souvenir exactement des commandes spécifiques :Bien sûr ça ne sont pas des fichiers aussi évolués que ceux générés par un outil tierce, mais ça fait aussi son boulot :)
[^] # Re: ?
Posté par kr1p . Évalué à 1. Dernière modification le 04 octobre 2020 à 15:33.
je fais une reponse de ce que j'ai trouvé dans la doc. ca me sera toujours utile pr un refresh si j'y reviens dans longtemps
vocabulaire:
cible: dependances
regles
@ sert à masquer les commandes effectuées par make dans le shell
a noter que make --just-print affiche quand meme les commandes
% équivaut à * : cela designe un ensemble de fichiers de facon generique
si utilisé dans cible: on ne parle plus de regle explicite mais de regle implicite
%: %.xml regle implicite
@cp $< file.xml
copie la 1ere dependance vers le fichier file.xml
$< : Le nom de la premi`ere dependance. Si les commandes pour
construire la cible proviennent d’une regle implicite, il s’agit de
la premiere dependance introduite par la regle implicite.
'-' en debut de ligne pr ignorer echec
.PRECIOUS : pour ne pas faire le menage si interrompu en cours de make sur une cible
PHONY:
la doc de RMS: "A phony target is one that is not really the name of a file; rather it is just a name for a
recipe to be executed when you make an explicit request. There are two reasons to use a
phony target: to avoid a conflict with a file of the same name, and to improve performance.
If you write a rule whose recipe will not create the target file, the recipe will be executed
every time the target comes up for remaking."
en gros utile si la cible n'est pas une fichier à creer
.SECONDARY
la doc de RMS: "The targets which .SECONDARY depends on are treated as intermediate files,
except that they are never automatically deleted."
en gros les cibles sont des fichiers intermediaires non supprimés
qu'est ce qu'un bloc entre define endef?
la doc de RMS : "When the same sequence of commands is useful in making various targets, you can define
it as a canned sequence with the define directive, and refer to the canned sequence from
the recipes for those targets. The canned sequence is actually a variable, so the name must
not conflict with other variable names."
en gros cest une variable qui peut definir une suite d'instructions à exécuter
$@ Le nom de la cible de la règle. Si une règle implicite comporte
plusieurs cibles, c’est la cible qui a déclenché la règle.
$< Le nom de la première dépendance. Si les commandes pour
construire la cible proviennent d’une règle implicite, il s’agit de
la première dépendance introduite par la règle implicite.
$? Les noms de toutes les dépendances qui sont plus récentes que la
cible, séparés par des espaces.
$^ Les noms de toutes les dépendances d’une cible, séparés par des
espaces.
$* Le radical associé à une règle implicite. Si la cible est toto.o
et que la motif dans la règle est %.o, alors $* vaut toto. Cette
variable est utile pour créer les noms de fichiers voisins.
Dans le cas des règles explicites, il n’y a pas de motif. Le radical
est souvent défini comme le nom de la cible sans suffixe. Il vau
[^] # Re: ?
Posté par kr1p . Évalué à 1. Dernière modification le 04 octobre 2020 à 15:54.
alors jai lu les docs anglaises et francaises et il y a deux trucs que je comprend pas bien dans le makefile que j'essaie de comprendre (en l'occurence il n'y a rien en .c ou en .o, cest une serie de commandes et de manip sur des bdd et du xml).
pour le shell
les variables imbriquées (cf question dans le premier post) : rien à voir avec make/makefile,cest du shell mais est ce que vous avez une bonne documentation de reference à me suggerer la dessus pr gagner du temps en recherche de documentation?
pour le make:
et pas de fichier ni de cible blabla initialement
est ce que les cibles default (en minuscule), link, clean sont des cibles avec mot clé réservé? (je ne vois pas de .PHONY pour indiquer que ce ne sont pas des cibles fichiers)
est ce que si j'ai une cible avec des dépendances qui ne sont pas des fichiers mais des cible, est ce que le make execute les instructions contenues dans ces dependances cibles ?
[^] # Re: ?
Posté par kr1p . Évalué à 1. Dernière modification le 04 octobre 2020 à 17:27.
Un petit refresh pour le shell (bash):
L'opérateur || signifie exécuter la commande suivante si la commande précédente n'a pas renvoyé 0. Il existe aussi l'opérateur && qui exécute la commande suivante si la commande précédente a renvoyé 0, et enfin ; qui exécute l'opération suivante dans tous les cas.
Variable Signification
$0 Nom du script
$1 Paramètre de position #1
$2 - $9 Paramètres de position #2 - #9
${10} Paramètre de position #10
$# Nombre de paramètres de position
"$" Tous les paramètres de position (en un seul mot) *
"$@" Tous les paramètres de position (en des chaînes séparées)
${#} Nombre de paramètres sur la ligne de commande passés au script
${#@} Nombre de paramètres sur la ligne de commande passés au script
$? Code de retour de la derniere operation
$$ Numéro d'identifiant du processus (PID) généré par le script
$- Options passées au script (utilisant set)
$_ Dernier argument de la commande précédente
$! Identifiant du processus (PID) du dernier job exécuté en tâche de fond
carte de reference
https://abs.traduc.org/abs-5.3-fr/apb.html
un bon guide avancé
https://abs.traduc.org/abs-fr/
Dans ce que je ne comprend toujours pas il y a les mots clés suivants (pas de man ni de info) :
word
subst
foreach
filter-out
wildcard
type
word
shell: est ce que $(shell blabla) appelle la variable SHELL=/bin/bash?
les variables ne sont pas sensible à la casse (minuscule/majuscules)?
pr ceux que jai trouvé
export:
Exporte le numéro de colonne dans l'environnement de façon à ce qu'il soit disponible plus tard.
call
CALL executes a procedure.
If the procedure has any output parameters, then a result row will be
returned, containing the values of those parameters.
fonctionne avec les sql
eval
y=eval ls -l # Similaire à y=ls -l
echo $y # mais les retours chariot sont supprimés parce que la variable
# n'est pas entre guillemets.
echo
echo "$y" # Les retours chariot sont préservés lorsque la variable se
# trouve entre guillemets.
strip
strip modifies the files named in its argument, rather than writing
modified copies under different names.
[^] # Re: ?
Posté par kr1p . Évalué à 1.
Et voilà
fonctions de make :
shell
The shell function is unlike any other function other than the wildcard function (see The Function wildcard) in that it communicates with the world outside of make.
The shell function performs the same function that backquotes (‘`’) perform in most shells: it does command expansion. This means that it takes as an argument a shell command and evaluates to the output of the command.
export:
Exporte le contenu d'une variable dans l'environnement ou dans un fichier de façon à ce qu'il soit disponible plus tard.
word
$(word n,text)
Returns the nth word of text. The legitimate values of n start from 1. If n is bigger than the number of words in text, the value is empty. For example,
$(word 2, foo bar baz)
returns ‘bar’.
filter-out
$(filter-out pattern…,text)
Returns all whitespace-separated words in text that do not match any of the pattern words, removing the words that do match one or more. This is the exact opposite of the filter function.
For example, given:
objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o
the following generates a list which contains all the object files not in ‘mains’:
(mains),$(objects))
subst
$(subst from,to,text)
Performs a textual replacement on the text text: each occurrence of from is replaced by to. The result is substituted for the function call. For example,
$(subst ee,EE,feet on the street)
produces the value ‘fEEt on the strEEt’.
wildcard
$(wildcard pattern…)
This string, used anywhere in a makefile, is replaced by a space-separated list of names of existing files that match one of the given file name patterns. If no existing file name matches a pattern, then that pattern is omitted from the output of the wildcard function.
foreach
$(foreach var,list,text)
The first two arguments, var and list, are expanded before anything else is done; note that the last argument, text, is not expanded at the same time. Then for each word of the expanded value of list, the variable named by the expanded value of var is set to that word, and text is expanded. Presumably text contains references to that variable, so its expansion will be different each time.
The result is that text is expanded as many times as there are whitespace-separated words in list. The multiple expansions of text are concatenated, with spaces between them, to make the result of foreach.
shell
The shell function is unlike any other function other than the wildcard function (see The Function wildcard) in that it communicates with the world outside of make.
The shell function performs the same function that backquotes (‘`’) perform in most shells: it does command expansion. This means that it takes as an argument a shell command and evaluates to the output of the command. The only processing make does on the result is to convert each newline (or carriage-return / newline pair) to a single space. If there is a trailing (carriage-return and) newline it will simply be removed.
call
CALL executes a procedure.
If the procedure has any output parameters, then a result row will be
returned, containing the values of those parameters.
fonctionne avec les sql
$(call variable,param,param,…)
When make expands this function, it assigns each param to temporary variables (2), etc. The variable $(0) will contain variable. There is no maximum number of parameter arguments. There is no minimum, either, but it doesn’t make sense to use call with no parameters.
strip
$(strip string)
Removes leading and trailing whitespace from string and replaces each internal sequence of one or more whitespace characters with a single space. Thus, ‘$(strip a b c )’ results in ‘a b c’.
commande shell
type
The type command will show you how a specific command will be interpreted if used on the command line.
type [OPTIONS] FILE_NAME…
-t renvoie alias (shell alias);function (shell function);builtin (shell builtin);file (disk file);keyword (shell reserved word)
-a renvoie t et localisation
-p renvoie le path si executable
eval
y=
eval ls -l
# Similaire à y=ls -l
echo $y # mais les retours chariot sont supprimés parce que la variable
# n'est pas entre guillemets.
echo
echo "$y" # Les retours chariot sont préservés lorsque la variable se
# trouve entre guillemets.
[^] # Re: ?
Posté par kr1p . Évalué à 1.
Jai toujours quelques questions irrésolues :
quand jai une cible avec une seule dépendance et rien dans le bloc d'instructions à faire: à quoi ca sert? exemple si j'ai ca dans le makefile
default: blabla
et pas de fichier ni de cible blabla initialement
est ce que les cibles default (en minuscule), link, clean sont des cibles avec mot clé réservé? (je ne vois pas de .PHONY pour indiquer que ce ne sont pas des cibles fichiers)
est ce que si j'ai une cible avec des dépendances qui ne sont pas des fichiers mais des cible, est ce que le make execute les instructions contenues dans ces dependances cibles ?
jajoute:
que faut il ajouter à un makefile pour qu'une cible soit systématiquement compilée quelque soit la façon dont on appelle make dans le terminal?
le symbole ?= est il reglementaire?
[^] # Re: ?
Posté par kr1p . Évalué à 1. Dernière modification le 06 octobre 2020 à 18:04.
jai trouvé pour ?= qui défini une variable seulement si elle n'est pas déjà définie.
par contre
pr le reste..pas trouvé dans la doc.
une derniere question : une instruction comme celle ci est elle lancée si elle n'est ni une cible ni une dépendance?
enfin, si elle est dans les instructions d'une cible, est ce qu'elle est lancée?
ca n'affiche rien avec --just-print: ni cat ni call fonction
$(foreach a,$(shell cat fichier 2> /dev/null),$(eval $(call fonction,$(a))))
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.