AnglaisFrançaisEspagnol

Ad


Icône de favori OnWorks

inconvénients - En ligne dans le Cloud

Exécutez les inconvénients 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 contre-commande qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks en utilisant 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


Inconvénients - Un système de construction de logiciels

DESCRIPTION


Un guide et une référence pour la version 2.2.0

Copyright (c) 1996-2000 Free Software Foundation, Inc.

Ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier selon les termes de
la licence publique générale GNU telle que publiée par la Free Software Foundation ; Soit
la version 2 de la licence ou (à votre choix) toute version ultérieure.

Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ;
sans même la garantie implicite de QUALITÉ MARCHANDE ou D'ADAPTATION À UN USAGE PARTICULIER.
Voir la licence publique générale GNU pour plus de détails.

Vous devriez avoir reçu une copie de la licence publique générale GNU avec ce programme ;
voir le fichier COPIE. Sinon, écrivez à la Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, États-Unis.

Introduction


Inconvénients est un système pour construire, principalement, un logiciel, mais est assez différent de
systèmes de construction de logiciels précédents. Inconvénients a été conçu dès le départ pour faire face
facilement avec la construction de logiciels répartis sur plusieurs répertoires sources. Les inconvénients
facilite la création de scripts de construction simples, compréhensibles et maintenables.
Les inconvénients garantissent que les logiciels complexes sont facilement et précisément reproductibles.

Cons utilise un certain nombre de techniques pour accomplir tout cela. Les scripts de construction sont juste
des scripts Perl, ce qui les rend à la fois faciles à comprendre et très flexibles. Portée mondiale de
variables est remplacée par un mécanisme d'import/export pour le partage d'informations entre
scripts, améliorant considérablement la lisibilité et la maintenabilité de chaque script.
Construction environnements sont introduits : ce sont des objets Perl qui capturent le
informations requises pour contrôler le processus de construction. Plusieurs environnements sont utilisés
lorsque différentes sémantiques sont requises pour générer des produits dans l'arborescence de construction. Les inconvénients
implémente une analyse de dépendance automatique et l'utilise pour séquencer globalement l'ensemble
construire. Les versions de variantes sont facilement produites à partir d'une seule arborescence source. Construction intelligente
un sous-ensemble est possible, lorsque vous travaillez sur des modifications localisées. Des dérogations peuvent être configurées pour
remplacer facilement les instructions de construction sans modifier aucun script. cryptographique MD5
signatures sont associés à des fichiers dérivés et sont utilisés pour déterminer avec précision si
un fichier donné doit être reconstruit.

Tout en offrant tout ce qui précède, et plus encore, Cons reste simple et facile à utiliser. Cette volonté,
espérons que cela devienne clair en lisant le reste de ce document.

Constat Les inconvénients? Constat ne sauraient Faire?


L'inconvénient est un faire remplacement. Dans les paragraphes suivants, nous examinons quelques-uns des
caractéristiques indésirables de make--et des environnements de construction typiques basés sur make--qui
motivé le développement de Cons.

Développer complexité

Les systèmes traditionnels basés sur les marques, quelle que soit leur taille, ont tendance à devenir assez complexes. La marque originale
l'utilité et ses dérivés ont contribué à cette tendance de plusieurs manières. Faire est
pas bon pour gérer des systèmes répartis sur plusieurs répertoires. Divers travaux-
des contours sont utilisés pour surmonter cette difficulté; le choix habituel est de faire invoquer
lui-même de manière récursive pour chaque sous-répertoire d'un build. Cela conduit à un code compliqué, en
dont on ne sait souvent pas comment une variable est définie, ou quel effet le réglage d'une variable
aura sur la construction dans son ensemble. Le langage de script make a été progressivement étendu
pour offrir plus de possibilités, mais celles-ci ont largement servi à encombrer un déjà
langage trop étendu. Souvent, les constructions sont effectuées en plusieurs passes afin de fournir
produits appropriés d'un répertoire à un autre. Cela représente une autre
augmentation de la complexité de construction.

Développer reproductibilité

Le fléau de toutes les marques a toujours été la gestion correcte des dépendances. Le plus souvent, un
une tentative est faite pour faire un travail raisonnable de dépendances dans un seul répertoire, mais aucun
une tentative sérieuse est faite pour faire le travail entre les répertoires. Même lorsque les dépendances sont
fonctionne correctement, faites confiance à une simple comparaison d'horodatage pour déterminer si
un dossier est obsolète en ce qui concerne ses personnes à charge n'est pas, en général, adéquat pour
déterminer quand un fichier doit être redérivé. Si une bibliothèque externe, par exemple, est
reconstruit puis « mis en place », les horodatages de ses fichiers nouvellement créés peuvent
bien être plus tôt que la dernière construction locale, puisqu'elle a été construite avant qu'elle ne devienne visible.

Variante construit

Make ne fournit que des fonctionnalités limitées pour gérer les versions de variantes. Avec la prolifération
des plates-formes matérielles et le besoin d'un code débogué par rapport à un code optimisé, la capacité de
créer facilement ces variantes est essentiel. Plus important encore, si des variantes sont créées, il
est important soit de pouvoir séparer les variantes, soit de pouvoir reproduire les
original ou variante à volonté. Avec make, il est très difficile de séparer les builds en
plusieurs répertoires de construction, séparés de la source. Et si cette technique n'est pas utilisée,
il est également pratiquement impossible de garantir à tout moment quelle variante est présente dans
l'arbre, sans recourir à une reconstruction complète.

Dépôts

Make ne fournit qu'un support limité pour la création de logiciels à partir de code existant dans un
structure de répertoire du référentiel central. La fonctionnalité VPATH de GNU make (et quelques autres
make implements) est destiné à fournir cela, mais ne fonctionne pas comme prévu : il
modifie le chemin du fichier cible vers le nom VPATH trop tôt dans son analyse, et donc
recherche toutes les dépendances dans le répertoire VPATH. Pour assurer un développement correct
builds, il est important de pouvoir créer un fichier dans un répertoire de build local et d'avoir
tous les fichiers dans un référentiel de code (un répertoire VPATH, en termes de make) qui dépendent du local
fichier est reconstruit correctement. Ce n'est pas possible avec VPATH, sans coder beaucoup de
connaissances du référentiel complexe directement dans les makefiles.

En gardant it simple


Quelques-unes des difficultés avec make ont été citées ci-dessus. Dans ce et les suivants
sections, nous présenterons les inconvénients et montrerons comment ces problèmes sont abordés.

Perl scripts

Cons est basé sur Perl. C'est-à-dire, les scripts Contre--Conscrit ainsi que Construire fichiers, l'équivalent
à Makefile or makefile--sont tous écrits en Perl. Cela procure un avantage immédiat : la
langage pour écrire des scripts est familier. Même si vous n'êtes pas un Perl
programmeur, il est utile de savoir que Perl n'est fondamentalement qu'un simple langage déclaratif,
avec un flux de contrôle bien défini et une sémantique familière. Il a des variables qui se comportent
essentiellement la façon dont vous vous attendez à ce qu'ils le fassent, les sous-programmes, le flux de contrôle, etc. Là
n'y a pas de syntaxe spéciale introduite pour Cons. L'utilisation de Perl comme langage de script
simplifie la tâche d'exprimer la solution appropriée au problème souvent complexe
exigences d'une construction.

Bonjour, Monde!

Pour fonder la discussion suivante, voici comment vous pourriez construire le Bonjour, Monde! C
application avec Inconvénients :

$env = nouveau cons();
Programmez $env 'hello', 'hello.c';

Si vous installez ce script dans un répertoire, nommez le script Construireet créez le
Bonjour c source dans le même répertoire, vous pouvez alors taper " contre bonjour " pour construire le
demande:

% contre bonjour
cc -c bonjour.c -o bonjour.o
cc -o bonjour bonjour.o

Construction environnements

Une simplification clé de Cons est l'idée d'un construction sûr, heureux et sain. Un chantier
l'environnement est un objet caractérisé par un ensemble de paires clé/valeur et un ensemble de méthodes.
Afin de dire à Cons comment construire quelque chose, vous invoquez la méthode appropriée via un
environnement de construction approprié. Considérez l'exemple suivant :

$env = nouveau contre(
CC => 'gcc',
LIBS => 'libworld.a'
);

Programmez $env 'hello', 'hello.c';

Dans ce cas, plutôt que d'utiliser l'environnement de construction par défaut, tel quel, nous avons
a remplacé la valeur de `CC' afin que l'équivalent du compilateur GNU C soit utilisé à la place. Puisque
cette version de Bonjour, Monde! nécessite une bibliothèque, libworld.a, nous avons précisé que tout
le programme lié dans cet environnement doit être lié à cette bibliothèque. Si la bibliothèque
existe déjà, très bien, mais sinon, nous devrons également inclure la déclaration :

Bibliothèque $env 'libworld', 'world.c';

Maintenant, si vous tapez " contre bonjour ", la bibliothèque sera construite avant que le programme ne soit lié, et,
bien sûr, `gcc' sera utilisé pour compiler les deux modules :

% contre bonjour
gcc -c bonjour.c -o bonjour.o
gcc -c monde.c -o monde.o
ar r libworld.a monde.o
ar : création de libworld.a
ranlib libworld.a
gcc -o bonjour bonjour.o libworld.a

Automatique ainsi que complet dépendance selon une analyse de l’Université de Princeton

Avec Cons, les dépendances sont gérées automatiquement. En reprenant l'exemple précédent, notez
que lorsque nous modifions monde.c, monde.o est recompilé, libworld.a recréé, et hello
reconnecté :

% vi monde.c
[EDIT]
% contre bonjour
gcc -c monde.c -o monde.o
ar r libworld.a monde.o
ar : création de libworld.a
ranlib libworld.a
gcc -o bonjour bonjour.o libworld.a

C'est un exemple relativement simple : Contre ``sait'' monde.o dépend monde.c, Parce
la dépendance est explicitement configurée par la méthode `Library'. Il sait aussi que libworld.a
dépend monde.o et que hello dépend libworld.a, le tout pour des raisons similaires.

Maintenant, il s'avère que Bonjour c inclut également le fichier de définition d'interface, monde.h:

% monde emacs.h
[EDIT]
% contre bonjour
gcc -c bonjour.c -o bonjour.o
gcc -o bonjour bonjour.o libworld.a

Comment Cons sait-il que Bonjour c inclut monde.h, Et Ce bonjour.o doit donc être
recompilé ? Pour l'instant, qu'il suffise de dire que lorsqu'on se demande si oui ou non bonjour.o est en place-
à ce jour, Cons invoque un scanner pour sa dépendance, Bonjour c. Ce scanner énumère les
fichiers inclus par Bonjour c pour dresser une liste d'autres dépendances, au-delà de celles
rendu explicite par le script Cons. Ce processus est récursif : tous les fichiers inclus par
les fichiers inclus seront également analysés.

N'est-ce pas cher? La réponse est - cela dépend. Si vous faites une construction complète d'un grand système,
le temps de balayage est insignifiant. Si vous effectuez une reconstruction d'un grand système, alors Cons
passer pas mal de temps à y réfléchir avant de décider que rien ne doit être
fait (mais pas nécessairement plus de temps que de faire !). La bonne nouvelle est que Cons le fait
très facile de sous-ensemble intelligemment votre build, lorsque vous travaillez sur des modifications localisées.

Automatique de défis construire séquençage

Parce que Cons effectue une analyse de dépendance complète et précise, et le fait globalement, pour le
l'ensemble de la construction, Cons est en mesure d'utiliser ces informations pour prendre le contrôle total de la séquençage
de la construction. Ce séquençage est évident dans les exemples ci-dessus, et est équivalent à ce que
vous attendez pour make, étant donné un ensemble complet de dépendances. Avec Cons, cela s'étend
trivialement aux versions plus grandes et multi-répertoires. En conséquence, toute la complexité impliquée
en s'assurant qu'une construction est organisée correctement - y compris hiérarchique multi-passes
construit - est éliminé. Nous en discuterons plus en détail dans les sections suivantes.

Développement gros arbres - encore juste as simple


A hiérarchie of construire scripts

Un build plus grand, dans Cons, est organisé en créant une hiérarchie de construire scripts. Au sommet
de l'arbre est un script appelé Construire. Le reste des scripts, par convention, sont chacun
appelé Conscrit. Ces scripts sont reliés entre eux, très simplement, par le `Build',
Commandes « Exporter » et « Importer ».

La Développer commander

La commande `Build' prend une liste de Conscrit les noms de fichiers et s'arrange pour qu'ils soient
inclus dans la construction. Par example:

Construire qw(
chauffeurs/affichage/appelé
pilotes/souris/appelé
analyseur/conscrit
services publics/appelé
);

Il s'agit d'une simple hiérarchie à deux niveaux de scripts de construction : tous les Conscrit fichiers
sont mentionnés au plus haut niveau Construire déposer. Notez que tous les répertoires de l'arborescence
ont nécessairement des scripts de construction qui leur sont associés.

Cela pourrait également être écrit comme un script à plusieurs niveaux. Par exemple, le Construire fichier pourrait
contient cette commande :

Construire qw(
analyseur/conscrit
chauffeurs/appelés
services publics/appelé
);

et par Conscrit déposer dans le conducteurs répertoire peut contenir ceci :

Construire qw(
afficher/appelé
souris/appelé
);

L'expérience a montré que le premier modèle est un peu plus facile à comprendre, puisque le
tout l'arbre de construction est disposé devant vous, au plus haut niveau. Les schémas hybrides sont
aussi possible. Un composant maintenu séparément qui doit être incorporé dans un
l'arbre de construction, par exemple, peut s'accrocher à l'arbre de construction à un endroit, mais définir le sien
hiérarchie de construction.

Par défaut, Cons ne remplace pas son répertoire de travail par le répertoire contenant un
filiale Conscrit fichier qu'il comprend. Ce comportement peut être activé pour une génération en
spécifiant, au niveau supérieur Construire fichier:

Conscrit_chdir 1;

Lorsqu'il est activé, Cons deviendra la filiale Conscrit répertoire contenant le fichier
lors de la lecture dans ce fichier, puis revenez au répertoire de niveau supérieur une fois le fichier
a été traité.

On s'attend à ce que ce comportement devienne la valeur par défaut dans une future version de Cons.
Pour se préparer à cette transition, les builds qui s'attendent à ce que les inconvénients restent au sommet de la build
pendant qu'il lit dans une filiale Conscrit fichier doit explicitement désactiver cette fonctionnalité car
suit:

Conscrit_chdir 0;

Relatif, parent supérieur, ainsi que absolu filet noms

Vous avez peut-être remarqué que les noms de fichiers spécifiés dans la commande Build sont relatifs à
l'emplacement du script à partir duquel il est invoqué. Ceci est généralement vrai pour les autres noms de fichiers
arguments à d'autres commandes aussi, bien que nous puissions aussi bien mentionner ici que si vous commencez
un nom de fichier avec un dièse, ``#'', alors ce fichier est interprété par rapport au top-
répertoire de niveau (où le Construire le fichier réside). Et, sans surprise, si vous le commencez
avec ``/'', alors il est considéré comme un chemin d'accès absolu. Ceci est vrai même sur les systèmes
qui utilisent une barre oblique inverse plutôt qu'une barre oblique pour nommer les chemins absolus.

En utilisant modules in construire scripts

Vous pouvez tirer des modules dans chaque Conscrit fichier utilisant le Perl normal `use' ou `require'
déclarations:

utiliser l'anglais;
nécessite My::Module;

Chaque « utilisation » ou « exiger » n'affecte que celui Conscrit fichier dans lequel il apparaît. Pour utiliser un
module en plusieurs Conscrit fichiers, vous devez mettre une instruction `use' ou `require' dans chaque
celui qui a besoin du module.

Domaine of les variables

Le haut niveau Construire fichier et tout Conscrit les fichiers commencent leur vie dans un Perl commun et séparé
paquet. Inconvénients contrôle la table des symboles pour le package de sorte que, la table des symboles pour
chaque script est vide, à l'exception du Construire fichier, qui obtient une partie de la ligne de commande
arguments. Toutes les variables définies ou utilisées sont donc définies par le script
lui-même--pas par un script externe.

Les variables peuvent être explicitement importé par un script de son script parent. Pour importer un
variable, il doit avoir été exporté par le parent et initialisé (sinon une erreur
se produira).

La Exportations commander

La commande « Exporter » est utilisée comme dans l'exemple suivant :

$env = nouveau cons();
$INCLUDE = "#export/include" ;
$LIB = "#export/lib" ;
Exporter qw( env INCLUDE LIB );
Construire qw( util/Conscript );

Les valeurs des variables simples mentionnées dans la liste « Exporter » seront éliminées
par toutes les commandes "Build" suivantes. La commande « Exporter » n'exportera que Perl scalaire
variables, c'est-à-dire des variables dont le nom commence par `$'. Autres variables, objets, etc.
peut être exporté par référence - mais tous les scripts feront référence au même objet, et cela
objet doit être considéré comme en lecture seule par les scripts subsidiaires et par l'original
script d'exportation. Il est toutefois acceptable d'affecter une nouvelle valeur au scalaire exporté
variable - qui ne changera pas la variable sous-jacente référencée. Cette séquence, pour
exemple, est OK :

$env = nouveau cons();
Exporter qw( env INCLUDE LIB );
Construire qw( util/Conscript );
$env = new cons(CFLAGS => '-O');
Construire qw( autre/Conscrit );

Peu importe que la variable soit définie avant ou après la commande « Exporter ». le
la chose importante est la valeur de la variable au moment où la commande `Build' est exécutée.
C'est ce qui s'en va. Soit dit en passant, toutes les commandes « Exporter » ultérieures,
invalider la première : vous devez mentionner toutes les variables que vous souhaitez exporter sur chaque
Commande « Exporter ».

La L’ commander

Les variables exportées par la commande 'Exporter' peuvent être importées dans des scripts subsidiaires par le
Commande « Importer ». Le script subsidiaire importe toujours les variables directement depuis le
scénario supérieur. Considérez cet exemple :

Importer qw( env INCLUDE );

Ceci n'est légal que si le script parent a exporté à la fois `$env' et `$INCLUDE'. Il doit également
ont donné à chacune de ces variables des valeurs. Il est normal que le script subsidiaire ne
importer un sous-ensemble des variables exportées (dans cet exemple, '$LIB', qui a été exporté par
l'exemple précédent, n'est pas importé).

Toutes les variables importées sont automatiquement réexportées, donc la séquence :

Importer qw ( env INCLUDE );
Build qw ( under-me/Conscript );

fournira à la fois `$env' et `$INCLUDE' au fichier subsidiaire. Si seulement `$env' doit être
exporté, alors ce qui suit suffira :

Importer qw ( env INCLUDE );
Exporter qw ( env );
Build qw ( under-me/Conscript );

Inutile de dire que les variables peuvent être modifiées localement avant d'appeler `Build' sur le
scénario subsidiaire.

Développer scénario évaluation de commander

La seule contrainte sur l'ordre des scripts de build est que les scripts supérieurs sont
évalués avant leurs scripts inférieurs. Le haut niveau Construire fichier, par exemple, est
évalué en premier, suivi de tous les scripts inférieurs. C'est tout ce que vous devez vraiment savoir
sur l'ordre d'évaluation, puisque l'ordre n'est généralement pas pertinent. Considérer ce qui suit
Commande « Construire » :

Construire qw(
chauffeurs/affichage/appelé
pilotes/souris/appelé
analyseur/conscrit
services publics/appelé
);

Nous avons choisi de mettre les noms de script par ordre alphabétique, simplement parce que c'est le plus
pratique pour l'entretien. La modification de la commande ne fera aucune différence pour le
construire.

A Modèle en partage fichiers


Certain simple conventions

Dans tout système logiciel complexe, une méthode de partage des produits de construction doit être
établi. Nous proposons un ensemble simple de conventions qui sont triviales à mettre en œuvre avec
Inconvénients, mais très efficace.

La règle de base est d'exiger que tous les produits de construction qui doivent être partagés entre
les répertoires sont partagés via un répertoire intermédiaire. Nous avons généralement appelé cela
Exporter, et, dans un environnement C, fourni des sous-répertoires classiques de ce répertoire,
tel que comprendre, lib, coffre, etc.

Ces répertoires sont définis par le niveau supérieur Construire déposer. Un simple Construire fichier pour
a Bonjour, Monde! l'application, organisée à l'aide de plusieurs répertoires, pourrait ressembler à ceci :

# Construire un fichier pour Hello, World!

# Où mettre tous nos produits partagés.
$EXPORT = '#export';

Exporter qw( CONS INCLUDE LIB BIN );

# Répertoires standard pour partager des produits.
$INCLUDE = "$EXPORT/inclure" ;
$LIB = "$EXPORT/lib" ;
$BIN = "$EXPORT/bin" ;

# Un environnement de construction standard.
$CONS = nouveau contre (
CPPPATH => $INCLUDE, # Inclure le chemin pour les compilations C
LIBPATH => $LIB, # Chemin de la bibliothèque pour lier les programmes
LIBS => '-lworld', # Liste des bibliothèques standards
);

Construire qw(
bonjour/appelé
monde/appelé
);

La world l'annuaire Conscrit le fichier ressemble à ceci :

# Fichier de conscrit pour le monde des répertoires
Importer qw( CONS INCLUDE LIB );

# Installer les produits de ce répertoire
Installez $CONS $LIB, 'libworld.a' ;
Installez $CONS $INCLUDE, 'world.h' ;

# Produits internes
Bibliothèque $CONS 'libworld.a', 'world.c';

et par hello l'annuaire Conscrit le fichier ressemble à ceci :

# Fichier de conscrit pour le répertoire hello
Importer qw( CONS BIN );

# Produits exportés
Installez $CONS $BIN, 'bonjour' ;

# Produits internes
Programmez $CONS 'bonjour', 'bonjour.c' ;

Pour construire un Bonjour, Monde! programme avec cette structure de répertoires, allez au niveau supérieur
répertoire et invoquez `cons' avec les arguments appropriés. Dans l'exemple suivant, nous
dire à Cons de construire le répertoire Exporter. Pour construire un répertoire, Cons construit récursivement tout
produits connus dans ce répertoire (uniquement s'ils ont besoin d'être reconstruits, bien sûr). Si l'un des
ces produits dépendent d'autres produits dans d'autres répertoires, alors ceux-ci seront construits,
trop.

% contre export
Installez world/world.h comme export/include/world.h
cc -Iexport/include -c bonjour/bonjour.c -o bonjour/bonjour.o
cc -Iexport/include -c monde/monde.c -o monde/monde.o
ar r monde/libworld.a monde/monde.o
ar : création du monde/libworld.a
monde ranlib/libworld.a
Installez world/libworld.a comme export/lib/libworld.a
cc -o bonjour/bonjour bonjour/bonjour.o -Lexport/lib -lworld
Installez hello/hello en tant qu'export/bin/hello

Faire le ménage, compréhensible, indépendant de l'emplacement scripts

Vous remarquerez que les deux Conscrit les fichiers sont très propres et précis. Ils ont simplement
spécifier les produits de l'annuaire et comment construire ces produits. Les instructions de construction
sont minimes : ils précisent quel environnement de construction utiliser, le nom du produit,
et le nom des entrées. Notez également que les scripts sont indépendants de l'emplacement : si vous
souhaitez réorganiser votre arborescence des sources, vous êtes libre de le faire : vous n'avez qu'à changer le
Construire (dans cet exemple), pour spécifier les nouveaux emplacements du Conscrit des dossiers. le
l'utilisation d'une arborescence d'exportation rend cet objectif facile.

Notez également comment Cons s'occupe des petits détails pour vous. Tous les Exporter répertoires, pour
exemple, ont été créés automatiquement. Et les fichiers installés étaient vraiment liés en dur dans le
répertoires d'exportation respectifs, pour économiser de l'espace et du temps. Cette attention aux détails sauve
un travail considérable, et rend encore plus facile la production de scripts simples et maintenables.

Séparer la source ainsi que construire arbres


Il est souvent souhaitable de garder tous les fichiers dérivés de la construction complètement séparés du
fichiers source. Cela rend beaucoup plus facile de garder une trace de ce qu'est un fichier source, et
facilite également la prise en main variante builds, surtout si vous voulez que la variante builds
de coexister.

Séparer construire ainsi que la source répertoires en utilisant le Lien commander

Cons fournit un mécanisme simple qui gère toutes ces exigences. Le 'Lien'
la commande est appelée comme dans cet exemple :

Lien 'build' => 'src';

Les répertoires spécifiés sont ``liés'' au répertoire source spécifié. Supposons
que vous configurez un répertoire source, src, avec les sous-répertoires world ainsi que hello dessous,
comme dans l'exemple précédent. Vous pouvez ensuite remplacer les lignes de construction d'origine par le
Suivante à la suite:

Construire qw(
build/monde/Conscrit
build/bonjour/conscrit
);

Notez que vous traitez le Conscrit comme s'il existait dans le répertoire de construction. Maintenant si
vous tapez la même commande que précédemment, vous obtiendrez les résultats suivants :

% contre export
Installez build/world/world.h comme export/include/world.h
cc -Iexport/include -c build/hello/hello.c -o build/hello/hello.o
cc -Iexport/include -c build/monde/monde.c -o build/monde/monde.o
a r build/world/libworld.a build/world/world.o
ar : création de build/world/libworld.a
ranlib build/world/libworld.a
Installez build/world/libworld.a comme export/lib/libworld.a
cc -o build/bonjour/bonjour build/bonjour/bonjour.o -Lexport/lib -lworld
Installez build/hello/hello comme export/bin/hello

Encore une fois, Cons s'est occupé des détails pour vous. En particulier, vous remarquerez que tous
les constructions sont effectuées à l'aide de fichiers source et de fichiers objet du répertoire de construction. Pour
Par exemple, construire/monde/monde.o est compilé à partir de construire/monde/monde.cet
exporter/inclure/monde.h est installé à partir de construire/monde/monde.h. Ceci est accompli sur la plupart
systèmes par le simple expédient de ``hard'' lier les fichiers requis de chaque source
répertoire dans le répertoire de construction approprié.

Les liens sont maintenus correctement par Cons, quoi que vous fassiez dans le répertoire source.
Si vous modifiez un fichier source, votre éditeur peut le faire ``sur place'' ou il peut le renommer
d'abord et créez un nouveau fichier. Dans ce dernier cas, tout lien physique sera perdu. Les inconvénients seront
détectera cette condition la prochaine fois que le fichier source sera nécessaire et le liera à nouveau
de manière appropriée.

Vous remarquerez aussi, d'ailleurs, que aucune des changements ont été nécessaires au sous-jacent Conscrit
des dossiers. Et nous pouvons aller plus loin, comme nous le verrons dans la section suivante.

Variante construit


Bonjour, Monde! en banane ainsi que pêche OS

Les versions de variantes nécessitent juste une autre extension simple. Prenons comme exemple un
exigence d'autoriser les builds pour les systèmes d'exploitation baNaNa et peAcH. Dans ce cas,
nous utilisons un système de fichiers distribué, tel que NFS pour accéder au système particulier, et
seul l'un ou l'autre des systèmes doit être compilé pour une invocation donnée de
"contre". Voici une façon de configurer le Construire dossier pour notre Bonjour, Monde!
demande:

# Construire un fichier pour Hello, World!

die qq(OS doit être spécifié) sauf si $OS = $ARG{OS} ;
die qq(le système d'exploitation doit être "pêche" ou "banane")
if $OS ne "pêche" && $OS ne "banane";

# Où mettre tous nos produits partagés.
$EXPORT = "#export/$OS" ;

Exporter qw( CONS INCLUDE LIB BIN );

# Répertoires standard pour partager des produits.
$INCLUDE = "$EXPORT/inclure" ;
$LIB = "$EXPORT/lib" ;
$BIN = "$EXPORT/bin" ;

# Un environnement de construction standard.
$CONS = nouveau contre (
CPPPATH => $INCLUDE, # Inclure le chemin pour les compilations C
LIBPATH => $LIB, # Chemin de la bibliothèque pour lier les programmes
LIBS => '-lworld', # Liste des bibliothèques standards
);

# $BUILD est l'endroit où nous allons tout dériver.
$BUILD = "#build/$OS" ;

# Indiquez où se trouvent les fichiers sources de $BUILD.
Lien $BUILD => 'src';

Construire (
"$CONSTRUIRE/bonjour/Conscrit",
"$CONSTRUIRE/monde/Conscrit",
);

Maintenant, si nous nous connectons à un système peAcH, nous pouvons construire notre Bonjour, Monde! demande pour ça
Plate-forme:

% contre export OS=pêche
Installez build/peach/world/world.h comme export/peach/include/world.h
cc -Iexport/peach/include -c build/peach/hello/hello.c -o build/peach/hello/hello.o
cc -Iexport/peach/include -c build/peach/world/world.c -o build/peach/world/world.o
ar build/peach/world/libworld.a build/peach/world/world.o
ar : création de build/peach/world/libworld.a
ranlib build/peach/world/libworld.a
Installez build/peach/world/libworld.a comme export/peach/lib/libworld.a
cc -o build/peach/bonjour/bonjour build/peach/hello/hello.o -Lexport/peach/lib -lworld
Installez build/peach/hello/hello comme export/peach/bin/hello

Variations on a thème

D'autres variantes de ce modèle sont possibles. Par exemple, vous pourriez décider que vous voulez
pour séparer vos fichiers d'inclusion en fichiers dépendants de la plate-forme et indépendants de la plate-forme.
Dans ce cas, vous devrez définir une alternative à `$INCLUDE' pour dépendant de la plate-forme
des dossiers. Plus Conscrit fichiers, générant des fichiers d'inclusion purement indépendants de la plate-forme,
pas besoin de changer.

Vous voudrez peut-être aussi pouvoir compiler l'ensemble de votre système avec le débogage ou le profilage,
par exemple, activé. Vous pouvez le faire avec les options de ligne de commande appropriées, telles que
`DEBUG=on'. Cela serait ensuite traduit dans la plate-forme appropriée spécifique
conditions requises pour activer le débogage (cela peut inclure la désactivation de l'optimisation, par exemple
Exemple). Vous pouvez éventuellement varier l'espace de noms pour ces différents types de systèmes,
mais, comme nous le verrons dans la section suivante, ce n'est pas essential pour ce faire, puisque Cons est jolie
intelligent sur la reconstruction des choses lorsque vous modifiez les options.

Signatures


MD5 cryptographique signatures

Chaque fois que Cons crée un fichier dérivé, il stocke un Signature pour ce fichier. La signature
est stocké dans un fichier séparé, un par répertoire. Après la compilation de l'exemple précédent,
le .expédier déposer dans le construire/pêcher/monde répertoire ressemblait à ceci :

world.o:834179303 23844c0b102ecdc0b4548d1cd1cbd8c6
libworld.a:834179304 9bf6587fa06ec49d864811a105222c00

Le premier nombre est un horodatage - pour un système UNIX, il s'agit généralement du nombre de
secondes depuis le 1er janvier 1970. La deuxième valeur est une somme de contrôle MD5. le Message Digérer
Algorithme est un algorithme qui, étant donné une chaîne d'entrée, calcule un fort
signature pour cette chaîne. La somme de contrôle MD5 stockée dans le .expédier fichier est, en effet, un
résumé de toutes les informations de dépendance pour le fichier spécifié. Ainsi, par exemple, pour le
monde.o fichier, cela inclut au moins le monde.c fichier, ainsi que tous les fichiers d'en-tête que Cons
sait qui sont inclus, directement ou indirectement par monde.c. Non seulement cela, mais
ligne de commande réelle qui a été utilisée pour générer monde.o est également pris en compte dans le calcul de
la signature. De la même manière, libworld.a obtient une signature qui ``inclut'' tous les
signatures de ses constituants (et donc, transitivement, les signatures de leur
constituants), ainsi que la ligne de commande qui a créé le fichier.

La signature d'un fichier non dérivé est calculée, par défaut, en prenant la valeur courante
l'heure de modification du fichier et le nom de l'entrée du fichier (sauf s'il y a un
actuel .expédier entrée pour ce fichier, auquel cas cette signature est utilisée).

Notez qu'il n'est pas nécessaire qu'un fichier dérivé dépende d'un Construire or
Conscrit fichier--si les modifications apportées à ces fichiers affectent le fichier en question, alors ce sera
automatiquement reflété dans sa signature, puisque les parties pertinentes de la ligne de commande sont
inclus dans la signature. Les modifications non liées n'auront aucun effet.

Lorsque Cons considère s'il faut dériver un fichier particulier, il calcule d'abord le
signature attendue du fichier. Il compare ensuite l'heure de la dernière modification du fichier avec
le temps enregistré dans le .expédier entrée, s'il en existe une. Si ces heures correspondent, alors le
signature stockée dans le .expédier fichier est considéré comme exact. Si le fichier est antérieur
signature ne correspond pas à la nouvelle signature attendue, le fichier doit être redérivé.

Notez qu'un fichier sera redérivé chaque fois que quelque chose concernant un fichier dépendant change. Dans
particulier, notez que tous modification de l'heure de modification d'une personne à charge (transfert ou
en arrière dans le temps) forcera la recompilation du fichier dérivé.

L'utilisation de ces signatures est une méthode extrêmement simple, efficiente et efficace de
améliorant de façon spectaculaire la reproductibilité d'un système.

Nous allons le démontrer avec un exemple simple :

# Simple "Bonjour, Monde!" Fichier de construction
$CFLAGS = '-g' si $ARG{DEBUG} eq 'on' ;
$CONS = nouveau cons(CFLAGS => $CFLAGS);
Programmez $CONS 'bonjour', 'bonjour.c' ;

Remarquez comment Cons se recompile aux moments appropriés :

% contre bonjour
cc -c bonjour.c -o bonjour.o
cc -o bonjour bonjour.o
% contre bonjour
inconvénients: "bonjour" est à jour.
% contre DEBUG=on bonjour
cc -g -c bonjour.c -o bonjour.o
cc -o bonjour bonjour.o
% contre DEBUG=on bonjour
inconvénients: "bonjour" est à jour.
% contre bonjour
cc -c bonjour.c -o bonjour.o
cc -o bonjour bonjour.o

Code Dépôts


De nombreuses organisations de développement de logiciels auront un ou plusieurs répertoires de référentiels centraux
arborescences contenant le code source actuel d'un ou plusieurs projets, ainsi que les
fichiers objets, bibliothèques et exécutables. Afin de réduire les recompilations inutiles,
il est utile d'utiliser des fichiers du référentiel pour créer un logiciel de développement - en supposant, de
bien sûr, qu'aucun fichier de dépendance plus récent n'existe dans l'arborescence de construction locale.

Dépôt

Cons fournit un mécanisme pour spécifier une liste de référentiels de code qui seront recherchés,
dans l'ordre, pour les fichiers source et les fichiers dérivés introuvables dans l'arborescence du répertoire de construction local.

Les lignes suivantes dans un Construire le fichier demandera à Cons de regarder d'abord sous le
/usr/expérience/dépôt répertoire, puis sous le /usr/produit/dépôt annuaire:

Référentiel qw (
/usr/expérience/dépôt
/usr/produit/dépôt
);

Les répertoires du référentiel spécifiés peuvent contenir des fichiers sources, des fichiers dérivés (objets,
bibliothèques et exécutables), ou les deux. S'il n'y a pas de fichier local (source ou dérivé) sous
le répertoire dans lequel Cons est exécuté, puis la première copie d'un fichier du même nom trouvé
sous un répertoire de référentiel sera utilisé pour créer tous les fichiers dérivés locaux.

Cons maintient une liste globale de répertoires de référentiels. Les inconvénients élimineront le
répertoire courant, et tous les répertoires inexistants, de la liste.

Trouver le Construire filet in a Dépôt

Les inconvénients rechercheront également Construire ainsi que Conscrit dans l'arborescence ou les arborescences du référentiel.
Cela conduit cependant à une situation de poule et d'œuf : à quoi ressemblez-vous dans un arbre de référentiel
pour Construire fichier si le Construire le fichier vous indique où se trouve le référentiel ? Pour obtenir
autour de cela, les référentiels peuvent être spécifiés via les options `-R' sur la ligne de commande :

% contre -R /usr/experiment/repository -R /usr/product/repository .

Tous les répertoires de référentiel spécifiés dans le Construire or Conscrit les fichiers seront ajoutés
vers les répertoires du référentiel spécifiés par les options de ligne de commande `-R'.

Dépôt la source fichiers

Si le code source (inclure le Conscrit fichier) pour la version bibliothèque du Bonjour,
Monde! L'application C est dans un référentiel (sans fichiers dérivés), Cons utilisera le
fichiers sources du référentiel pour créer les fichiers objets locaux et le fichier exécutable :

% contre -R /usr/src_only/repository bonjour
gcc -c /usr/src_only/repository/hello.c -o bonjour.o
gcc -c /usr/src_only/repository/world.c -o monde.o
ar r libworld.a monde.o
ar : création de libworld.a
ranlib libworld.a
gcc -o bonjour bonjour.o libworld.a

La création d'un fichier source local amènera Cons à reconstruire le fichier dérivé approprié ou
fichiers:

% pico monde.c
[EDIT]
% contre -R /usr/src_only/repository bonjour
gcc -c monde.c -o monde.o
ar r libworld.a monde.o
ar : création de libworld.a
ranlib libworld.a
gcc -o bonjour bonjour.o libworld.a

Et la suppression du fichier source local entraînera le retour de Cons à la construction du fichier dérivé.
fichiers de la source du référentiel :

% rm monde.c
% contre -R /usr/src_only/repository bonjour
gcc -c /usr/src_only/repository/world.c -o monde.o
ar r libworld.a monde.o
ar : création de libworld.a
ranlib libworld.a
gcc -o bonjour bonjour.o libworld.a

Dépôt dérivé fichiers

Si une arborescence de référentiel contient des fichiers dérivés (généralement des fichiers objets, des bibliothèques ou
exécutables), Cons effectuera son calcul de signature normal pour décider si le
référentiel est à jour ou un fichier dérivé doit être généré localement. Cela signifie que,
afin d'assurer un calcul correct de la signature, une arborescence de référentiel doit également contenir les
.expédier fichiers qui ont été créés par Cons lors de la génération des fichiers dérivés.

Cela serait généralement accompli en construisant le logiciel dans le référentiel (ou,
alternativement, dans un répertoire de construction, puis en copiant le résultat dans le référentiel):

% cd /usr/all/dépôt
% contre bonjour
gcc -c bonjour.c -o bonjour.o
gcc -c monde.c -o monde.o
ar r libworld.a monde.o
ar : création de libworld.a
ranlib libworld.a
gcc -o bonjour bonjour.o libworld.a

(Ceci est sûr même si le Construire fichier répertorie les /usr/all/dépôt répertoire dans un
Commande 'Repository' car Cons supprimera le répertoire actuel du référentiel
liste.)

Maintenant, si nous voulons créer une copie de l'application avec notre propre Bonjour c fichier, nous avons seulement besoin
pour créer le fichier source nécessaire et utilisez l'option `-R' pour que Cons utilise d'autres
fichiers du référentiel :

% répk $HOME/build1
% cd $HOME/build1
% ed bonjour.c
[EDIT]
% contre -R /usr/all/repository bonjour
gcc -c bonjour.c -o bonjour.o
gcc -o bonjour bonjour.o /usr/all/repository/libworld.a

Notez que Cons n'a pas pris la peine de recréer un local libworld.a bibliothèque (ou recompiler le
monde.o module), mais utilise à la place la version déjà compilée du référentiel.

Parce que les signatures MD5 que Cons met dans le .expédier fichier contient des horodatages pour le
fichiers dérivés, les horodatages de signature doivent correspondre aux horodatages de fichier pour qu'une signature
être considéré comme valide.

Certains systèmes logiciels peuvent modifier les horodatages des fichiers du référentiel (en les copiant,
par exemple), auquel cas Cons supposera, par défaut, que les signatures du référentiel ne sont pas valides
et reconstruire les fichiers inutilement. Ce comportement peut être modifié en spécifiant :

Référentiel_Sig_Times_OK 0 ;

Cela indique à Cons d'ignorer les horodatages lorsqu'il décide si une signature est valide. (Noter
qu'éviter ce contrôle de cohérence signifie qu'il doit y avoir un contrôle approprié sur le référentiel
arborescence pour s'assurer que les fichiers dérivés ne peuvent pas être modifiés sans mettre à jour le .expédier
Signature.)

Lieu copies of fichiers

Si l'arborescence du référentiel contient les résultats complets d'une génération et que nous essayons de construire à partir de
le référentiel sans aucun fichier dans notre arborescence locale, quelque chose de moyennement surprenant
arrive:

% répk $HOME/build2
% cd $HOME/build2
% contre -R /usr/all/repository bonjour
inconvénients: "bonjour" est à jour.

Pourquoi Cons dit-il que le hello le programme est à jour lorsqu'il n'y a pas hello programme en
le répertoire de construction local ? Parce que le référentiel (pas le répertoire local) contient le
mise à jour hello programme, et Cons détermine correctement que rien ne doit être fait pour
reconstruisez cette copie à jour du fichier.

Cependant, il arrive souvent qu'il soit approprié de s'assurer qu'une copie locale d'un
le fichier existe toujours. Un script d'empaquetage ou de test, par exemple, peut supposer que certains
les fichiers générés existent localement. Au lieu de faire prendre conscience à ces scripts subsidiaires de la
répertoire du référentiel, la commande 'Local' peut être ajoutée à un Construire or Conscrit déposer à
spécifiez qu'un ou plusieurs fichiers doivent apparaître dans le répertoire de construction local :

qw local(
hello
);

Ensuite, si nous réexécutons la même commande, Cons fera une copie locale du programme à partir du
copie du référentiel (vous indiquant qu'il le fait):

% contre -R /usr/all/repository bonjour
Copie locale de hello depuis /usr/all/repository/hello
inconvénients: "bonjour" est à jour.

Notez que, parce que l'acte de faire la copie locale n'est pas considéré comme une « construction » du
hello fichier, Cons signale toujours qu'il est à jour.

La création de copies locales est particulièrement utile pour les fichiers en cours d'installation dans un
répertoire intermédiaire (à partager avec d'autres répertoires) via la commande 'Install'.
Accompagner la commande « Install » pour un fichier avec une commande « Local » associée est si
Il est courant que Cons fournisse une commande `Install_Local' comme moyen pratique de faire les deux :

Install_Local $env, '#export', 'bonjour';

est exactement équivalent à :

Installez $env '#export', 'hello' ;
'#export/bonjour' local ;

Les commandes « Local » et « Install_Local » mettent à jour le .expédier déposer auprès de la
signatures de fichiers appropriées, afin que les futures versions soient exécutées correctement.

Dépôt dépendance selon une analyse de l’Université de Princeton

En raison de son analyse intégrée, Cons recherchera dans les arborescences de référentiels spécifiées les éléments inclus.
.h des dossiers. À moins que le compilateur ne connaisse également les arborescences du référentiel, il sera
impossible à trouver .h fichiers qui n'existent que dans un référentiel. Si, par exemple, le Bonjour c
fichier comprend le salut fichier dans son répertoire courant :

% contre -R /usr/all/repository bonjour
gcc -c /usr/all/repository/hello.c -o bonjour.o
/usr/all/repository/hello.c:1 : hello.h : aucun fichier ou répertoire de ce type

La résolution de ce problème impose certaines exigences sur la façon dont les environnements de construction sont
défini et sur la façon dont la directive de préprocesseur C `#include' est utilisée pour inclure des fichiers.

Afin d'informer le compilateur sur les arborescences du référentiel, Cons ajoutera le `-I' approprié
flags aux commandes de compilation. Cela signifie que la variable `CPPPATH' dans le
L'environnement de construction doit spécifier explicitement tous les sous-répertoires qui doivent être recherchés
pour les fichiers inclus, y compris le répertoire courant. Par conséquent, nous pouvons corriger ce qui précède
exemple en modifiant la création d'environnement dans le Construire fichier comme suit:

$env = nouveau contre(
CC => 'gcc',
CHEMIN CPPP => '.',
LIBS => 'libworld.a',
);

En raison de la définition de la variable `CPPPATH', cela donne, lorsque nous réexécutons le
commander:

% contre -R /usr/all/repository bonjour
gcc -c -I. -I/usr/all/repository /usr/all/repository/hello.c -o bonjour.o
gcc -o bonjour bonjour.o /usr/all/repository/libworld.a

L'ordre des drapeaux '-I' réplique, pour le préprocesseur C, le même référentiel-
chemin de recherche de répertoire que Cons utilise pour sa propre analyse de dépendance. S'il y a
plusieurs référentiels et plusieurs répertoires `CPPPATH', Cons ajoutera le référentiel
répertoires au début de chaque répertoire `CPPPATH', multipliant rapidement le nombre
des drapeaux "-I". A titre d'exemple extrême, un Construire fichier contenant:

Référentiel qw(
/u1
/u2
);

$env = nouveau contre(
CPPPATH => 'a:b:c',
);

Donnerait une commande de compilation de :

cc -Ia -I/u1/a -I/u2/a -Ib -I/u1/b -I/u2/b -Ic -I/u1/c -I/u2/c -c bonjour.c -o bonjour.o

Parce que Cons s'appuie sur les indicateurs "-I" du compilateur pour communiquer l'ordre dans lequel
les répertoires de référentiel doivent être recherchés, la gestion des répertoires de référentiel par Cons est
fondamentalement incompatible avec l'utilisation de guillemets doubles sur les directives `#include' dans votre C
code source:

#include "file.h" /* N'UTILISEZ PAS DE GITULES DOUBLES COMME CELUI-CI */

C'est parce que la plupart des préprocesseurs C, lorsqu'ils sont confrontés à une telle directive, seront toujours d'abord
rechercher le répertoire contenant le fichier source. Cela sape le "-je" élaboré
options que Cons construit pour rendre le préprocesseur conforme à sa recherche préférée
chemin.

Par conséquent, lorsque vous utilisez des arborescences de référentiels dans Cons, toujours utiliser des équerres pour inclus
fichiers:

#inclure /* UTILISER DES ÉQUERRES À LA PLACE */

Liste_dépôt

Cons fournit une commande `Repository_List' pour renvoyer une liste de tous les répertoires du référentiel
dans leur ordre de recherche actuel. Cela peut être utilisé pour le débogage ou pour faire du Perl plus complexe
des trucs:

@list = Repository_List ;
print join(' ', @list), "\n" ;

Dépôt l'interaction avec autre Inconvénients Caractéristiques

La gestion par Cons des arborescences de référentiels interagit correctement avec les autres fonctionnalités de Cons - ce qui est
dire, il fait généralement ce que vous attendez.

Plus particulièrement, les arborescences de référentiels interagissent correctement, et assez puissamment, avec le 'Link'
commander. Une arborescence de référentiel peut contenir un ou plusieurs sous-répertoires pour les builds de version
établi via `Link' à un sous-répertoire source. Les inconvénients rechercheront les fichiers dérivés dans
les sous-répertoires de construction appropriés sous l'arborescence du référentiel.

Réglage par défaut objectifs


Jusqu'à présent, nous avons démontré l'invocation de Cons avec une cible explicite pour créer :

% contre bonjour

Normalement, Cons ne construit rien à moins qu'une cible ne soit spécifiée, mais en spécifiant '.'
(le répertoire courant) construira tout :

% contre # ne construit rien

% les inconvénients . # construit tout sous le répertoire de niveau supérieur

L'ajout de la méthode `Default' à n'importe quel Construire or Conscrit fichier ajoutera le spécifié
cibles à une liste de cibles par défaut. Les inconvénients construiront ces valeurs par défaut s'il n'y a pas
cibles spécifiées sur la ligne de commande. Donc, en ajoutant la ligne suivante au niveau supérieur
Construire Le fichier imitera le comportement typique de Make consistant à tout construire par défaut :

Défaut '.';

Ce qui suit ajouterait le hello ainsi que au revoir commandes (dans le même répertoire que le
Construire or Conscrit fichier) à la liste par défaut :

qw par défaut(
hello
au revoir
);

La méthode `Default' peut être utilisée plus d'une fois pour ajouter des cibles à la liste par défaut.

Sélectif construit


Cons fournit deux méthodes pour réduire la taille d'un build donné. La première consiste à préciser
cibles sur la ligne de commande, et la seconde est une méthode pour élaguer l'arbre de construction. Bien
considérer d'abord la spécification de la cible.

Sélectif ciblage

Comme make, Cons permet la spécification de ``cibles'' sur la ligne de commande. Contre cibles
peut être soit des fichiers, soit des répertoires. Lorsqu'un répertoire est spécifié, il s'agit simplement d'un
notation manuelle pour chaque produit dérivable - que Cons connaît - dans le
répertoire et ci-dessous. Par example:

% contre build/hello/hello.o

signifie construire bonjour.o et tout ce qui bonjour.o va peut-être avoir besoin de. C'est d'un précédent
version de l' Bonjour, Monde! programme dans lequel bonjour.o dépendait de
exporter/inclure/monde.h. Si ce fichier n'est pas à jour (parce que quelqu'un a modifié
src/monde/monde.h), alors il sera reconstruit, même s'il se trouve dans un répertoire distant de
construire/bonjour.

Dans cet exemple:

% contre construire

Tout dans le construire répertoire est construit, si nécessaire. Encore une fois, cela peut entraîner plus de fichiers
à construire. En particulier, les deux exporter/inclure/monde.h ainsi que export/lib/libworld.a
requis par le construire/bonjour répertoire, et donc ils seront construits s'ils sont obsolètes.

Si nous le faisons, à la place :

% contre export

alors seuls les fichiers qui doivent être installés dans le répertoire d'exportation seront reconstruits, si
nécessaire, puis installé là-bas. Notez que `cons build' peut créer des fichiers que `cons build'
export' ne se construit pas, et vice-versa.

Non ''spécial'' objectifs

Avec les inconvénients, les cibles ``spéciales'' de style make ne sont pas nécessaires. L'analogique le plus simple avec Cons
est d'utiliser spécial Exporter répertoires, à la place. Supposons, par exemple, que vous ayez un
toute une série de tests unitaires qui sont associés à votre code. Les tests vivent dans le
répertoire source près du code. Normalement, cependant, vous ne voulez pas construire ces tests.
Une solution consiste à fournir toutes les instructions de construction pour créer les tests, puis à
installer les tests dans une partie séparée de l'arborescence. Si nous installons les tests dans un
répertoire appelé tests, puis:

% contre tests

va construire tous les tests.

% contre export

construira la version de production du système (mais pas les tests), et :

% contre construire

devrait probablement être évité (puisqu'il compilera des tests inutilement).

Si vous souhaitez créer un seul test, vous pouvez nommer explicitement le test (dans
soit le tests répertoire ou le construire annuaire). Vous pouvez également agréger les tests
dans une hiérarchie pratique dans le répertoire tests. Cette hiérarchie n'a pas besoin
correspondent nécessairement à la hiérarchie source, de la même manière que la hiérarchie d'inclusion
ne correspond probablement pas à la hiérarchie source (il est peu probable que la hiérarchie d'inclusion soit plus
plus de deux niveaux de profondeur, pour les programmes C).

Si vous voulez construire absolument tout dans l'arborescence (sous réserve des options que vous
sélectionner), vous pouvez utiliser :

% les inconvénients .

Ce n'est pas particulièrement efficace, car il parcourra tous les arbres de manière redondante,
y compris l'arborescence des sources. L'arbre source, bien sûr, peut avoir des objets constructibles dans
cela - rien ne vous empêche de le faire, même si vous construisez normalement dans une version séparée
arbre.

Développer Élagage


En conjonction avec la sélection des cibles, construire taille peut être utilisé pour réduire la portée de la
construire. Dans l'exemple précédent de peAcH et baNaNa, nous avons déjà vu comment les scripts
l'élagage de la construction peut être utilisé pour ne rendre disponible que la moitié de la construction potentielle pour un
invocation de "contre". Cons fournit également, par commodité, une convention de ligne de commande qui
permet de spécifier quel Conscrit les fichiers sont réellement « construits », c'est-à-dire incorporés
dans l'arbre de construction. Par example:

% contre build + monde

L'argument `+' introduit une expression régulière Perl. Ceci doit, bien sûr, être cité à
le niveau du shell s'il y a des méta-caractères du shell dans l'expression. le
l'expression est comparée à chaque Conscrit fichier qui a été mentionné dans un `Build'
déclaration, et seuls les scripts avec des noms correspondants sont réellement incorporés dans le
construire un arbre. Plusieurs de ces arguments sont autorisés, auquel cas une correspondance avec l'un d'entre eux
est suffisant pour qu'un script soit inclus.

Dans l'exemple ci-dessus, le hello programme ne sera pas construit, puisque Cons n'aura pas
connaissance du scénario bonjour/appeléL’ libworld.a l'archive sera construite, cependant, si
besoin d'être.

Il y a quelques utilisations pour l'élagage de build via la ligne de commande. Peut-être le plus utile
est la capacité d'effectuer des changements locaux, puis, avec une connaissance suffisante de la
conséquences de ces changements, restreindre la taille de l'arbre de construction afin d'accélérer
le temps de reconstruction. Une deuxième utilisation de l'élagage de construction est d'empêcher activement la recompilation
de certains fichiers dont vous savez qu'ils seront recompilés en raison, par exemple, d'un fichier d'en-tête modifié.
Vous savez peut-être que les modifications apportées au fichier d'en-tête sont sans importance, ou que le
les modifications peuvent être ignorées en toute sécurité pour la plupart de l'arborescence, à des fins de test.Avec les inconvénients, le
est qu'il est pragmatique d'admettre ce type de comportement, étant entendu que
lors de la prochaine version complète, tout ce qui doit être reconstruit le sera. il n'y a pas d'équivalent
à une commande ``make touch'', pour marquer les fichiers comme étant à jour en permanence. Ainsi, tout risque
encourus par l'élagage de construction est atténué. Pour un travail de qualité de sortie, évidemment, nous recommandons
que vous n'utilisez pas l'élagage de build (c'est tout à fait correct d'utiliser pendant l'intégration, cependant,
pour vérifier la compilation, etc. Assurez-vous simplement de faire une construction sans contrainte avant de valider
l'intégration).

Temporaire remplacements


Cons fournit un mécanisme très simple pour remplacer les aspects d'un build. L'essentiel est
que vous écrivez un fichier de remplacement contenant une ou plusieurs commandes « Override », et vous
spécifiez ceci sur la ligne de commande, lorsque vous exécutez « cons » :

% contre -o sur exportation

construira le Exporter répertoire, avec tous les fichiers dérivés soumis aux remplacements présents
dans l' plus de déposer. Si vous omettez l'option `-o', alors tout le nécessaire pour supprimer
tous les remplacements seront reconstruits.

Primordial sûr, heureux et sain les variables

Le fichier de dérogation peut contenir deux types de dérogations. Le premier est l'environnement entrant
variables. Ceux-ci sont normalement accessibles par le Construire fichier à partir du hachage `%ENV'
variable. Ceux-ci peuvent être remplacés de manière triviale dans le fichier de remplacement en définissant le
éléments appropriés de « %ENV » (ceux-ci peuvent également être remplacés dans l'environnement de l'utilisateur,
bien sûr).

La Remplacer commander

Le deuxième type de dérogation est accompli avec la commande « Override », qui ressemble à
ce:

Passer outre , => , => , ... ;

L'expression régulière regexp est comparé à chaque fichier dérivé qui est un candidat
pour la construction. Si le fichier dérivé correspond, les paires variable/valeur sont utilisées pour
remplacer les valeurs de l'environnement de construction associées au fichier dérivé.

Supposons que nous ayons un environnement de construction comme celui-ci :

$CONS = nouveau contre(
COPT => '',
CDBG => '-g',
CFLAG => '%COPT %CDBG',
);

Ensuite, si nous avons un fichier de substitution plus de contenant cette commande :

Remplacer '\.o$', COPT => '-O', CDBG => '';

puis toute invocation "contre" avec "-o sur" qui crée .o via cet environnement
les faire compiler avec `-O' et pas `-g'. La dérogation pourrait, bien entendu, être
restreint à un seul répertoire par la sélection appropriée d'une expression régulière.

Voici la version originale de Hello, World! programme, construit avec cet environnement.
Notez que Cons reconstruit les pièces appropriées lorsque le remplacement est appliqué ou supprimé :

% contre bonjour
cc -g -c bonjour.c -o bonjour.o
cc -o bonjour bonjour.o
% contre -o sur bonjour
cc -O -c bonjour.c -o bonjour.o
cc -o bonjour bonjour.o
% contre -o sur bonjour
inconvénients: "bonjour" est à jour.
% contre bonjour
cc -g -c bonjour.c -o bonjour.o
cc -o bonjour bonjour.o

Il est important que la commande « Override » ne soit utilisée que pour des
remplacements nécessaires au développement car les remplacements ne sont pas indépendants de la plate-forme et
parce qu'ils s'appuient trop sur une connaissance intime du fonctionnement des scripts. Pour
utilisation temporaire, cependant, ils sont exactement ce que vous voulez.

Notez qu'il est toujours utile de fournir, par exemple, la possibilité de créer un
version d'un système pour une utilisation en production - de la Construire ainsi que Conscrit des dossiers. Par ici
vous pouvez adapter le système optimisé à la plate-forme. Où les compromis de l'optimiseur doivent être
fait (des fichiers particuliers peuvent ne pas être compilés avec une optimisation complète, par exemple), puis
ceux-ci peuvent être enregistrés pour la postérité (et la reproductibilité) directement dans les scripts.

Plus on construction environnements


Réglage par défaut construction les variables

Nous avons mentionné et utilisé le concept de construction sûr, heureux et sain, plusieurs fois dans le
pages précédentes. Il est maintenant temps de rendre cela un peu plus concret. Avec ce qui suit
déclaration:

$env = nouveau cons();

une référence à un nouvel environnement de construction par défaut est créée. Celui-ci contient un nombre
des variables de construction et de certaines méthodes. A l'heure où nous écrivons, la liste par défaut des
variables de construction est défini comme suit :

CC => 'cc',
CFLAG => '',
CCCOM => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
INCDIRPREFIX => '-I',
CXX => '%CC',
CXXFLAGS => '%CFLAGS',
CXXCOM => '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
LIEN => '%CXX',
LINKCOM => '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',
LINKMODULECOM => '%LD -r -o %> %<',
LIBDIRPREFIX => '-L',
AR => 'ar',
ARFLAG => 'r',
ARCOM => "%AR %ARFLAGS %> %<\n%RANLIB %>",
RANLIB => 'ranlib',
AS => 'comme',
ASFLAGS => '',
ASCOM => '%AS %ASFLAGS %< -o %>',
LD => 'ld',
LDFLAGS => '',
PREFLIB => 'lib',
SUFLIB => '.a',
SUFLIBS => '.so:.a',
SUFOBJ => '.o',
ENV => { 'CHEMIN' => '/ bin:/ usr / bin' },

Sur les systèmes Win32 (Windows NT), les variables de construction suivantes sont remplacées dans le
par défaut:

CC => 'cl',
CFLAG => '/nologo',
CCCOM => '%CC %CFLAGS %_IFLAGS /c %< /Fo%>',
CXXCOM => '%CXX %CXXFLAGS %_IFLAGS /c %< /Fo%>',
INCDIRPREFIX => '/I',
LIEN => 'lien',
LINKCOM => '%LINK %LDFLAGS /out:%> %< %_LDIRS %LIBS',
LINKMODULECOM => '%LD /r /o %> %<',
LIBDIRPREFIX => '/LIBPATH:',
AR => 'lib',
ARFLAGS => '/nologo',
ARCOM => "%AR %ARFLAGS /out:%> %<",
RANLIB => '',
LD => 'lien',
LDFLAGS => '/nologo',
PREFLIB => '',
SUFEXE => '.exe',
SUFLIB => '.lib',
SUFLIBS => '.dll:.lib',
SUFOBJ => '.obj',

Ces variables sont utilisées par les différentes méthodes associées à l'environnement, en
particulier toute méthode qui invoque finalement une commande externe substituera ces
variables dans la commande finale, le cas échéant. Par exemple, la méthode `Objects' prend
un certain nombre de fichiers sources et s'arrange pour dériver, si nécessaire, l'objet correspondant
des dossiers. Par exemple:

Objets $env 'foo.c', 'bar.c';

Celui-ci s'arrangera pour produire, si nécessaire, foo.o ainsi que bar.o. La commande invoquée est simplement
`%CCCOM', qui s'étend par substitution, à la commande externe appropriée requise
pour construire chaque objet. Nous allons explorer les règles de substitution plus loin sous la « Commande »
méthode, ci-dessous.

Les variables de construction sont également utilisées à d'autres fins. Par exemple, « CPPPATH » est
utilisé pour spécifier un chemin séparé par des deux-points des répertoires d'inclusion. Ceux-ci sont destinés à être
transmis au préprocesseur C et sont également utilisés par la machine d'analyse des fichiers C pour
déterminer les dépendances impliquées dans une compilation C. Variables commençant par
souligné, sont créés par diverses méthodes, et devraient normalement être considérés comme ``internes''
variables. Par exemple, lorsqu'une méthode est appelée qui appelle à la création d'un objet
à partir d'une source C, la variable '_IFLAGS' est créée : cela correspond aux commutateurs '-I'
requis par le compilateur C pour représenter les répertoires spécifiés par `CPPPATH'.

Notez que, pour tout environnement particulier, la valeur d'une variable est définie une fois, puis
ne jamais réinitialiser (pour modifier une variable, vous devez créer un nouvel environnement. Des méthodes sont fournies
pour copier des environnements existants à cette fin). Certaines variables internes, telles que
Les `_IFLAGS' sont créés à la demande, mais une fois définis, ils restent fixes pour la durée de vie du
environnement.

Les variables 'CFLAGS', 'LDFLAGS' et 'ARFLAGS' fournissent toutes un emplacement pour passer des options à
le compilateur, le chargeur et l'archiveur, respectivement. Moins évidemment, le `INCDIRPREFIX'
variable spécifie la chaîne d'options à ajouter au début de chaque inclusion
répertoire afin que le compilateur sache où trouver .h des dossiers. De même, le
La variable `LIBDIRPREFIX' spécifie la chaîne d'options à ajouter au début de
chaque répertoire que l'éditeur de liens doit rechercher des bibliothèques.

Une autre variable, 'ENV', est utilisée pour déterminer l'environnement système pendant l'exécution
d'une commande externe. Par défaut, la seule variable d'environnement définie est `PATH',
qui est le chemin d'exécution d'une commande UNIX. Pour une reproductibilité maximale, vous devez
vraiment arranger pour définir votre propre chemin d'exécution, dans votre niveau supérieur Construire fichier (ou
peut-être en important un package de construction approprié avec la commande Perl `use'). le
les variables par défaut sont destinées à vous faire décoller.

Interpolation construction les variables

Les variables d'environnement de construction peuvent être interpolées dans les noms de fichiers source et cible
en préfixant le nom de la variable de construction avec « % ».

$env = nouveau contre(
DESTDIR => 'programmes',
SRCDIR => 'src',
);
Programmez $env '%DESTDIR/hello', '%SRCDIR/hello.c' ;

L'expansion des variables de construction est récursive, c'est-à-dire que le fichier prénom(s) sera re-
étendu jusqu'à ce qu'aucune autre substitution ne puisse être effectuée. Si une variable de construction n'est pas
défini dans l'environnement, alors la chaîne nulle sera substituée.

Réglage par défaut construction méthodes


La liste des méthodes de construction par défaut comprend les éléments suivants :

La 'nouveau' constructeur

La méthode « new » est un constructeur d'objet Perl. C'est-à-dire qu'il n'est pas invoqué via une référence
à un environnement de construction existant référence, mais, plutôt statiquement, en utilisant le nom
de la Perl paquet où le constructeur est défini. La méthode est invoquée comme ceci :

$env = nouveau contre( );

L'environnement que vous récupérez est inclus dans le paquet "contre", ce qui signifie qu'il
lui ont associé les méthodes par défaut décrites ci-dessous. Construction individuelle
les variables peuvent être remplacées en fournissant des paires nom/valeur dans une liste de remplacement. Noter que
pour remplacer n'importe quelle variable d'environnement de commande (c'est-à-dire n'importe quoi sous `ENV'), vous devrez
passer outre tous. Vous pouvez contourner cette difficulté en utilisant la méthode 'copy' sur un
environnement de construction existant.

La "cloner" méthode

La méthode "clone" crée un clone d'un environnement de construction existant et peut être
appelé comme dans l'exemple suivant :

$env2 = $env1->clone( );

Vous pouvez fournir des remplacements de la manière habituelle pour créer un environnement différent du
original. Si vous voulez juste un nouveau nom pour le même environnement (ce qui peut être utile lorsque
l'exportation d'environnements vers des composants existants), vous pouvez simplement utiliser une simple affectation.

La 'copie' méthode

La méthode `copy' extrait les variables de construction définies en externe d'un
environnement et les renvoie sous forme de liste de paires nom/valeur. Les dérogations peuvent également être
fourni, auquel cas, les valeurs remplacées seront renvoyées, le cas échéant. le
La liste renvoyée peut être affectée à un hachage, comme indiqué dans le prototype ci-dessous, mais elle peut également
être manipulé d'autres manières :

%env = $env1->copie( );

La valeur de « ENV », qui est elle-même un hachage, est également copiée dans un nouveau hachage, ce qui peut être
changé sans crainte d'affecter l'environnement d'origine. Ainsi, par exemple, si vous avez vraiment
voulez remplacer uniquement la variable `PATH' dans l'environnement par défaut, vous pouvez faire le
Suivante à la suite:

%cons = new cons()->copy();
$cons{ENV}{CHEMIN} = " ";
$cons = nouveau cons(%cons);

Cela laissera tout ce qui pourrait être dans l'environnement d'exécution par défaut
paisible.

La 'Installer' méthode

La méthode `Install' fait en sorte que les fichiers spécifiés soient installés dans le
annuaire. L'installation est optimisée : le fichier n'est pas copié s'il peut être lié. Si
ce n'est pas le comportement souhaité, vous devrez utiliser une méthode différente pour installer le
déposer. Il s'appelle ainsi :

Installer $env , ;

Notez que, bien que les fichiers à installer puissent être nommés arbitrairement, seul le dernier
composant de chaque nom est utilisé pour le nom de la cible installée. Ainsi, par exemple, si vous
arranger pour installer nourriture/bar in baz, cela créera un barre déposer dans le baz répertoire (pas
nourriture/bar).

La "Installer en tant que" méthode

La méthode `InstallAs' organise la source spécifiée filet(s) à installer en tant que
cible spécifiée filet(s). Plusieurs fichiers doivent être spécifiés sous forme de liste de fichiers. le
l'installation est optimisée : le fichier n'est pas copié s'il peut être lié. Si ce n'est pas le
comportement souhaité, vous devrez utiliser une méthode différente pour installer le fichier. Il est
appelé comme suit :

« InstallAs » fonctionne de deux manières :

Installation d'un seul fichier :

InstallAs $env TgtFile, SrcFile ;

Installation de plusieurs fichiers :

InstallAs $env ['tgt1', 'tgt2'], ['src1', 'src2'] ;

Ou encore :

@srcs = qw(src1 src2 src3) ;
@tgts = qw(tgt1 tgt2 tgt3) ;
InstallAs $env [@tgts], [@srcs] ;

La liste cible et la liste des sources doivent être de la même longueur.

La 'Précieux' méthode

La méthode `Precious' demande par contre de ne pas supprimer le fichier spécifié ou la liste de fichiers avant
les reconstruire. Il est invoqué comme :

Précieux ;

Ceci est particulièrement utile pour permettre les mises à jour incrémentielles des bibliothèques ou le débogage
des fichiers d'information qui sont mis à jour plutôt que recréés à chaque fois. Les inconvénients seront toujours
supprimer les fichiers lorsque l'indicateur `-r' est spécifié.

La 'Commande' méthode

La méthode « Command » est une méthode fourre-tout qui peut être utilisée pour organiser n'importe quel
commande à appeler pour mettre à jour la cible. Pour cette commande, un fichier cible et une liste de
les entrées sont fournies. De plus, une ou plusieurs lignes de commande de construction sont fournies en tant que
chaîne (cette chaîne peut contenir plusieurs commandes intégrées, séparées par de nouvelles
lignes). « Commande » est appelée comme suit :

Commande $env , , ;

La cible dépend de la liste des fichiers d'entrée spécifiés, et les entrées doivent
être construit avec succès ou Cons n'essaiera pas de construire la cible.

Dans la commande de construction, toute variable de l'environnement de construction peut être
introduit en préfixant le nom de la variable de construction avec '%'. C'est récursif :
la commande est étendue jusqu'à ce qu'aucune autre substitution ne puisse être effectuée. Si une construction
variable n'est pas définie dans l'environnement, alors la chaîne nulle sera substituée. UNE
doublé `%%' sera remplacé par un simple `%' dans la commande de construction.

Il existe plusieurs pseudo-variables qui seront également développées :

%> Le nom du fichier cible (dans une commande multi-cible, c'est toujours la première cible
mentionné).

%0 Identique à `%>'.

%1, %2, ..., %9
Ceux-ci se réfèrent respectivement au premier au neuvième fichier d'entrée.

%< L'ensemble complet des entrées. Si l'un de ceux-ci a été utilisé ailleurs dans le
ligne de commande actuelle (via `%1', `%2', etc.), alors ceux-ci seront supprimés de la
liste fournie par `%<'. Considérez la commande suivante trouvée dans un Conscrit filet
dans l' tester annuaire:

Commande $env 'tgt', qw(foo bar baz), qq(
echo %< -i %1 > %>
echo %< -i %2 >> %>
echo %< -i %3 >> %>
);

If tgt devait être mis à jour, cela entraînerait l'exécution de la
commandes suivantes, en supposant qu'aucun remappage n'a été établi pour le tester
annuaire:

echo test/bar test/baz -i test/foo > test/tgt
echo test/foo test/baz -i test/bar >> test/tgt
echo test/foo test/bar -i test/baz >> test/tgt

N'importe laquelle des pseudo-variables ci-dessus peut être immédiatement suivie par l'une des suivantes
suffixes pour sélectionner une partie du nom de chemin étendu :

:a le chemin absolu vers le nom du fichier
:b le répertoire plus le nom du fichier dépouillé de tout suffixe
:d le répertoire
:f le nom du fichier
:s le suffixe du nom de fichier
:F le nom du fichier dépouillé de tout suffixe

En continuant avec l'exemple ci-dessus, `%<:f' se développerait en `foo bar baz', et `%':d> serait
développez en « test ».

Il est possible de réécrire par programmation une partie de la commande en enfermant une partie de celle-ci
entre '%[' et '%]'. Cela appellera la variable de construction nommée comme premier mot
entre parenthèses comme référence de code Perl ; les résultats de cet appel seront utilisés
pour remplacer le contenu des crochets dans la ligne de commande. Par exemple, étant donné un
fichier d'entrée existant nommé cible.dans:

@keywords = qw(foo bar baz);
$env = new cons(X_COMMA => sub { join(",", @_) });
Commande $env 'tgt', 'tgt.in', qq(
echo '# Mots-clés : %[X_COMMA @mots-clés %]' > %>
chat %< >> %>
);

Cela exécutera :

echo '# Mots-clés : foo,bar,baz' > tgt
chat cible.in >> cible

Une fois la substitution effectuée, les chaînes d'espaces blancs sont converties en blancs simples, et
les espaces blancs de début et de fin sont éliminés. Il n'est donc pas possible d'introduire
espace blanc de longueur variable dans les chaînes passées dans une commande, sans recourir à certains
sorte de citation de shell.

Si une chaîne de commande multiligne est fournie, les commandes sont exécutées de manière séquentielle. Si seulement
des commandes échoue, alors aucune des autres n'est exécutée et la cible n'est pas marquée comme
mis à jour, c'est-à-dire qu'une nouvelle signature n'est pas stockée pour la cible.

Normalement, si toutes les commandes réussissent, et renvoient un statut zéro (ou n'importe quelle plate-forme-
une indication spécifique de réussite est requise), puis une nouvelle signature est stockée pour le
cible. Si une commande signale par erreur un succès même après un échec, Cons sera
supposons que le fichier cible créé par cette commande est exact et à jour.

Le premier mot de chaque chaîne de commande, après expansion, est supposé être un exécutable
recherche la variable d'environnement `PATH' (qui est, à son tour, spécifiée par la
variable de construction 'ENV'). Si cette commande est trouvée sur le chemin, alors la cible sera
en dépendra : la commande sera donc automatiquement construite, si nécessaire. C'est
possible d'écrire des commandes en plusieurs parties dans certains shells, séparées par des points-virgules. Seulement le
le premier mot de commande dépendra cependant, donc si vous écrivez vos chaînes de commande
de cette façon, vous devez soit configurer explicitement une dépendance (avec la méthode `Depends'), soit
assurez-vous que la commande que vous utilisez est une commande système qui devrait être
disponible. S'il n'est pas disponible, vous obtiendrez, bien sûr, une erreur.

Si une commande (même une dans une commande multiligne) commence par `[perl]', le reste
de cette ligne de commande sera évalué par le Perl en cours d'exécution au lieu d'être forké par le
coquille. Si une erreur se produit lors de l'analyse de Perl ou si l'expression Perl renvoie 0 ou
undef, la commande sera considérée comme ayant échoué. Par exemple, voici un simple
commande qui crée un fichier `foo' directement depuis Perl :

$env = nouveau cons();
Commande $env 'foo',
qq([perl] open(FOO,'>foo');print FOO "hi\\n"; close(FOO); 1);

Notez que lorsque la commande est exécutée, vous êtes dans le même package que lorsque le Construire
or Conscrit fichier a été lu, vous pouvez donc appeler les fonctions Perl que vous avez définies dans le même
Construire or Conscrit fichier dans lequel la `Commande' apparaît :

$env = nouveau cons();
sous créer_fichier {
mon $fichier = shift;
open(FILE, ">$file");
print FICHIER "salut\n" ;
Fermer le fichier);
1 revenir;
}
Commande $env 'foo', "[perl] &create_file('%>')" ;

La chaîne Perl sera utilisée pour générer la signature du fichier dérivé, donc si vous
changez la chaîne, le fichier sera reconstruit. Le contenu de tous les sous-programmes que vous appelez,
cependant, ne font pas partie de la signature, donc si vous modifiez un sous-programme appelé tel que
`create_file' ci-dessus, la cible sera ne sauraient être reconstruit. Mise en garde de l'utilisateur.

Cons imprime normalement une commande avant de l'exécuter. Ce comportement est supprimé si le
premier caractère de la commande est `@'. Notez que vous devrez peut-être séparer le `@' de
le nom de la commande ou échappez-le pour empêcher `@cmd' de ressembler à un tableau pour les guillemets Perl
opérateurs qui effectuent l'interpolation :

# La première ligne de commande est incorrecte,
# car "@cp" ressemble à un tableau
# à la fonction Perl qq//.
# Utilisez plutôt le deuxième formulaire.
Commande $env 'foo', 'foo.in', qq(
@cp %< fichier temporaire
@ cp fichier temporaire %>
);

S'il y a des méta-caractères shell n'importe où dans la ligne de commande développée, comme `<',
`>', guillemets ou point-virgule, la commande sera effectivement exécutée en invoquant un
coquille. Cela signifie qu'une commande telle que :

cd truc

seul échouera typiquement, puisqu'il n'y a pas de commande `cd' sur le chemin. Mais la commande
chaîne:

cd $<:d; tar cf $>:f $<:f

lorsqu'il sera développé, il contiendra toujours le point-virgule du méta-caractère du shell, et un shell sera
invoqué pour interpréter la commande. Comme `cd' est interprété par ce sous-shell, la commande
s'exécutera comme prévu.

Pour spécifier une commande avec plusieurs cibles, vous pouvez spécifier une référence à une liste de
cibles. En Perl, une référence de liste peut être créée en plaçant une liste entre crochets.
D'où la commande suivante :

Commande $env ['foo.h', 'foo.c'], 'foo.template', q(
génération %1
);

peut être utilisé dans le cas où la commande `gen' crée deux fichiers, tous deux foo.h ainsi que foo.c.

La `Objets' méthode

La méthode `Objects' s'arrange pour créer les fichiers objets qui correspondent aux
fichiers source. Il est invoqué comme indiqué ci-dessous :

@files = Objets $env ;

Sous Unix, les fichiers source se terminant par .s ainsi que .c sont actuellement pris en charge et seront compilés
dans un nom du même fichier se terminant par .o. Par défaut, tous les fichiers sont créés en appelant
la commande externe qui résulte du développement de la variable de construction `CCCOM', avec
`%<' et `%>' définis respectivement sur les fichiers source et objet (voir la méthode `Command'
pour plus de détails sur l'extension). La variable `CPPPATH' est également utilisée lors de l'analyse des fichiers source
pour les dépendances. Il s'agit d'une liste de chemins d'accès séparés par deux-points, et est également utilisée pour créer
la variable de construction `_IFLAGS,' qui contiendra la liste appropriée de -`I'
options pour la compilation. Tous les noms de chemin relatifs dans `CPPPATH' sont interprétés comme relatifs
au répertoire dans lequel l'environnement de construction associé a été créé (valeur absolue
et les noms relatifs supérieurs peuvent également être utilisés). Cette variable est utilisée par 'CCCOM'. Le comportement
de cette commande peut être modifié en changeant l'une des variables qui sont interpolées
dans `CCCOM', comme `CC', `CFLAGS' et, indirectement, `CPPPATH'. Il est également possible de
remplacer la valeur de `CCCOM', elle-même. Par commodité, ce fichier renvoie la liste des
noms de fichiers d'objets.

La 'Programme' méthode

La méthode `Program' s'arrange pour lier le programme spécifié avec l'objet spécifié
des dossiers. Il est invoqué de la manière suivante :

Programme $env , ;

Le nom du programme aura la valeur de la variable de construction `SUFEXE' ajoutée (par
par défaut, `.exe' sur les systèmes Win32, rien sur les systèmes Unix) si le suffixe n'est pas déjà
présent.

Les fichiers source peuvent être spécifiés à la place des fichiers d'objets -- la méthode `Objects' sera
invoqué pour organiser la conversion de tous les fichiers en fichiers objets, et donc de tous les
les observations sur la méthode `Objects', ci-dessus, s'appliquent également à cette méthode.

La liaison réelle du programme sera gérée par une commande externe qui se traduit par
d'étendre la variable de construction `LINKCOM', avec `%<' défini sur les fichiers objets pour
être lié (dans l'ordre présenté), et `%>' défini sur la cible (voir la méthode `Command'
pour plus de détails sur l'extension). L'utilisateur peut définir des variables supplémentaires dans la construction
environnement, y compris `LINK', pour définir le programme à utiliser pour la liaison, `LIBPATH', un
liste de chemins de recherche de bibliothèque séparés par deux-points, à utiliser avec les spécifications de bibliothèque du
formulaire -llib, et `LIBS', en spécifiant la liste des bibliothèques à lier (dans l'un ou l'autre -llib
forme ou simplement comme noms de chemin. Les noms de chemin relatifs dans `LIBPATH' et `LIBS' sont interprétés
relatif au répertoire dans lequel l'environnement de construction associé est créé
(les noms absolus et relatifs supérieurs peuvent également être utilisés). Les inconvénients se configurent automatiquement
dépendances sur toutes les bibliothèques mentionnées dans `LIBS' : ces bibliothèques seront construites avant
la commande est liée.

La "Bibliothèque" méthode

La méthode `Library' s'arrange pour créer la bibliothèque spécifiée à partir de l'objet spécifié
des dossiers. Il est invoqué comme suit :

Bibliothèque $env , ;

Le nom de la bibliothèque aura la valeur de la variable de construction `SUFLIB' ajoutée (par
par défaut, `.lib' sur les systèmes Win32, `.a' sur les systèmes Unix) si le suffixe n'est pas déjà
présent.

Les fichiers source peuvent être spécifiés à la place des fichiers d'objets -- la méthode `Objects' sera
invoqué pour organiser la conversion de tous les fichiers en fichiers objets, et donc de tous les
les observations sur la méthode `Objects', ci-dessus, s'appliquent également à cette méthode.

La création proprement dite de la bibliothèque sera gérée par une commande externe qui résultera
d'étendre la variable de construction `ARCOM', avec `%<' défini sur les membres de la bibliothèque (dans
l'ordre présenté), et `%>' à la bibliothèque à créer (voir la méthode `Command' pour
détails de l'extension). L'utilisateur peut définir des variables dans l'environnement de construction qui
affecter le fonctionnement de la commande. Ceux-ci incluent `AR', le programme d'archivage à utiliser,
`ARFLAGS', qui peut être utilisé pour modifier les drapeaux donnés au programme spécifié par `AR',
et `RANLIB', le nom d'un programme de génération d'index d'archives, si nécessaire (si le
besoin ne nécessite pas cette dernière fonctionnalité, alors `ARCOM' doit être redéfini pour ne pas
référence 'RANLIB').

La méthode `Library' permet à la même bibliothèque d'être spécifiée dans plusieurs méthodes
invocations. Tous les objets contributeurs de toutes les invocations (qui peuvent provenir de
différents répertoires) sont combinés et générés par une seule commande d'archivage. Noter,
cependant, que si vous élaguez une construction de sorte que seule une partie d'une bibliothèque soit spécifiée, alors seulement
cette partie de la bibliothèque sera générée (le reste disparaîtra !).

La "Module" méthode

La méthode `Module' est une combinaison des méthodes `Programme' et `Commande'. Plutôt que
générant directement un programme exécutable, cette commande vous permet de spécifier votre propre
commande pour générer réellement un module. La méthode est invoquée comme suit :

Module $env , , ;

Cette commande est utile dans les cas où vous souhaitez créer, par exemple, dynamiquement
modules chargés ou bibliothèques de code liées statiquement.

La `Ça dépend' méthode

La méthode `Depends' vous permet de spécifier des dépendances supplémentaires pour une cible. Il est
invoqué comme suit :

Dépend de $env , ;

Cela peut être parfois utile, en particulier dans les cas où aucun scanner n'existe (ou est
accessible en écriture) pour des types de fichiers particuliers. Normalement, les dépendances sont calculées
automatiquement à partir d'une combinaison des dépendances explicites mises en place par la méthode
invocation ou en analysant les fichiers source.

Un ensemble de dépendances identiques pour plusieurs cibles peut être spécifié à l'aide d'une référence à
une liste de cibles. En Perl, une référence de liste peut être créée en entourant une liste d'un carré
supports. D'où la commande suivante :

Dépend de $env ['foo', 'bar'], 'input_file_1', 'input_file_2' ;

précise que les deux foo ainsi que barre dépendent des fichiers d'entrée répertoriés.

La 'Ignorer' méthode

La méthode `Ignore' vous permet d'ignorer explicitement les dépendances que Cons infère sur son
posséder. Il est invoqué comme suit :

Ignorer ;

Cela peut être utilisé pour éviter les recompilations dues à des changements dans les fichiers d'en-tête du système ou
utilitaires connus pour ne pas affecter les cibles générées.

Si, par exemple, un programme est construit dans un répertoire monté NFS sur plusieurs systèmes qui
avoir différentes copies de stdio.h, les différences affecteront les signatures de tous
cibles dérivées construites à partir de fichiers source qui `#include '. Cela causera tout
ces cibles à reconstruire lors d'un changement de système. Si ce n'est pas un comportement souhaitable,
alors la ligne suivante supprimera les dépendances sur le stdio.h fichier:

Ignorer '^/usr/include/stdio\.h$' ;

Notez que les arguments de la méthode `Ignore' sont des expressions régulières, donc spéciales
caractères doivent être échappés et vous souhaiterez peut-être ancrer le début ou la fin du
expression avec les caractères `^' ou `$'.

La "Sel" méthode

La méthode "Salt" ajoute une valeur constante au calcul de la signature pour chaque dérivé
fichier. Il est invoqué comme suit :

Sel $string ;

La modification de la valeur Salt forcera une reconstruction complète de chaque fichier dérivé. Cela peut être
utilisé pour forcer les reconstructions dans certaines circonstances souhaitées. Par exemple,

Sel `uname -s` ;

Forcerait une reconstruction complète de chaque fichier dérivé chaque fois que le système d'exploitation sur
lequel la construction est effectuée (comme indiqué par `uname -s') change.

La `Utiliser le cache' méthode

La méthode `UseCache' demande à Cons de maintenir un cache de fichiers dérivés, à partager
parmi des arborescences de construction distinctes du même projet.

UseCache("cache/ ") ⎪⎪ warn("répertoire cache introuvable");

La `CheminSource' méthode

La méthode `SourcePath' renvoie le véritable nom du chemin source d'un fichier, contrairement à la méthode
nom de chemin dans un répertoire de génération. Il est invoqué comme suit :

$path = CheminSource ;

La `ConsPath' méthode

La méthode `ConsPath' renvoie true si le chemin fourni est un fichier dérivable, et renvoie
undef (faux) sinon. Il est invoqué comme suit :

$résultat = ConsPath ;

La `SplitPath' méthode

La méthode `SplitPath' recherche plusieurs noms de chemin dans une chaîne séparés par la valeur par défaut
séparateur de chemin pour le système d'exploitation (':' sur les systèmes UNIX, ';' sur Windows NT), et
renvoie les noms complets. Il est invoqué comme suit :

@paths = SplitPath ;

La méthode `SplitPath' convertira les noms précédés de '#' en la construction de niveau supérieur appropriée
name (sans le '#') et convertira les noms relatifs en noms de niveau supérieur.

La `DirPath' méthode

La méthode `DirPath' renvoie le chemin de construction prénom(s) d'un répertoire ou d'une liste de répertoires.
Il est invoqué comme suit :

$cwd = DirPath ;

L'utilisation la plus courante de la méthode `DirPath' est :

$cwd = DirPath '.';

pour récupérer le chemin du répertoire courant d'une filiale Conscrit fichier.

La `CheminFichier' méthode

La méthode `FilePath' renvoie le chemin de construction prénom(s) d'un fichier ou d'une liste de fichiers. Il est
invoqué comme suit :

$file = FilePath ;

La "Aide" méthode

La méthode `Help' spécifie le texte d'aide qui sera affiché lorsque l'utilisateur appelle `cons
-h'. Cela peut être utilisé pour fournir une documentation sur des cibles, des valeurs, des builds spécifiques
options, etc. pour l'arborescence de construction. Il est invoqué comme suit :

Aider ;

La méthode `Help' ne peut être appelée qu'une seule fois et doit généralement être spécifiée en haut de la page.
niveau Construire fichier.

Extension Inconvénients


Primordial construction les variables

Il existe plusieurs façons d'étendre Cons, qui varient en degré de difficulté. Le plus simple
méthode consiste à définir votre propre environnement de construction, basé sur l'environnement par défaut,
mais modifié pour refléter vos besoins particuliers. Cela suffira souvent pour les
applications. Vous pouvez utiliser le constructeur `new' et les méthodes `clone' et `copy' pour
créer des environnements hybrides. Ces changements peuvent être entièrement transparents pour le sous-jacent
Conscrit fichiers.

L'ajout de neufs méthodes

Pour des changements un peu plus exigeants, vous pouvez ajouter de nouvelles méthodes aux "contre"
emballer. Voici un exemple d'extension très simple, `InstallScript', qui installe un
tcl dans un emplacement demandé, mais édite d'abord le script pour refléter une plate-forme-
chemin dépendant qui doit être installé dans le script :

# cons::InstallScript - Crée une version dépendante de la plate-forme d'un shell
# script en remplaçant la chaîne ``#!your-path-here'' par la plate-forme spécifique
# chemin $BIN_DIR.

sous contre ::InstallScript {
mon ($env, $dst, $src) = @_;
Commande $env $dst, $src, qq(
sed s+votre-chemin-ici+$BIN_DIR+ %< > %>
chmod oug+x %>
);
}

Notez que cette méthode est définie directement dans le package `cons' (en préfixant le nom
avec `contre ::'). Une modification effectuée de cette manière sera globalement visible pour tous les environnements,
et pourrait être appelé comme dans l'exemple suivant :

InstallScript $env "$BIN/foo", "foo.tcl" ;

Pour une petite amélioration de la généralité, la variable `BINDIR' pourrait être transmise en tant que
argument ou extrait de l'environnement de construction - comme `%BINDIR'.

Primordial méthodes

Au lieu d'ajouter la méthode à l'espace de noms `cons', vous pouvez définir un nouveau package
qui hérite des méthodes existantes du paquet `cons' et remplace ou en ajoute d'autres. Ce
peut être fait en utilisant les mécanismes d'héritage de Perl.

L'exemple suivant définit un nouveau package `cons::switch' qui remplace le standard
Méthode 'Bibliothèque'. La méthode remplacée construit des modules de bibliothèque liés, plutôt que des bibliothèques
les archives. Un nouveau constructeur est fourni. Les environnements créés avec ce constructeur
avoir la nouvelle méthode de bibliothèque ; d'autres non.

paquet contre ::switch;
COMMENCER {@ISA = 'contre'}

sous nouveau {
décalage;
bénisse les nouveaux cons(@_);
}

sous Bibliothèque {
ma($env) = décalage ;
ma($lib) = shift ;
mon(@objs) = Objets $env @_;
Commande $env $lib, @objs, q(
%LD -r %LDFLAGS %< -o %>
);
}

Cette fonctionnalité peut être invoquée comme dans l'exemple suivant :

$env = new cons ::switch(@overrides);

Bibliothèque $env 'lib.o', 'foo.c', 'bar.c' ;

Invoquer Inconvénients


La commande `cons' est généralement invoquée depuis la racine de l'arborescence de construction. UNE Construire filet
doit exister dans ce répertoire. Si l'argument `-f' est utilisé, alors un autre Construire
peut être utilisé (et, éventuellement, une racine alternative, puisque `cons' sera cd vers Construire
répertoire contenant le fichier).

Si `cons' est invoqué depuis un enfant de la racine de l'arborescence de construction avec l'argument `-t', il
remontera la hiérarchie des répertoires à la recherche d'un Construire fichier. (Un autre nom peut
toujours être spécifié avec `-f'.) Les cibles fournies sur la ligne de commande seront modifiées
être relatif à la découverte Construire fichier. Par exemple, à partir d'un répertoire contenant
un niveau supérieur Construire fichier, l'invocation suivante :

% cd libfoo/sous-répertoire
% contre -t cible

est exactement équivalent à :

% contre libfoo/sous-répertoire/cible

Si des cibles "par défaut" sont spécifiées dans la hiérarchie des répertoires Construire or
Conscrit fichiers, uniquement les cibles par défaut au niveau ou en dessous du répertoire à partir duquel `cons -t'
a été invoqué sera construit.

La commande est invoquée comme suit :

les inconvénients --

De arguments peut être l'un des éléments suivants, dans n'importe quel ordre :

l'objectif Construire la cible spécifiée. Si l'objectif est un répertoire, puis construit récursivement
tout dans ce répertoire.

+motif Limiter le Conscrit fichiers considérés uniquement ceux qui correspondent modèle, lequel est
une expression régulière Perl. Plusieurs arguments `+' sont acceptés.

prénom=
Sets prénom évaluer vague dans le hachage `ARG' passé au niveau supérieur Construire fichier.

`-cc' Affiche la commande qui aurait été exécutée lors de la récupération depuis le cache. Non
l'indication que le fichier a été récupéré est donnée ; c'est utile pour
générer des journaux de construction qui peuvent être comparés aux journaux de construction réels.

`-cd' Désactive toutes les mises en cache. Ne pas récupérer du cache ni vider le cache.

`-cr' Construit les dépendances dans un ordre aléatoire. Ceci est utile lors de la construction de plusieurs
arborescences similaires avec mise en cache activée.

`-cs' Synchronise les cibles de construction existantes qui sont à jour avec le cache.
Ceci est utile si la mise en cache a été désactivée avec -cc ou récemment activée
avec UseCache.

`-d' Active le débogage des dépendances.

`-f'
Utiliser le fichier spécifié au lieu de Construire (mais d'abord changer pour contenir
répertoire de filet).

`-h' Affiche un message d'aide local à la construction actuelle si un tel est défini, et quitte.

`-k' Continuer aussi loin que possible après les erreurs.

`-o'
Lire le fichier de remplacement filet.

`-p' Affiche les produits de construction dans les arborescences spécifiées. Aucune construction n'est tentée.

`-pa' Afficher les produits de construction et les actions associées. Aucune construction n'est tentée.

`-pw' Afficher les produits et où ils sont définis. Aucune construction n'est tentée.

`-q' Ne soyez pas prolixe sur l'installation et la suppression de cibles.

`-r' Supprime les produits de construction associés à . Aucune construction n'est tentée.

`-R'
Rechercher des fichiers dans repos. Plusieurs -R repos les répertoires sont recherchés dans le
ordre spécifié.

`-t' Remonte la hiérarchie des répertoires à la recherche d'un Construire fichier, s'il n'en existe pas
dans le répertoire courant. Les cibles seront modifiées pour être relatives à la
Construire fichier.

`-v' Affiche la version `cons' et continue le traitement.

`-V' Affiche la version `cons' et quitte.

`-wf'
Écrivez tous les noms de fichiers considérés dans filet.

`-x' Affiche un message d'aide similaire à celui-ci et quitte.

Et arguments de construction peut être n'importe quel argument que vous souhaitez traiter dans le Construire fichier.
Notez qu'il devrait y avoir un -- séparant les arguments contre et les arguments que vous
souhaitez traiter dans le Construire fichier.

Traitement de arguments de construction peut être fait par n'importe quel package standard comme Getopt ou ses
variantes ou tout package défini par l'utilisateur. contre passera dans le arguments de construction as @ARGV ainsi que
ne tentera pas d'interpréter quoi que ce soit après la --.

% contre -R /usr/local/repository -d os=solaris +driver -- -c test -f DEBUG

passerait la suite aux inconvénients

-R /usr/local/repository -dos=solaris +pilote

et les suivants, au niveau supérieur Construire fichier comme @ARGV

-c test -f DÉBOGAGE

Notez que `cons -r .' équivaut à un "make clean" récursif complet, mais ne nécessite pas
soutien dans le Construire fichier ou tout Conscrit des dossiers. Ceci est très utile si vous êtes
compiler les fichiers dans les répertoires source (si vous séparez les construire ainsi que Exporter répertoires,
alors vous pouvez simplement supprimer les répertoires).

Les options `-p', `-pa' et `-pw' sont extrêmement utiles pour une aide à la lecture
scripts ou les déboguer. Si vous voulez savoir quel script installe exporter/inclure/foo.h,
par exemple, tapez simplement :

% contre -pw exporter/inclure/foo.h

En utilisant ainsi que écriture dépendance scanners


QuickScan permet de configurer des analyseurs simples indépendants de la cible pour les fichiers source. Seulement
un analyseur QuickScan peut être associé à n'importe quel fichier source et environnement donné.

QuickScan est appelé comme suit :

QuickScan CONSENV CODEREF, NOM DE FICHIER [, CHEMIN]

Le sous-programme référencé par CODEREF est censé renvoyer une liste de noms de fichiers inclus
directement par FICHIER. Ces noms de fichiers seront, à leur tour, scannés. L'argument PATH facultatif
fournit un chemin de recherche pour trouver FILENAME et/ou les fichiers renvoyés par l'utilisateur
sous-programme. Le PATH peut être une référence à un tableau de noms de répertoires de recherche, ou un
chaîne de noms séparés par le caractère séparateur du système (':' sur les systèmes UNIX, ';' sur
WindowsNT).

Le sous-programme est appelé une fois pour chaque ligne du fichier, avec $_ défini sur la ligne courante.
Si la sous-routine a besoin de regarder des lignes supplémentaires, ou, d'ailleurs, le fichier entier,
alors il peut les lire lui-même, à partir du descripteur de fichier SCAN. Il peut également terminer la boucle, si
il sait qu'aucune autre information d'inclusion n'est disponible, en fermant le descripteur de fichier.

Qu'un chemin de recherche soit fourni ou non, QuickScan essaie d'abord de rechercher le fichier
par rapport au répertoire courant (pour le fichier de niveau supérieur fourni directement à QuickScan),
soit depuis le répertoire contenant le fichier qui a référencé le fichier. Ce n'est pas très
général, mais semble assez bon - surtout si vous avez le luxe d'écrire votre propre
utilitaires et peut contrôler l'utilisation du chemin de recherche de manière standard. Finalement, le
le chemin de recherche est, actuellement, séparé par deux-points. Cela peut ne pas rendre le camp NT heureux.

Voici un exemple réel, tiré d'un Construire fichier ici :

sous contre::SMFgen {
mon($env, @tables) = @_;
foreach $t (@tables) {
$env->QuickScan(sub { /\b\S*?\.smf\b/g }, "$t.smf",
$env->{SMF_INCLUDE_PATH});
$env->Commande(
["$t.smdb.cc","$t.smdb.h","$t.snmp.cc","$t.ami.cc", "$t.http.cc"],
"$t.smf",
q(
smfgen %( %SMF_INCLUDE_OPT %) %
)
);
}
}

[NOTEZ que la forme `$env->QuickScan ...' et `$env->Command ...' ne doit pas être
nécessaire, mais, pour une raison quelconque, est requis pour cette invocation particulière. Cela apparaît
être un bogue dans Perl ou un malentendu de ma part ; ce style d'invocation ne
paraissent toujours nécessaires.]

Ceci trouve tous les noms du formulaire .smf dans le fichier. Il renverra les noms même si
ils se trouvent dans les commentaires, mais ce n'est pas grave (le mécanisme pardonne les fichiers supplémentaires ;
ils sont simplement ignorés en supposant que le fichier manquant sera remarqué lorsque le
programme, dans cet exemple, smfgen, est réellement appelé).

Un analyseur n'est appelé pour un fichier source donné que s'il est requis par une cible dans le
arbre. Il n'est invoqué qu'une seule fois pour un fichier source donné.

Voici une autre façon de construire le même scanner. Celui-ci utilise une référence de code explicite,
et aussi (inutilement, dans ce cas) lit l'intégralité du fichier lui-même :

sous myscan {
mon(@inclut);
faire {
push (@includes, /\b\S*?\.smf\b/g);
} tandis que ;
@inclut
}

Notez que l'ordre de la boucle est inversé, avec le test de boucle à la fin. C'est
car la première ligne est déjà lue pour vous. Ce scanner peut être attaché à une source
dossier par :

QuickScan $env \myscan, "$_.smf" ;

SUPPORT ET SUGGESTIONS


Les inconvénients sont maintenus par la communauté des utilisateurs. Pour vous inscrire, envoyez un mail à contre-discuter-
[email protected] avec corps inscrire.

Veuillez signaler toute suggestion via le [email protected] liste de diffusion.

Utilisez les inconvénients en ligne en utilisant les services onworks.net


Serveurs et postes de travail gratuits

Télécharger des applications Windows et Linux

  • 1
    turcdevops
    turcdevops
    TurkDevOps a ?k kaynak yaz?l?m
    geli?tirici topluluklar? DevTurks-Équipe
    Tarafándan desteklenmektedir..
    Fonctionnalités : https://github.com/turkdevopshttps://turkdevops.g...
    Télécharger turkdevops
  • 2
    asammdf
    asammdf
    *asammdf* est un analyseur rapide Python et
    éditeur pour l'ASAM (Association pour
    Standardisation de l'automatisation et
    Systèmes de mesure) MDF / MF4
    (Format des données de mesure...
    Télécharger asammdf
  • 3
    LAME (Lame n'est pas un encodeur MP3)
    LAME (Lame n'est pas un encodeur MP3)
    LAME est un outil pédagogique à utiliser
    pour en savoir plus sur l'encodage MP3. Le
    L'objectif du projet LAME est d'améliorer
    la psycho acoustique, la qualité et la rapidité
    de député...
    Télécharger LAME (Lame n'est pas un encodeur MP3)
  • 4
    wxPython
    wxPython
    Un ensemble de modules d'extension Python qui
    encapsulez les classes d'interface graphique multiplateforme à partir de
    wxWidgets.. Public : Développeurs. Utilisateur
    interface : Système X Window (X11), Win32...
    Télécharger wxPython
  • 5
    gestionnaire de fichiers de paquets
    gestionnaire de fichiers de paquets
    Ceci est le gestionnaire de fichiers du pack Total War
    projet, à partir de la version 1.7. UNE
    courte introduction à Warscape
    modding : ...
    Télécharger le packfilemanager
  • 6
    IPerf2
    IPerf2
    Un outil de trafic réseau pour mesurer
    Performances TCP et UDP avec métriques
    autour du débit et de la latence. Les
    les objectifs comprennent le maintien d'une activité
    morue iperf...
    Télécharger IPerf2
  • Plus "

Commandes Linux

Ad