AnglaisFrançaisEspagnol

Ad


Icône de favori OnWorks

makepp_extending - En ligne dans le Cloud

Exécutez makepp_extending dans le fournisseur d'hébergement gratuit OnWorks sur Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

Il s'agit de la commande makepp_extending qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks à l'aide de l'un de nos multiples postes de travail en ligne gratuits tels que Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

PROGRAMME:

Nom


makepp_extending -- Comment étendre makepp en utilisant Perl

DESCRIPTION


Makepp est suffisamment flexible en interne pour qu'en écrivant un peu de code Perl, vous puissiez
ajouter des fonctions ou effectuer un certain nombre d'autres opérations.

Général note on écriture Perl code à TRAVAIL avec makepp
Chaque makefile vit dans son propre package. Ainsi, les définitions dans un makefile n'affectent pas
définitions dans un autre makefile. Un ensemble commun de fonctions comprenant toutes les
les fonctions de manipulation de texte sont importées dans le package lors de sa création.

Les variables Makefile sont stockées sous forme de scalaires Perl dans ce package. (Il y a des exceptions à
ceci : les variables automatiques et la valeur par défaut des variables comme CC sont en fait
implémenté sous forme de fonctions sans arguments. Ciblez des vars spécifiques, des vars de ligne de commande et
les variables d'environnement ne sont pas vues de cette façon.) Ainsi, tout code Perl que vous écrivez a accès à tous
variables makefile. Les variables globales sont stockées dans le package "Mpp::global". Voir
Variables Makefile pour les détails.

Chacune des instructions (ifperl / ifmakeperl, perl / makeperl, sub / makesub), le
fonctions (perl / makeperl, map / makemap) et l'action de règle (perl / makeperl) pour
écrire du code Perl directement dans le makefile se présente sous deux formes. Le premier est absolument
Perl normal, ce qui signifie que vous devez utiliser le préfixe "f_" comme expliqué dans la section suivante, si
vous voulez appeler les fonctions makepp. La deuxième variante passe d'abord l'instruction par
Extension de variable de style Make, ce qui signifie que vous devez doubler les "$" que vous voulez que Perl voit.

La gestion de la fin est spéciale car les données énormes de makepp (selon votre système de construction)
les structures mettraient plusieurs secondes à ramasser les ordures avec une sortie normale. Alors on fait un
sortie par force brute. Dans le processus principal, vous pouvez toujours avoir des blocs "END", mais si vous en avez
descripteurs de fichiers globaux, ils peuvent ne pas être vidés. Mais vous devriez utiliser le lexique moderne
les descripteurs de fichiers, qui se ferment correctement lorsqu'ils sortent de la portée.

Dans le code Perl exécuté directement en tant qu'action de règle ou via une commande que vous définissez, c'est le
contraire. Les blocs "END" ne seront pas exécutés, mais les descripteurs de fichiers globaux seront vidés pour vous. Les
"DÉTRUIRE" des objets globaux ne sera jamais exécuté.

L'ajout de neufs textuel fonctions
Vous pouvez ajouter une nouvelle fonction au répertoire de makepp en définissant simplement un sous-programme Perl de
le même nom mais avec un préfixe de "f_". Par exemple:

sous f_myfunc {
mon $argument = &arg; # Nommez l'argument.
my( undef, $mkfile, $mkfile_line ) = @_; # Nommez les arguments.

... faites quelque chose ici

return $ return_value;
}

XYZ := $(myfunc mes arguments func)

Si votre fonction ne prend aucun argument, il n'y a rien à faire. Si votre fonction prend un
argument, comme dans l'exemple ci-dessus, utilisez l'accesseur simple &arg pour l'obtenir. Si tu
attendez-vous à plus d'arguments, vous avez besoin de l'accesseur plus complexe "args" décrit ci-dessous.

Ces accesseurs traitent les trois mêmes paramètres qui doivent être passés à n'importe quel "f_"
fonction, à savoir les arguments de la fonction, l'objet makefile et un descripteur de ligne pour
messages. Par conséquent, vous pouvez utiliser la forme efficace &arg dans le premier cas.

L'accesseur &arg s'occupe de ce qui suit pour vous : Si les arguments étaient déjà
développé (par exemple pour trouver le nom de la fonction dans "$(my$(function) arg)" l'arg est
passé sous forme de chaîne et vient de revenir. Si l'argument a encore besoin d'être développé, c'est le
cas habituel, il s'agit plutôt d'une référence à une chaîne. L'accesseur &arg l'étend pour vous,
pour lequel il a besoin de l'objet makefile comme 2ème paramètre.

Si vous attendez plus d'arguments, éventuellement en nombre variable, le travail est effectué par "args".
Cet accesseur prend les mêmes 3 paramètres que arg, plus des paramètres supplémentaires :

max : nombre d'arguments (par défaut 2) : donnez ~0 (maxint) pour l'infini
min : nombre d'arguments (par défaut 0 si max est ~0, sinon identique à max)
only_comma: ne mange pas d'espace autour des virgules, habituel pour les non-noms de fichiers

Au plus max, mais au moins min, les virgules présentes avant l'expansion sont utilisées pour diviser le
arguments. Quelques exemples des fonctions intégrées de makepp :

my( $prefix, $text ) = args $_[0], $_[1], $_[2], 2, 2, 1; # ajouter un préfixe
pour mon $cond ( args $_[0], undef, $_[2], ~0 ) ... # et, ou
mon @args= args $_[0], $_[1], $_[2], ~0, 1, 1 ; # appel
my( $filters, $words ) = args $_[0], $_[1], $_[2]; # filtre

La fonction doit renvoyer une chaîne scalaire (pas un tableau) qui est ensuite insérée dans le
texte à ce moment-là.

Si votre fonction rencontre une erreur, elle devrait mourir en utilisant l'instruction Perl die habituelle.
Cela sera piégé par makepp et un message d'erreur affichant le nom du fichier et la ligne
le numéro de l'expression à l'origine de l'erreur sera imprimé.

Il n'y a essentiellement aucune limite à ce que la fonction peut faire ; vous pouvez accéder au fichier, exécutez
commandes shell, etc.

Actuellement, les expressions apparaissant dans les dépendances et dans les actions de règle sont développées
une fois tandis que les expressions apparaissant dans les cibles sont développées deux fois, alors soyez prudent si votre
La fonction a des effets secondaires et est présente dans une expression pour une cible.

Notez que l'environnement (en particulier, le cwd) dans lequel la fonction évalue sera
correspondent pas nécessairement à l'environnement dans lequel les règles du Makefile dans lequel le
fonction a été évaluée sont exécutées. Si c'est un problème pour vous, alors votre fonction
devrait probablement ressembler à ceci :

sous f_foo {

chdir $makefile->{CWD} ;

...etc.
}

Putting fonctions développement a Perl module
Si vous placez des fonctions dans un fichier d'inclusion, vous aurez une copie par Makeppfile qui
l'utilise. Pour éviter cela, vous pouvez les écrire comme un module Perl normal avec un "Exporter"
interface, et utilisez-la. Cela chargera plus rapidement et économisera de la mémoire :

perl { utiliser mon module }
perle {
utiliser mon::module; # put : sur une nouvelle ligne donc ce n'est pas parsé en règle générale
}

Si vous avez besoin de l'une des fonctions normalement disponibles dans un Makefile (comme le "f_"
fonctions, "arg" ou "args"), vous devez mettre cette ligne dans votre module :

utiliser Mpp::Subs ;

L'inconvénient est que le module serait dans un package différent d'une fonction directement
apparaissant dans un makefile. Il faut donc tout passer en paramètre, ou construire
noms avec la fonction "appelant" de Perl.

appel externe Perl scripts
Si vous appelez un script Perl externe via "system", ou en règle générale, makepp créera un fork
nouveau processus (sauf s'il s'agit de la dernière action de règle) et lancez un tout nouvel interpréteur perl.
Il n'y a rien de mal à cela, sauf qu'il existe un moyen plus efficace :

&commander arguments...
Cela peut être une action de règle. Il appellera une fonction commander avec un préfixe "c_", et
transmettez-lui le reste (style makepp éventuellement cité - pas exactement le même que
Shell). Si une telle fonction ne peut pas être trouvée, cela passe toutes les chaînes à
"Cours".

sub c_mycmd { mon @args = @_; ... }

$(phony callcmd) :
&mycmd 'arg with space' arg2 "arg3" # appelle c_mycmd

%.out : %in
&myscript -o $(output) $(input) # appelle mon script externe

Vous pouvez écrire vos commandes dans le cadre des builtins, vous permettant d'utiliser
les mêmes options standard qu'ils ont, et la gestion des E/S qu'ils offrent.

L'opérateur de bloc "Mpp::Cmds::frame" est suivi d'une liste d'options à une seule lettre de
les commandes intégrées (au maximum "qw(fi I ​​o O rs)"). Même si vous spécifiez votre propre option
en remplaçant l'un d'eux, vous donnez toujours la seule lettre de l'option standard.

Chaque propre option est spécifiée comme "[qw(n name), \$réf, argument, sous]". Les deux premiers
les éléments sont des noms courts et longs, suivis de la référence de la variable et éventuellement de
un booléen pour savoir s'il faut prendre un argument. Sans argument, la variable est
incrémenté à chaque fois que l'option est donnée, sinon la valeur de l'option y est stockée.

sub c_my_ocmd { # Cas de sortie typique
local @ARGV = @_ ;
Mpp::Cmds::frame {

... imprimez quelque chose ici avec @ARGV, avec les options déjà supprimées automatiquement

} 'f', qw(o O);
}

sub c_my_icmd { # Cas d'entrée typique avec 2 options
local @ARGV = @_ ;
my( $court, $long );
Mpp::Cmds::frame {

... faites quelque chose ici avec <>

} qw(i I rs), # s spécifie uniquement --separator, pas -s
[qw(s short), \$short], # Aucune option arg -> $short == 1
[qw(l long), \$long, 1, sub { warn "got arg $long"}] ;
}

Voici une commande simple qui ne met en évidence que le premier caractère de chaque entrée
enregistrement (équivalent à "&sed '$$_ = "\u\L$$_"'") :

sous c_uc {
local @ARGV = @_ ;
Mpp::Cmds::frame {
print "\u\L$_" while <> ;
} 'f', qw(i I o O rs);
}

Dans le bloc géré par image, vous pouvez avoir des blocs imbriqués pour effectuer des tâches critiques
opérations, comme l'ouverture d'autres fichiers.

Mpp::Cmds::perform { ... } 'message';

Cela produira un message avec "--verbose" (que chaque commande accepte) ssi le
la commande est exécutée avec succès. Mais si le bloc est évalué comme faux, il meurt avec
message nié.

courir scénario arguments...
Il s'agit d'une fonction Perl normale que vous pouvez utiliser dans n'importe quel contexte Perl dans votre makefile.
Il est similaire à la forme multi-arguments du système, mais il exécute le script Perl dans
le processus en cours. Pour les instructions makepp, la fonction perl ou vos propres fonctions
c'est le processus qui exécute makepp. Mais pour une règle qui est le sous-processus exécutant
ce. Le script est analysé autant de fois qu'il est appelé, mais vous pouvez mettre le vrai
travailler dans une bibliothèque, comme le fait pod2html. Cette bibliothèque peut ensuite être utilisée au niveau supérieur, donc
qu'il est déjà présent :

perl { use mylib } # est redirigé vers toutes les règles qui n'ont pas besoin de l'analyser

%.out : %in
makeperl { exécuter qw'myscript -o $(output) $(input)' }

Si le script appelle "exit", ferme les descripteurs de fichiers standard ou s'appuie sur le système
pour nettoyer après (fichiers ouverts, mémoire...), cela peut être un problème avec "run". Si
vous appelez "run" dans les instructions ou la fonction perl, makepp peut être perturbé ou le
le nettoyage n'a lieu qu'à la fin de makepp.

Si vous rencontrez l'un des problèmes susmentionnés, exécutez le script en externe, c'est-à-dire à partir de
la ligne de commande à la place. Dans une règle, le nettoyage est moins un problème, surtout pas
comme dernière action d'une règle, puisque le sous-processus de règle se terminera de toute façon par la suite,
sauf sous Windows.

Écriture Un flux efficace peut augmenter propre Signature méthodes
Parfois, vous voulez que makepp calcule une méthode de signature en utilisant une technique différente. Pour
exemple, supposons que vous ayez un binaire qui dépend d'une bibliothèque partagée. Normalement, si vous
changer la bibliothèque partagée, vous n'avez pas à relier les exécutables qui en dépendent car
la liaison est effectuée au moment de l'exécution. (Cependant, il est possible que la reconnexion de l'exécutable
peut être nécessaire, c'est pourquoi je n'en ai pas fait par défaut.) Ce que vous voulez makepp
faire est d'avoir la même signature pour la bibliothèque partagée même si elle change.

Ceci peut être accompli de plusieurs manières. Le moyen le plus simple est de créer votre propre nouveau
méthode de signature (appelons-la "shared_object"). Vous utiliseriez cette méthode de signature
uniquement sur les règles qui relient les binaires, comme ceci :

monprogramme : *.o lib1/lib1.so lib2/lib2.so
: signature objet_partagé
$(CC) $(entrées) -o $(sortie)

Nous devons maintenant créer la méthode de signature.

Toutes les méthodes de signature doivent être leur propre classe, et la classe doit contenir quelques
articles (voir Mpp/Signature.pm dans la distribution pour plus de détails). Le nom de la classe doit être
préfixé par "Mpp::Signature ::", donc dans ce cas notre classe devrait être appelée
"Mpp::Signature::shared_object". Nous devons créer un fichier appelé objet_partagé.pm et met
en un Député::Signature répertoire quelque part dans le chemin d'inclusion de Perl ; l'endroit le plus facile
peut-être dans le Député/Signature répertoire dans l'installation makepp (par exemple,
/usr/local/share/makepp/Mpp/Signature ou partout où vous l'avez installé).

Pour des détails précis sur ce qui doit aller dans cette classe, vous devriez regarder attentivement
le fichier Mpp/Signature.pm et probablement aussi Mpp/Signature/correspondance_exacte.pm dans le makepp
Distribution. Mais dans notre cas, tout ce que nous voulons faire, c'est apporter une toute petite modification à un
mécanisme de signature existant; si le fichier est une bibliothèque partagée, nous voulons avoir une constante
signature, alors que si le fichier est autre chose, nous voulons nous fier à la normale de makepp
mécanisme de signature. La meilleure façon de le faire est d'hériter de
"Mpp::Signature::c_compilation_md5", qui est la méthode de signature qui est généralement choisie
lorsque makepp reconnaît une commande de lien.

Donc le fichier Mpp/Signature/shared_object.pm peut contenir les éléments suivants :

utiliser strict;
package Mpp::Signature::shared_object;
utiliser Mpp::Signature::c_compilation_md5;
notre @ISA = qw(Mpp::Signature::c_compilation_md5) ; # Indiquer l'héritage.
notre $shared_object = bénir \@ISA; # Un morceau de magie qui aide makepp à trouver
# les sous-routines pour cette méthode. Tous
# méthode de signature doit en avoir une.
# La valeur n'est pas utilisée, n'importe quel objet.
# Maintenant, voici la méthode qui est appelée lorsque nous avons besoin de la signature de
# toute cible ou dépendance pour laquelle cette méthode de signature est active :
sous-signature {
my ($self, # Ce sera le même que $shared_object.
$finfo) = @_; # Une structure spéciale qui contient tout
# makepp connaît ce fichier. Voir
# Mpp/File.pm pour plus de détails.

if ($finfo->{NAME} =~ /\.s[oa]$/) { # Le nom du fichier se termine-t-il par .so ou .sa ?
return $finfo->file_exists ? 'existe' : '';
# Renvoie toujours la même signature si le fichier
# existe. Dans ce cas, la signature est le
# chaîne "existe".
}

Mpp::Signature::c_compilation_md5::signature;
# Si le fichier ne se termine pas par .so ou .sa,
# délégue à la méthode de signature habituelle de makepp.
}

Ce fichier est fourni à titre d'exemple dans la distribution makepp, avec quelques
commentaires.

Incidemment, pourquoi n'en faisons-nous pas la valeur par défaut ? Eh bien, il y a des moments où changer un
bibliothèque partagée nécessitera une reconnexion de votre programme. Si jamais vous changez le
symboles qu'une bibliothèque partagée définit, ou les symboles dont elle dépend d'autres bibliothèques
car, une reconnexion peut parfois être nécessaire.

Supposons, par exemple, que la bibliothèque partagée invoque des sous-programmes que votre programme
fournit. Par exemple, supposons que vous modifiez la bibliothèque partagée pour qu'elle appelle maintenant un
sous-programme "xyz()". Sauf si vous utilisez l'option "-E" ou "--export-dynamic" pour l'éditeur de liens
(pour GNU binutils ; d'autres éditeurs de liens ont des noms d'options différents), le symbole "xyz()" peut ne pas
être accessible à l'éditeur de liens d'exécution même s'il existe dans votre programme.

Pire encore, supposons que vous ayez défini "xyz()" dans une autre bibliothèque (appelez-la libxyz), comme ça:

mon_programme : main.o lib1/lib1.so xyz/libxyz.a

Puisque "libxyz" est un .a fichier et non un .so fichier, alors "xyz()" ne peut pas être extrait
correctement de libxyz.a à moins que vous ne reliiez votre binaire.

Les méthodes Mpp::Signature contrôlent également non seulement la chaîne utilisée pour déterminer si un
fichier a changé, mais l'algorithme utilisé pour comparer les chaînes. Par exemple, le
la méthode de signature "target_newer" dans la distribution makepp nécessite simplement que le
les cibles soient plus récentes que les dépendances, alors que la méthode de signature "exact_match" (et
tout ce qui en dépend, comme "md5" et "c_compilation_md5") nécessite que le
fichier ont la même signature que sur la dernière version.

Voici quelques autres types de méthodes de signature qui pourraient être utiles, pour vous aider à réaliser
les possibilités. Si l'usage est suffisamment général, certains d'entre eux peuvent éventuellement être
incorporé dans makepp :

· Une méthode de signature pour les bibliothèques partagées qui renvoie une somme de contrôle de tous les
symboles, ainsi que tous les symboles dont il a besoin d'autres bibliothèques. Cela résout le
problème avec l'exemple ci-dessus, et garantit un lien correct en toutes circonstances.
Une tentative expérimentale a été faite pour le faire dans la distribution makepp (voir
Mpp/Signature/shared_object.pm), mais cela ne fonctionnera qu'avec GNU binutils et ELF
bibliothèques en ce moment.

· Une méthode de signature qui ignore un horodatage écrit dans un fichier. Par exemple, si vous
générer un .c fichier automatiquement en utilisant un programme qui insiste pour mettre une chaîne
dans comme ça :

static char * date_stamp = "Généré automatiquement le 01 avril 2004 par personne" ;

vous pouvez écrire une méthode de signature qui ignore spécifiquement les changements d'horodatage.
Ainsi, si l'horodatage est la seule chose qui a changé, makepp ne reconstruira pas.

· Une méthode de signature qui calcule les signatures de manière normale, mais ignore les
dépendance à l'architecture au moment de décider s'il faut reconstruire. Cela pourrait être utile pour
des fichiers véritablement indépendants de l'architecture ; actuellement si vous construisez sur une architecture,
makepp insistera pour reconstruire même les fichiers indépendants de l'architecture lorsque vous basculez
à une architecture différente.

· Une méthode de signature qui sait ignorer les commentaires dans les fichiers latex, comme le
La méthode "c_compilation_md5" sait comment ignorer les commentaires dans les fichiers C.

· Une méthode de signature pour l'extraction automatique de la documentation qui ne fait que les sommes de contrôle
commentaires dont un extracteur de documentation a besoin et ignore les autres modifications apportées à la source
fichier.

Inachevé
Ce document n'est pas encore terminé. Il devrait couvrir comment écrire vos propres scanners pour
inclure des fichiers et des choses comme ça.

Utilisez makepp_extending en ligne à l'aide des services onworks.net


Serveurs et postes de travail gratuits

Télécharger des applications Windows et Linux

Commandes Linux

Ad