EnglischFranzösischSpanisch

Ad


OnWorks-Favicon

Nachteile – Online in der Cloud

Führen Sie Nachteile beim kostenlosen Hosting-Anbieter OnWorks über Ubuntu Online, Fedora Online, den Windows-Online-Emulator oder den MAC OS-Online-Emulator aus

Dies ist der Befehl, der beim kostenlosen Hosting-Anbieter OnWorks mit einer unserer zahlreichen kostenlosen Online-Workstations wie Ubuntu Online, Fedora Online, dem Windows-Online-Emulator oder dem MAC OS-Online-Emulator ausgeführt werden kann

PROGRAMM:

NAME/FUNKTION


Nachteile – Ein Software-Konstruktionssystem

BESCHREIBUNG


Eine Anleitung und Referenz für Version 2.2.0

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

Dieses Programm ist freie Software; Sie können es unter den Bedingungen von . weitergeben und/oder ändern
die GNU General Public License, wie von der Free Software Foundation veröffentlicht; entweder
Version 2 der Lizenz oder (nach Ihrer Wahl) eine spätere Version.

Dieses Programm wird in der Hoffnung verteilt, dass es nützlich ist, jedoch OHNE JEGLICHE GEWÄHRLEISTUNG;
auch ohne die stillschweigende Garantie der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
Weitere Informationen finden Sie in der GNU General Public License.

Zusammen mit diesem Programm sollten Sie eine Kopie der GNU General Public License erhalten haben;
siehe Datei COPYING. Wenn nicht, schreiben Sie an die Free Software Foundation, Inc., 59 Temple
Ort – Suite 330, Boston, MA 02111-1307, USA.

Einleitung


Nachteile ist in erster Linie ein System zum Erstellen von Software, unterscheidet sich jedoch deutlich davon
bisherige Software-Konstruktionssysteme. Cons wurde von Grund auf für den Deal konzipiert
einfach durch die Erstellung von Software, die über mehrere Quellverzeichnisse verteilt ist. Nachteile
erleichtert die Erstellung von Build-Skripten, die einfach, verständlich und wartbar sind.
Cons stellt sicher, dass komplexe Software einfach und genau reproduzierbar ist.

Cons nutzt eine Reihe von Techniken, um all dies zu erreichen. Konstruktionsskripte sind einfach
Perl-Skripte, was sie sowohl leicht verständlich als auch sehr flexibel macht. Globales Scoping von
Variablen werden durch einen Import-/Exportmechanismus zum Austausch von Informationen zwischen ihnen ersetzt
Skripte, wodurch die Lesbarkeit und Wartbarkeit jedes Skripts erheblich verbessert wird.
Hoch- und Tiefbau Umgebungen werden eingeführt: Dies sind Perl-Objekte, die das erfassen
Informationen, die zur Steuerung des Build-Prozesses erforderlich sind. Es werden mehrere Umgebungen verwendet
wenn unterschiedliche Semantiken zum Generieren von Produkten im Build-Baum erforderlich sind. Nachteile
implementiert eine automatische Abhängigkeitsanalyse und nutzt diese, um das Ganze global zu sequenzieren
bauen. Varianten-Builds können problemlos aus einem einzigen Quellbaum erstellt werden. Intelligenter Aufbau
Bei der Arbeit an lokalisierten Änderungen ist eine Teilmenge möglich. Es können Überschreibungen eingerichtet werden
Bauanweisungen können einfach überschrieben werden, ohne dass Skripts geändert werden müssen. MD5-Verschlüsselung
Unterschriften sind mit abgeleiteten Dateien verknüpft und werden verwendet, um genau zu bestimmen, ob
Eine bestimmte Datei muss neu erstellt werden.

Obwohl Cons all das oben Genannte und noch mehr bietet, bleibt es einfach und benutzerfreundlich. Dieser Wille,
Hoffentlich wird Ihnen das klar, wenn Sie den Rest dieses Dokuments lesen.

Warum Nachteile? Warum nicht Machen?


Nachteile ist ein um Ersatz. In den folgenden Abschnitten betrachten wir einige davon
unerwünschte Eigenschaften von make--und typischen Build-Umgebungen, die auf make--that basieren
motivierte die Entwicklung von Cons.

Bauen Komplexität

Herkömmliche markenbasierte Systeme jeder Größe neigen dazu, recht komplex zu werden. Die Originalmarke
Der Nutzen und seine Derivate haben auf verschiedene Weise zu dieser Tendenz beigetragen. Machen ist
nicht gut im Umgang mit Systemen, die über mehrere Verzeichnisse verteilt sind. Diverse Arbeits-
Um diese Schwierigkeit zu überwinden, werden Rundungen eingesetzt. Die übliche Wahl ist make zum Aufrufen
selbst rekursiv für jedes Unterverzeichnis eines Builds. Dies führt zu kompliziertem Code
Dabei ist oft unklar, wie eine Variable gesetzt wird bzw. welche Auswirkungen die Einstellung einer Variable hat
wird sich auf den Bau als Ganzes auswirken. Die Skriptsprache make wurde schrittweise erweitert
um mehr Möglichkeiten zu bieten, aber diese haben bereits weitgehend zu Unordnung geführt
überdehnte Sprache. Oftmals werden Builds zur Bereitstellung in mehreren Durchgängen durchgeführt
entsprechende Produkte von einem Verzeichnis in ein anderes Verzeichnis. Dies stellt eine weitere dar
Erhöhung der Build-Komplexität.

Bauen Reproduzierbarkeit

Der Fluch aller Marken war schon immer der richtige Umgang mit Abhängigkeiten. Meistens ein
Es wird versucht, die Abhängigkeiten innerhalb eines einzelnen Verzeichnisses angemessen zu berücksichtigen, aber nein
Es wird ernsthaft versucht, die Arbeit zwischen Verzeichnissen zu erledigen. Auch wenn es Abhängigkeiten gibt
Wenn es richtig funktioniert, verlassen Sie sich auf einen einfachen Zeitstempelvergleich, um festzustellen, ob
Eine Datei ist in Bezug auf ihre abhängigen Dateien veraltet. Dies ist im Allgemeinen nicht ausreichend für
Bestimmen, wann eine Datei erneut abgeleitet werden soll. Wenn es sich beispielsweise um eine externe Bibliothek handelt
neu erstellt und dann „eingerastet“ werden, können die Zeitstempel in den neu erstellten Dateien vorhanden sein
wird wahrscheinlich früher sein als der letzte örtliche Bau, da er gebaut wurde, bevor er sichtbar wurde.

Variante baut

Make bietet nur begrenzte Möglichkeiten zur Handhabung von Varianten-Builds. Mit der Verbreitung
von Hardwareplattformen und der Notwendigkeit von debuggbarem vs. optimiertem Code, die Fähigkeit dazu
Eine einfache Erstellung dieser Varianten ist unerlässlich. Noch wichtiger: Wenn Varianten erstellt werden, ist dies der Fall
Wichtig ist, die Varianten entweder trennen oder reproduzieren zu können
Original oder Variante nach Belieben. Mit make ist es sehr schwierig, die Builds aufzuteilen
mehrere Build-Verzeichnisse, getrennt von der Quelle. Und wenn diese Technik nicht verwendet wird,
Es ist auch praktisch unmöglich, jederzeit zu garantieren, welche Variante vorhanden ist
den Baum, ohne auf einen kompletten Neuaufbau zurückgreifen zu müssen.

Aufbewahrungsorte

Make bietet nur begrenzte Unterstützung für die Erstellung von Software aus Code, der in einem vorhanden ist
zentrale Repository-Verzeichnisstruktur. Die VPATH-Funktion von GNU make (und einigen anderen
make-Implementierungen) soll dies bereitstellen, funktioniert aber nicht wie erwartet: es
ändert den Pfad der Zieldatei zu früh in der Analyse in den VPATH-Namen und daher
sucht nach allen Abhängigkeiten im VPATH-Verzeichnis. Um eine korrekte Entwicklung sicherzustellen
Builds ist es wichtig, eine Datei in einem lokalen Build-Verzeichnis erstellen und haben zu können
alle Dateien in einem Code-Repository (in Make-Begriffen ein VPATH-Verzeichnis), die von der lokalen Datei abhängen
Die Datei wird ordnungsgemäß neu erstellt. Dies ist mit VPATH nicht möglich, ohne viel zu programmieren
komplexes Repository-Wissen direkt in die Makefiles.

Verwahrung it einfach


Einige der Schwierigkeiten mit make wurden oben genannt. In diesem und folgenden
In den folgenden Abschnitten werden wir Nachteile vorstellen und zeigen, wie diese Probleme angegangen werden.

Perl Skripte

Cons basiert auf Perl. Das heißt, Cons-Skripte--Wehrpflicht und Konstruieren Dateien, das Äquivalent
zu Make-Datei or Makefile--sind alle in Perl geschrieben. Dies bietet einen unmittelbaren Vorteil: die
Die Sprache zum Schreiben von Skripten ist vertraut. Auch wenn Sie kein Perl sind
Für Programmierer ist es hilfreich zu wissen, dass Perl im Grunde nur eine einfache deklarative Sprache ist.
mit einem klar definierten Kontrollfluss und vertrauter Semantik. Es gibt Variablen, die sich verhalten
im Grunde so, wie man es von ihnen erwarten würde: Unterroutinen, Kontrollfluss und so weiter. Dort
Für Cons wird keine spezielle Syntax eingeführt. Die Verwendung von Perl als Skriptsprache
vereinfacht die Aufgabe, die passende Lösung für oft komplexe Probleme auszudrücken
Anforderungen an einen Bau.

Hallo, Welt!

Um die folgende Diskussion zu untermauern, erfahren Sie hier, wie Sie das erstellen könnten Hallo, Welt! C
Bewerbung mit Nachteilen:

$env = neue Nachteile();
Programm $env 'hello', 'hello.c';

Wenn Sie dieses Skript in einem Verzeichnis installieren, geben Sie dem Skript einen Namen Konstruierenund erstellen Sie die
Hallo c Quelldatei im selben Verzeichnis, dann können Sie „cons hello“ eingeben, um die zu erstellen
Anwendung:

% Nachteile Hallo
cc -c hallo.c -o hallo.o
cc -o hallo hallo.o

Hoch- und Tiefbau Umgebungen

Eine wesentliche Vereinfachung von Cons ist die Idee von a Baugewerbe Umwelt. Eine Konstruktion
Umgebung ist ein Objekt gekennzeichnet durch eine Reihe von Schlüssel/Wert-Paaren und eine Reihe von Methoden.
Um Cons mitzuteilen, wie etwas erstellt werden soll, rufen Sie die entsprechende Methode über an auf
geeignete Bauumgebung. Betrachten Sie das folgende Beispiel:

$env = neue Nachteile(
CC => 'gcc',
LIBS => 'libworld.a'
);

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

In diesem Fall verwenden wir nicht wie bisher die standardmäßige Konstruktionsumgebung
hat den Wert von „CC“ überschrieben, sodass stattdessen das GNU C Compiler-Äquivalent verwendet wird. Seit
diese Version von Hallo, Welt! erfordert eine Bibliothek, libworld.a, wir haben das angegeben
Das in dieser Umgebung verknüpfte Programm sollte mit dieser Bibliothek verknüpft werden. Wenn die Bibliothek
existiert schon, schön und gut, aber wenn nicht, dann müssen wir auch die Aussage einfügen:

Bibliothek $env 'libworld', 'world.c';

Wenn Sie nun „cons hello“ eingeben, wird die Bibliothek erstellt, bevor das Programm verknüpft wird, und
Natürlich wird „gcc“ zum Kompilieren beider Module verwendet:

% Nachteile Hallo
gcc -c hallo.c -o hallo.o
gcc -c welt.c -o welt.o
ar r libworld.a world.o
ar: libworld.a erstellen
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

automatische und abschließen Abhängigkeit Analyse

Mit Cons werden Abhängigkeiten automatisch gehandhabt. Beachten Sie, dass wir das vorherige Beispiel fortsetzen
das, wenn wir ändern Welt.c, Welt.o wird neu kompiliert, libworld.a neu erstellt, und HELLO
neu verlinkt:

% vi Welt.c
[BEARBEITEN]
% Nachteile Hallo
gcc -c welt.c -o welt.o
ar r libworld.a world.o
ar: libworld.a erstellen
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

Dies ist ein relativ einfaches Beispiel: Cons „weiß“ Welt.o hängt ab von Welt.cDa
Die Abhängigkeit wird explizit durch die Methode „Library“ eingerichtet. Das weiß es auch libworld.a
hängt ab von Welt.o und dass HELLO hängt ab von libworld.a, alles aus ähnlichen Gründen.

Nun stellt sich heraus, dass Hallo c enthält auch die Schnittstellendefinitionsdatei, Welt.h:

% emacs world.h
[BEARBEITEN]
% Nachteile Hallo
gcc -c hallo.c -o hallo.o
gcc -o hallo hallo.o libworld.a

Woher weiß Cons das? Hallo c Dazu gehören Welt.h, Und das hallo.o muss also sein
neu kompiliert? Im Moment genügt es, das zu sagen, wenn man darüber nachdenkt, ob oder nicht hallo.o ist oben-
Bisher ruft Cons einen Scanner für seine Abhängigkeit auf. Hallo c. Dieser Scanner zählt die auf
Dateien enthalten von Hallo c um eine Liste weiterer darüber hinausgehender Abhängigkeiten zu erstellen
wird durch das Cons-Skript explizit gemacht. Dieser Prozess ist rekursiv: alle darin enthaltenen Dateien
Die enthaltenen Dateien werden ebenfalls gescannt.

Ist das nicht teuer? Die Antwort lautet: Es kommt darauf an. Wenn Sie einen vollständigen Aufbau eines großen Systems durchführen,
Die Scanzeit ist unbedeutend. Wenn Sie ein großes System neu erstellen, wird dies bei Cons der Fall sein
Verbringen Sie eine ganze Menge Zeit damit, darüber nachzudenken, bevor Sie entscheiden, dass nichts sein muss
erledigt (wenn auch nicht unbedingt mehr Zeit als nötig!). Die gute Nachricht ist, dass Cons es schafft
Es ist sehr einfach, Ihren Build intelligent zu unterteilen, wenn Sie an lokalisierten Änderungen arbeiten.

automatische globale bauen Sequenzierung

Weil Cons eine vollständige und genaue Abhängigkeitsanalyse durchführt, und zwar weltweit, für
Während des gesamten Builds ist Cons in der Lage, diese Informationen zu nutzen, um die volle Kontrolle darüber zu übernehmen Sequenzierung
des Baus. Diese Reihenfolge ist in den obigen Beispielen deutlich zu erkennen und entspricht what
was Sie für make erwarten würden, wenn ein vollständiger Satz an Abhängigkeiten vorliegt. Mit Cons verlängert sich dies
trivial zu größeren Builds mit mehreren Verzeichnissen. Daraus ergibt sich die ganze damit verbundene Komplexität
um sicherzustellen, dass ein Build korrekt organisiert ist – einschließlich der Hierarchie mit mehreren Durchgängen
baut – wird eliminiert. Wir werden dies in den nächsten Abschnitten weiter besprechen.

Building grosse Bäume – immer noch nur as einfach


A Hierarchie of bauen Skripte

Ein größerer Build in Cons wird durch die Erstellung einer Hierarchie von organisiert bauen Skripte. Oben
des Baums wird ein Skript aufgerufen Konstruieren. Die übrigen Skripte sind vereinbarungsgemäß jeweils
namens Wehrpflicht. Diese Skripte sind ganz einfach durch den „Build“ miteinander verbunden.
Befehle „Exportieren“ und „Importieren“.

Das Bauen Befehl

Der Befehl „Build“ benötigt eine Liste von Wehrpflicht Dateinamen und ordnet deren Zuordnung zu
im Bau enthalten. Zum Beispiel:

Erstellen Sie qw(
Fahrer/Display/Rekrut
Treiber/Maus/Conscript
Parser/Rekrut
Versorgungsunternehmen/Rekrut
);

Dies ist eine einfache zweistufige Hierarchie von Build-Skripten: alle untergeordneten Wehrpflicht Dateien
werden in der obersten Ebene erwähnt Konstruieren Datei. Beachten Sie, dass nicht alle Verzeichnisse im Baum
Es sind unbedingt Build-Skripte mit ihnen verknüpft.

Dies könnte auch als mehrstufiges Skript geschrieben werden. Zum Beispiel die Konstruieren Datei könnte
diesen Befehl enthalten:

Erstellen Sie qw(
Parser/Rekrut
Fahrer/Rekrut
Versorgungsunternehmen/Rekrut
);

und dem Wehrpflicht Datei in das Treiber Verzeichnis könnte Folgendes enthalten:

Erstellen Sie qw(
Anzeige/Rekrut
Maus/Rekrut
);

Die Erfahrung hat gezeigt, dass das frühere Modell etwas einfacher zu verstehen ist, da das
Der gesamte Baubaum liegt auf der obersten Ebene vor Ihnen. Hybridsysteme sind
auch möglich. Eine separat verwaltete Komponente, die in eine integriert werden muss
Der Build-Baum kann sich beispielsweise an einer Stelle in den Build-Baum einbinden, aber seine eigene definieren
Bauhierarchie.

Standardmäßig ändert Cons sein Arbeitsverzeichnis nicht in das Verzeichnis, das a enthält
Tochtergesellschaft Wehrpflicht Datei, die es enthält. Dieses Verhalten kann für einen Build von aktiviert werden
Angabe, in der obersten Ebene Konstruieren Datei:

Conscript_chdir 1;

Wenn diese Option aktiviert ist, ändert sich „Cons“ zur Tochtergesellschaft Wehrpflicht Verzeichnis, in dem die Datei enthalten ist
während Sie diese Datei einlesen, und wechseln Sie dann zurück zum Verzeichnis der obersten Ebene, sobald die Datei geöffnet ist
wurde bearbeitet.

Es wird erwartet, dass dieses Verhalten in einer zukünftigen Version von Cons zum Standard wird.
Um sich auf diesen Übergang vorzubereiten, bleiben Builds, die erwarten, dass Cons an der Spitze des Builds bleiben
während es in einer Tochtergesellschaft liest Wehrpflicht Datei sollte diese Funktion explizit deaktivieren als
folgt:

Conscript_chdir 0;

Relativ, Top-Verwandter, und Absolute Datei Namen

Möglicherweise ist Ihnen aufgefallen, dass die im Build-Befehl angegebenen Dateinamen relativ zu sind
der Speicherort des Skripts, von dem aus es aufgerufen wird. Dies gilt im Allgemeinen für andere Dateinamen
Argumente auch für andere Befehle, obwohl wir das hier auch erwähnen könnten, wenn Sie beginnen
einen Dateinamen mit einem Rautenzeichen, „#“, dann wird diese Datei relativ zur obersten Datei interpretiert.
Level-Verzeichnis (wo die Konstruieren Datei befindet). Und es überrascht nicht, wenn Sie damit beginnen
mit „/“, dann wird es als absoluter Pfadname betrachtet. Dies gilt auch für Systeme
die einen umgekehrten Schrägstrich anstelle eines Schrägstrichs verwenden, um absolute Pfade zu benennen.

Die richtigen Module in bauen Skripte

Sie können jeweils Module hineinziehen Wehrpflicht Datei mit dem normalen Perl-Befehl „use“ oder „require“
Aussagen:

Benutze Englisch;
require My::Module;

Jedes „use“ oder „require“ wirkt sich nur auf das eine aus Wehrpflicht Datei, in der es erscheint. Um a zu verwenden
Modul in mehreren Wehrpflicht Dateien müssen Sie in jede eine „use“- oder „require“-Anweisung einfügen
einer, der das Modul benötigt.

Geltungsbereich of Variablen

Die oberste Ebene Konstruieren Datei und alles Wehrpflicht Dateien beginnen ihr Leben in einem gemeinsamen, separaten Perl
Paket. Nachteile Steuert die Symboltabelle für das Paket, sodass die Symboltabelle für
Jedes Skript ist leer, bis auf das Konstruieren Datei, die einen Teil der Befehlszeile abruft
Argumente. Alle Variablen, die gesetzt oder verwendet werden, werden daher vom Skript gesetzt
selbst – nicht durch ein externes Skript.

Variablen können explizit sein importiert durch ein Skript aus seinem übergeordneten Skript. Um eine zu importieren
variabel, das muss es gewesen sein exportiert vom übergeordneten Element erstellt und initialisiert (andernfalls ein Fehler).
wird passieren).

Das Exportieren Befehl

Der Befehl „Export“ wird wie im folgenden Beispiel verwendet:

$env = neue Nachteile();
$INCLUDE = "#export/include";
$LIB = "#export/lib";
Export qw( env INCLUDE LIB );
Erstellen Sie qw( util/Conscript );

Die Werte der in der „Export“-Liste genannten einfachen Variablen werden weggeschmissen
durch alle nachfolgenden „Build“-Befehle. Der Befehl „Export“ exportiert nur Perl Skalar
Variablen, also Variablen, deren Name mit „$“ beginnt. Andere Variablen, Objekte usw.
kann per Referenz exportiert werden – aber alle Skripte verweisen auf dasselbe Objekt, und zwar auf dieses
Das Objekt sollte von den untergeordneten Skripten und vom Original als schreibgeschützt betrachtet werden
Skript exportieren. Es ist jedoch akzeptabel, dem exportierten Skalar einen neuen Wert zuzuweisen
Variable – dadurch wird die zugrunde liegende Variable, auf die verwiesen wird, nicht geändert. Diese Sequenz, z
Beispiel, ist in Ordnung:

$env = neue Nachteile();
Export qw( env INCLUDE LIB );
Erstellen Sie qw( util/Conscript );
$env = neue Nachteile(CFLAGS => '-O');
Build qw( other/Conscript );

Dabei spielt es keine Rolle, ob die Variable vor oder nach dem „Export“-Befehl gesetzt wird. Der
Wichtig ist der Wert der Variablen zum Zeitpunkt der Ausführung des Befehls „Build“.
Das ist es, was weggeschmissen wird. Alle nachfolgenden „Export“-Befehle übrigens
Machen Sie die erste ungültig: Sie müssen alle Variablen angeben, die Sie exportieren möchten
Befehl „Exportieren“.

Das Import Befehl

Mit dem Befehl „Export“ exportierte Variablen können von in untergeordnete Skripte importiert werden
Befehl „Importieren“. Das Tochterskript importiert Variablen immer direkt aus dem
überlegenes Drehbuch. Betrachten Sie dieses Beispiel:

Import qw( env INCLUDE );

Dies ist nur zulässig, wenn das übergeordnete Skript sowohl „$env“ als auch „$INCLUDE“ exportiert hat. Es muss auch
haben jeder dieser Variablen Werte gegeben. Es ist in Ordnung, nur das Nebenskript zu verwenden
Importieren Sie eine Teilmenge der exportierten Variablen (in diesem Beispiel „$LIB“, die exportiert wurde von
(das vorherige Beispiel wird nicht importiert).

Alle importierten Variablen werden automatisch wieder exportiert, also die Reihenfolge:

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

stellt sowohl „$env“ als auch „$INCLUDE“ für die Tochterdatei bereit. Wenn nur „$env“ sein soll
exportiert, dann reicht Folgendes aus:

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

Selbstverständlich können die Variablen lokal geändert werden, bevor „Build“ aufgerufen wird
Nebenskript.

Bauen Skript Auswertung Auftrag

Die einzige Einschränkung bei der Reihenfolge von Build-Skripten besteht darin, dass es sich um übergeordnete Skripte handelt
vor ihren minderwertigen Skripten bewertet. Die oberste Ebene Konstruieren Datei ist zum Beispiel
werden zuerst ausgewertet, gefolgt von allen minderwertigen Skripten. Das ist alles, was Sie wirklich wissen müssen
über die Bewertungsreihenfolge, da die Reihenfolge im Allgemeinen irrelevant ist. Folgendes berücksichtigen
Befehl „Build“:

Erstellen Sie qw(
Fahrer/Display/Rekrut
Treiber/Maus/Conscript
Parser/Rekrut
Versorgungsunternehmen/Rekrut
);

Wir haben uns dafür entschieden, die Skriptnamen in alphabetischer Reihenfolge anzuordnen, einfach weil das am meisten ist
praktisch für Wartungszwecke. Eine Änderung der Reihenfolge hat keinen Einfluss auf die
bauen.

A Modell für ,,teilen" Dateien


Manche einfach Conventions

In jedem komplexen Softwaresystem muss eine Methode zum Teilen von Build-Produkten vorhanden sein
gegründet. Wir schlagen eine Reihe einfacher Konventionen vor, deren Umsetzung trivial ist
Nachteile, aber sehr effektiv.

Die Grundregel besteht darin, zu verlangen, dass alle Build-Produkte erstellt werden, die gemeinsam genutzt werden müssen
Verzeichnisse werden über ein Zwischenverzeichnis gemeinsam genutzt. Wir haben dies typischerweise genannt
exportieren, und in einer C-Umgebung herkömmliche Unterverzeichnisse dieses Verzeichnisses bereitgestellt,
sowie das, lib, Kasten, usw.

Diese Verzeichnisse werden von der obersten Ebene definiert Konstruieren Datei. Eine einfache Konstruieren Datei für
a Hallo, Welt! Eine Anwendung, die über mehrere Verzeichnisse organisiert ist, könnte so aussehen:

# Datei für Hello, World! erstellen

# Wohin mit all unseren geteilten Produkten?
$EXPORT = '#export';

Export qw( CONS INCLUDE LIB BIN );

# Standardverzeichnisse zum Teilen von Produkten.
$INCLUDE = "$EXPORT/include";
$LIB = "$EXPORT/lib";
$BIN = "$EXPORT/bin";

# Eine Standard-Bauumgebung.
$CONS = neue Nachteile (
CPPPATH => $INCLUDE, # Include-Pfad für C-Kompilierungen
LIBPATH => $LIB, # Bibliothekspfad zum Verknüpfen von Programmen
LIBS => '-lworld', # Liste der Standardbibliotheken
);

Erstellen Sie qw(
Hallo/Rekrut
Welt/Rekrut
);

Das weltweit wie ausgehandelt und gekauft ausgeführt wird. Verzeichnisse Wehrpflicht Datei sieht so aus:

# Conscript-Datei für das Verzeichnis world
Import qw( CONS INCLUDE LIB );

# Installieren Sie die Produkte dieses Verzeichnisses
Installieren Sie $CONS $LIB, 'libworld.a';
Installieren Sie $CONS $INCLUDE, 'world.h';

# Interne Produkte
Bibliothek $CONS 'libworld.a', 'world.c';

und dem HELLO Verzeichnisse Wehrpflicht Datei sieht so aus:

# Conscript-Datei für das Verzeichnis hallo
Import qw( CONS BIN );

# Exportierte Produkte
Installieren Sie $CONS $BIN, 'hello';

# Interne Produkte
Programm $CONS 'hello', 'hello.c';

Um eine zu konstruieren Hallo, Welt! Wenn Sie ein Programm mit dieser Verzeichnisstruktur aufrufen, wechseln Sie zur obersten Ebene
Verzeichnis und rufen Sie „cons“ mit den entsprechenden Argumenten auf. Im folgenden Beispiel haben wir
Weisen Sie Cons an, das Verzeichnis zu erstellen exportieren. Um ein Verzeichnis zu erstellen, erstellt Cons alle rekursiv
bekannte Produkte in diesem Verzeichnis (natürlich nur, wenn sie neu erstellt werden müssen). Wenn überhaupt
diese Produkte hängen von anderen Produkten in anderen Verzeichnissen ab, dann werden diese erstellt,
Auch.

% Nachteile Export
Installieren Sie world/world.h als export/include/world.h
cc -Iexport/include -c hello/hello.c -o hello/hello.o
cc -Iexport/include -c world/world.c -o world/world.o
ar r world/libworld.a world/world.o
ar: Welt erstellen/libworld.a
ranlib world/libworld.a
Installieren Sie world/libworld.a als export/lib/libworld.a
cc -o hallo/hello hallo/hello.o -Lexport/lib -lworld
Installieren Sie hello/hello als export/bin/hello

Sauber, verständlich, ortsunabhängig Skripte

Sie werden feststellen, dass die beiden Wehrpflicht Die Dateien sind sehr sauber und auf den Punkt gebracht. Sie einfach
Geben Sie Produkte des Verzeichnisses an und wie diese Produkte erstellt werden. Die Bauanleitung
sind minimal: Sie geben an, welche Bauumgebung verwendet werden soll, den Namen des Produkts,
und der Name der Eingänge. Beachten Sie auch, dass die Skripte ortsunabhängig sind: Wenn Sie
Wenn Sie Ihren Quellbaum neu organisieren möchten, können Sie dies tun: Sie müssen nur die ändern
Konstruieren Datei (in diesem Beispiel), um die neuen Speicherorte der anzugeben Wehrpflicht Dateien. das
Die Verwendung eines Exportbaums erleichtert dieses Ziel.

Beachten Sie auch, wie Cons sich um kleine Details für Sie kümmert. All die exportieren Verzeichnisse, z
wurden beispielsweise automatisch erstellt. Und die installierten Dateien waren wirklich fest mit dem verknüpft
entsprechenden Exportverzeichnisse, um Platz und Zeit zu sparen. Diese Liebe zum Detail spart
Dies erspart Ihnen einen erheblichen Arbeitsaufwand und macht es noch einfacher, einfache, wartbare Skripte zu erstellen.

Trennung Quelle und bauen Bäume


Es ist oft wünschenswert, alle abgeleiteten Dateien aus dem Build vollständig von dem zu trennen
Quelldaten. Dies macht es viel einfacher, den Überblick darüber zu behalten, was eine Quelldatei ist und
erleichtert auch die Handhabung Variante Builds, insbesondere wenn Sie Varianten-Builds wünschen
koexistieren.

Trennung bauen und Quelle Verzeichnisse Verwendung von Link Befehl

Cons bietet einen einfachen Mechanismus, der alle diese Anforderungen erfüllt. Der „Link“
Der Befehl wird wie in diesem Beispiel aufgerufen:

Link 'build' => 'src';

Die angegebenen Verzeichnisse sind mit dem angegebenen Quellverzeichnis „verlinkt“. Gesetzt den Fall
dass Sie ein Quellverzeichnis einrichten, src, mit den Unterverzeichnissen weltweit wie ausgehandelt und gekauft ausgeführt wird. und HELLO darunter,
wie im vorherigen Beispiel. Sie könnten dann die ursprünglichen Baulinien ersetzen
wie folgt vor:

Erstellen Sie qw(
build/world/Conscript
build/hello/Conscript
);

Beachten Sie, dass Sie das behandeln Wehrpflicht Datei, als ob sie im Build-Verzeichnis vorhanden wäre. Nun, wenn
Wenn Sie den gleichen Befehl wie zuvor eingeben, erhalten Sie folgende Ergebnisse:

% Nachteile Export
Installieren Sie build/world/world.h als export/include/world.h
cc -Iexport/include -c build/hello/hello.c -o build/hello/hello.o
cc -Iexport/include -c build/world/world.c -o build/world/world.o
ar r build/world/libworld.a build/world/world.o
ar: build/world/libworld.a erstellen
ranlib build/world/libworld.a
Installieren Sie build/world/libworld.a als export/lib/libworld.a
cc -o build/hello/hello build/hello/hello.o -Lexport/lib -lworld
Installieren Sie build/hello/hello als export/bin/hello

Auch hier hat sich Cons für Sie um die Details gekümmert. Insbesondere werden Sie das alles bemerken
Die Builds werden mithilfe von Quelldateien und Objektdateien aus dem Build-Verzeichnis erstellt. Für
Beispiel build/world/world.o ist zusammengestellt aus build/world/world.c und
export/include/world.h wird von installiert build/world/world.h. Dies ist bei den meisten der Fall
Systeme durch die einfache Möglichkeit, die erforderlichen Dateien aus jeder Quelle „hart“ zu verknüpfen
Verzeichnis in das entsprechende Build-Verzeichnis.

Die Links werden von Cons korrekt gepflegt, unabhängig davon, was Sie mit dem Quellverzeichnis tun.
Wenn Sie eine Quelldatei ändern, kann Ihr Editor dies „an Ort und Stelle“ tun oder sie umbenennen
zuerst und erstellen Sie eine neue Datei. Im letzteren Fall geht jeglicher Hardlink verloren. Nachteile werden
Erkennen Sie diesen Zustand, wenn die Quelldatei das nächste Mal benötigt wird, und verknüpfen Sie sie erneut
passend.

Das merkt man übrigens auch nicht Es waren Änderungen am Basiswert erforderlich Wehrpflicht
Dateien. Und wir können noch weiter gehen, wie wir im nächsten Abschnitt sehen werden.

Variante baut


Hallo, Welt! für Banane und Pfirsich Betriebssysteme

Varianten-Builds erfordern lediglich eine weitere einfache Erweiterung. Nehmen wir als Beispiel a
Anforderung, Builds sowohl für die Betriebssysteme baNaNa als auch peAcH zuzulassen. In diesem Fall,
Wir verwenden ein verteiltes Dateisystem wie NFS, um auf das jeweilige System zuzugreifen, und
Für jeden Aufruf von muss nur das eine oder andere System kompiliert werden
„Nachteile“. Hier ist eine Möglichkeit, wie wir das einrichten könnten Konstruieren Datei für unsere Hallo, Welt!
Anwendung:

# Datei für Hello, World! erstellen

die qq(OS muss angegeben werden), es sei denn $OS = $ARG{OS};
die qq(OS muss „peach“ oder „banana“ sein)
if $OS ne "Pfirsich" && $OS ne "Banane";

# Wohin mit all unseren geteilten Produkten?
$EXPORT = "#export/$OS";

Export qw( CONS INCLUDE LIB BIN );

# Standardverzeichnisse zum Teilen von Produkten.
$INCLUDE = "$EXPORT/include";
$LIB = "$EXPORT/lib";
$BIN = "$EXPORT/bin";

# Eine Standard-Bauumgebung.
$CONS = neue Nachteile (
CPPPATH => $INCLUDE, # Include-Pfad für C-Kompilierungen
LIBPATH => $LIB, # Bibliothekspfad zum Verknüpfen von Programmen
LIBS => '-lworld', # Liste der Standardbibliotheken
);

# Von $BUILD werden wir alles ableiten.
$BUILD = "#build/$OS";

# Cons mitteilen, wo sich die Quelldateien für $BUILD befinden.
Link $BUILD => 'src';

Bauen (
„$BUILD/hello/Conscript“,
„$BUILD/world/Conscript“,
);

Wenn wir uns nun bei einem peAcH-System anmelden, können wir unser erstellen Hallo, Welt! Antrag dafür
Plattform:

% cons export OS=peach
Installieren Sie build/peach/world/world.h als 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 r build/peach/world/libworld.a build/peach/world/world.o
ar: build/peach/world/libworld.a erstellen
ranlib build/peach/world/libworld.a
Installieren Sie build/peach/world/libworld.a als export/peach/lib/libworld.a
cc -o build/peach/hello/hello build/peach/hello/hello.o -Lexport/peach/lib -lworld
Installieren Sie build/peach/hello/hello als export/peach/bin/hello

Variationen on a Thema

Weitere Variationen dieses Modells sind möglich. Beispielsweise könnten Sie entscheiden, dass Sie möchten
um Ihre Include-Dateien in plattformabhängige und plattformunabhängige Dateien zu unterteilen.
In diesem Fall müssten Sie eine Alternative zu „$INCLUDE“ für plattformabhängig definieren
Dateien. Am meisten Wehrpflicht Dateien, die rein plattformunabhängige Include-Dateien erzeugen, würden
nicht ändern müssen.

Möglicherweise möchten Sie auch in der Lage sein, Ihr gesamtes System mit Debugging oder Profiling zu kompilieren.
zum Beispiel aktiviert. Sie können dies mit entsprechenden Befehlszeilenoptionen tun, z
„DEBUG=on“. Dies würde dann in die entsprechende plattformspezifische Übersetzung übersetzt
Anforderungen zum Aktivieren des Debuggens (dazu kann z. B. das Ausschalten der Optimierung gehören).
Beispiel). Sie können optional den Namensraum für diese verschiedenen Systemtypen variieren.
Aber wie wir im nächsten Abschnitt sehen werden, ist das nicht der Fall essential um dies zu tun, da Cons hübsch ist
klug darin, Dinge neu aufzubauen, wenn Sie Optionen ändern.

Unterschriften


MD5 kryptographisch Unterschriften

Immer wenn Cons eine abgeleitete Datei erstellt, speichert es eine Stempel, Unterschrift für diese Datei. Die Unterschrift
wird in einer separaten Datei gespeichert, eine pro Verzeichnis. Nachdem das vorherige Beispiel kompiliert wurde,
.versenden Datei in das bauen/pfirsich/welt Verzeichnis sah so aus:

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

Die erste Zahl ist ein Zeitstempel – bei UNIX-Systemen ist dies normalerweise die Anzahl von
Sekunden seit dem 1. Januar 1970. Der zweite Wert ist eine MD5-Prüfsumme. Der Nachricht Digest
Algorithmus ist ein Algorithmus, der bei gegebener Eingabezeichenfolge eine starke Kryptografie berechnet
Signatur für diese Zeichenfolge. Die MD5-Prüfsumme ist im gespeichert .versenden Die Datei ist im Grunde eine
Zusammenfassung aller Abhängigkeitsinformationen für die angegebene Datei. So zum Beispiel für die
Welt.o Datei, dazu gehört mindestens die Welt.c Datei und auch alle Header-Dateien, die Cons
weiß davon, dass direkt oder indirekt einbezogen werden Welt.c. Nicht nur das, sondern auch die
tatsächliche Befehlszeile, die zum Generieren verwendet wurde Welt.o fließt ebenfalls in die Berechnung ein
die Unterschrift. Ähnlich, libworld.a erhält eine Signatur, die alles „einschließt“.
Signaturen seiner Bestandteile (und daher, transitiv, die Signaturen von ihr
Bestandteile) sowie die Befehlszeile, mit der die Datei erstellt wurde.

Die Signatur einer nicht abgeleiteten Datei wird standardmäßig anhand der aktuellen Datei berechnet
Änderungszeit der Datei und der Eintragsname der Datei (es sei denn, es gibt einen
Strom .versenden Eintrag für diese Datei, in diesem Fall wird diese Signatur verwendet).

Beachten Sie, dass eine abgeleitete Datei nicht von einer bestimmten Datei abhängig sein muss Konstruieren or
Wehrpflicht Datei – wenn sich Änderungen an diesen Dateien auf die betreffende Datei auswirken, dann ist dies der Fall
automatisch in seiner Signatur widergespiegelt, da relevante Teile der Befehlszeile vorhanden sind
in die Signatur aufgenommen. Unabhängige Änderungen haben keine Auswirkungen.

Wenn Cons überlegt, ob eine bestimmte Datei abgeleitet werden soll, berechnet es zunächst die
erwartete Signatur der Datei. Anschließend wird der Zeitpunkt der letzten Änderung der Datei mit verglichen
die in der aufgezeichnete Zeit .versenden Eintrag, falls vorhanden. Wenn diese Zeiten übereinstimmen, dann wird die
Signatur im gespeichert .versenden Die Datei gilt als korrekt. Wenn die Datei älter ist
Wenn die Signatur nicht mit der neuen, erwarteten Signatur übereinstimmt, muss die Datei erneut abgeleitet werden.

Beachten Sie, dass eine Datei immer dann neu abgeleitet wird, wenn sich etwas an einer abhängigen Datei ändert. In
Beachten Sie das insbesondere jedem Änderung der Änderungszeit eines abhängigen (Vorwärts- oder
zeitlich rückwärts) erzwingt eine Neukompilierung der abgeleiteten Datei.

Die Verwendung dieser Signaturen ist eine äußerst einfache, effiziente und effektive Methode
die Reproduzierbarkeit eines Systems drastisch verbessert.

Wir demonstrieren dies anhand eines einfachen Beispiels:

# Einfaches „Hallo Welt!“ Datei erstellen
$CFLAGS = '-g' if $ARG{DEBUG} eq 'on';
$CONS = neue Nachteile(CFLAGS => $CFLAGS);
Programm $CONS 'hello', 'hello.c';

Beachten Sie, wie Cons zu den entsprechenden Zeitpunkten neu kompiliert wird:

% Nachteile Hallo
cc -c hallo.c -o hallo.o
cc -o hallo hallo.o
% Nachteile Hallo
Nachteile: „Hallo“ ist aktuell.
% cons DEBUG=on Hallo
cc -g -c hallo.c -o hallo.o
cc -o hallo hallo.o
% cons DEBUG=on Hallo
Nachteile: „Hallo“ ist aktuell.
% Nachteile Hallo
cc -c hallo.c -o hallo.o
cc -o hallo hallo.o

Code Aufbewahrungsorte


Viele Softwareentwicklungsorganisationen verfügen über ein oder mehrere zentrale Repository-Verzeichnisse
Bäume, die den aktuellen Quellcode für ein oder mehrere Projekte sowie den abgeleiteten enthalten
Objektdateien, Bibliotheken und ausführbare Dateien. Um unnötige Neukompilierungen zu reduzieren,
Es ist nützlich, Dateien aus dem Repository zu verwenden, um Entwicklungssoftware zu erstellen – vorausgesetzt, von
Natürlich ist im lokalen Build-Baum keine neuere Abhängigkeitsdatei vorhanden.

Dokumente

Cons bietet einen Mechanismus zum Angeben einer Liste von Code-Repositorys, die durchsucht werden.
in der richtigen Reihenfolge für Quelldateien und abgeleitete Dateien, die nicht im lokalen Build-Verzeichnisbaum gefunden werden.

Die folgenden Zeilen in a Konstruieren Die Datei weist Cons an, zuerst unter der zu suchen
/usr/experiment/repository Verzeichnis und dann unter /usr/product/repository Verzeichnis:

Repository qw (
/usr/experiment/repository
/usr/product/repository
);

Die angegebenen Repository-Verzeichnisse können Quelldateien, abgeleitete Dateien (Objekte,
Bibliotheken und ausführbare Dateien) oder beides. Wenn keine lokale Datei (Quelle oder abgeleitet) vorhanden ist
das Verzeichnis, in dem Cons ausgeführt wird, dann wird die erste Kopie einer gleichnamigen Datei gefunden
unter einem Repository-Verzeichnis wird zum Erstellen aller lokal abgeleiteten Dateien verwendet.

Cons verwaltet eine globale Liste von Repository-Verzeichnissen. Nachteile werden das beseitigen
aktuelles Verzeichnis und alle nicht vorhandenen Verzeichnisse aus der Liste.

Erkenntnis Konstruieren Datei in a Dokumente

Nachteile werden auch gesucht Konstruieren und Wehrpflicht Dateien im Repository-Baum oder in den Repository-Bäumen.
Dies führt jedoch zu einer Henne-Ei-Situation: Wie sieht ein Repository-Baum aus?
für eine Konstruieren Datei, wenn die Konstruieren Datei sagt Ihnen, wo sich das Repository befindet? Zu bekommen
Aus diesem Grund können Repositorys über „-R“-Optionen in der Befehlszeile angegeben werden:

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

Alle in der angegebenen Repository-Verzeichnisse Konstruieren or Wehrpflicht Dateien werden angehängt
in die Repository-Verzeichnisse, die durch die Befehlszeilenoptionen „-R“ angegeben werden.

Dokumente Quelle Dateien

Wenn der Quellcode (einschließlich der Wehrpflicht Datei) für die Bibliotheksversion von Hallo,
Welt! Die C-Anwendung befindet sich in einem Repository (ohne abgeleitete Dateien), Cons verwendet die
Repository-Quelldateien, um die lokalen Objektdateien und die ausführbare Datei zu erstellen:

% cons -R /usr/src_only/repository Hallo
gcc -c /usr/src_only/repository/hello.c -o hello.o
gcc -c /usr/src_only/repository/world.c -o world.o
ar r libworld.a world.o
ar: libworld.a erstellen
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

Das Erstellen einer lokalen Quelldatei führt dazu, dass Cons die entsprechende abgeleitete Datei neu erstellt oder
Dateien:

% pico world.c
[BEARBEITEN]
% cons -R /usr/src_only/repository Hallo
gcc -c welt.c -o welt.o
ar r libworld.a world.o
ar: libworld.a erstellen
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

Und das Entfernen der lokalen Quelldatei führt dazu, dass Cons wieder die abgeleitete Datei erstellt
Dateien aus der Repository-Quelle:

% rm world.c
% cons -R /usr/src_only/repository Hallo
gcc -c /usr/src_only/repository/world.c -o world.o
ar r libworld.a world.o
ar: libworld.a erstellen
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

Dokumente abgeleitet Dateien

Wenn ein Repository-Baum abgeleitete Dateien enthält (normalerweise Objektdateien, Bibliotheken usw.)
ausführbaren Dateien), führt Cons seine normale Signaturberechnung durch, um zu entscheiden, ob die
Die Repository-Datei ist aktuell oder eine abgeleitete Datei muss lokal erstellt werden. Das bedeutet, dass,
Um eine korrekte Signaturberechnung sicherzustellen, muss ein Repository-Baum auch Folgendes enthalten
.versenden Dateien, die von Cons beim Generieren der abgeleiteten Dateien erstellt wurden.

Dies würde normalerweise dadurch erreicht, dass die Software im Repository erstellt wird (oder
alternativ in einem Build-Verzeichnis und anschließendes Kopieren des Ergebnisses in das Repository):

% cd /usr/all/repository
% Nachteile Hallo
gcc -c hallo.c -o hallo.o
gcc -c welt.c -o welt.o
ar r libworld.a world.o
ar: libworld.a erstellen
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

(Dies ist sicher, auch wenn die Konstruieren Datei listet die auf /usr/all/repository Verzeichnis in einem
„Repository“-Befehl, da Cons das aktuelle Verzeichnis aus dem Repository entfernt
Liste.)

Wenn wir nun eine Kopie der Anwendung mit unserer eigenen erstellen möchten Hallo c Datei, wir brauchen nur
um die eine erforderliche Quelldatei zu erstellen, und verwenden Sie die Option „-R“, damit Cons andere verwenden kann
Dateien aus dem Repository:

% mkdir $HOME/build1
% cd $HOME/build1
% ed hallo.c
[BEARBEITEN]
% cons -R /usr/all/repository Hallo
gcc -c hallo.c -o hallo.o
gcc -o hallo hallo.o /usr/all/repository/libworld.a

Beachten Sie, dass Cons sich nicht die Mühe gemacht hat, eine lokale Datei neu zu erstellen libworld.a Bibliothek (oder kompilieren Sie die
Welt.o Modul), sondern verwendet stattdessen die bereits kompilierte Version aus dem Repository.

Denn die MD5-Signaturen, die Cons einfügt .versenden Datei enthält Zeitstempel für die
Bei abgeleiteten Dateien müssen die Signaturzeitstempel mit den Dateizeitstempeln für eine Signatur übereinstimmen
als gültig angesehen werden.

Einige Softwaresysteme ändern möglicherweise die Zeitstempel in Repository-Dateien (indem sie sie kopieren,
Beispiel: In diesem Fall geht Cons standardmäßig davon aus, dass die Repository-Signaturen ungültig sind
und Dateien unnötigerweise neu erstellen. Dieses Verhalten kann geändert werden, indem Folgendes angegeben wird:

Repository_Sig_Times_OK 0;

Dadurch wird Cons angewiesen, Zeitstempel zu ignorieren, wenn entschieden wird, ob eine Signatur gültig ist. (Notiz
Das Vermeiden dieser Plausibilitätsprüfung bedeutet, dass eine ordnungsgemäße Kontrolle über das Repository vorhanden sein muss
Baum, um sicherzustellen, dass die abgeleiteten Dateien nicht geändert werden können, ohne die zu aktualisieren .versenden
Unterschrift.)

Lokale Kopien of Dateien

Wenn der Repository-Baum die vollständigen Ergebnisse eines Builds enthält und wir versuchen, daraus zu erstellen
das Repository ohne Dateien in unserem lokalen Baum, was einigermaßen überraschend ist
das passiert:

% mkdir $HOME/build2
% cd $HOME/build2
% cons -R /usr/all/repository Hallo
Nachteile: „Hallo“ ist aktuell.

Warum sagt Cons, dass die HELLO Das Programm ist aktuell, wenn es keines gibt HELLO Programm ein
das lokale Build-Verzeichnis? Weil das Repository (nicht das lokale Verzeichnis) die enthält
auf dem neusten Stand HELLO Programm, und Cons stellt korrekt fest, dass nichts unternommen werden muss
Erstellen Sie diese aktuelle Kopie der Datei neu.

Es gibt jedoch viele Fälle, in denen es angebracht ist, sicherzustellen, dass eine lokale Kopie von a
Datei existiert immer. Ein Verpackungs- oder Testskript kann beispielsweise davon ausgehen, dass dies sicher ist
Die generierten Dateien sind lokal vorhanden. Anstatt diese Nebenskripte darauf aufmerksam zu machen
Im Repository-Verzeichnis kann der Befehl „Lokal“ zu einem hinzugefügt werden Konstruieren or Wehrpflicht Datei auf
Geben Sie an, dass eine oder mehrere bestimmte Dateien im lokalen Build-Verzeichnis erscheinen müssen:

Lokales qw(
HELLO
);

Wenn wir dann denselben Befehl erneut ausführen, erstellt Cons eine lokale Kopie des Programms aus dem
Repository-Kopie (mit der Meldung, dass dies geschieht):

% cons -R /usr/all/repository Hallo
Lokale Kopie von hello aus /usr/all/repository/hello
Nachteile: „Hallo“ ist aktuell.

Beachten Sie, dass das Erstellen der lokalen Kopie nicht als „Build“ der Datei betrachtet wird
HELLO Datei, Cons meldet immer noch, dass sie aktuell ist.

Das Erstellen lokaler Kopien ist am nützlichsten für Dateien, die in einem installiert werden
Zwischenverzeichnis (zum Teilen mit anderen Verzeichnissen) über den Befehl „Installieren“.
Dies ist so, wenn man den „Install“-Befehl für eine Datei mit einem begleitenden „Local“-Befehl begleitet
Es ist üblich, dass Cons einen „Install_Local“-Befehl als praktische Möglichkeit für beides bereitstellt:

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

ist genau gleichbedeutend mit:

Installieren Sie $env '#export', 'hello';
Lokal '#export/hello';

Sowohl die Befehle „Local“ als auch „Install_Local“ aktualisieren die lokale Datei .versenden Datei mit der
entsprechende Dateisignaturen, damit zukünftige Builds korrekt ausgeführt werden.

Dokumente Abhängigkeit Analyse

Aufgrund der integrierten Scanfunktion durchsucht Cons die angegebenen Repository-Bäume nach Einschlüssen
.h Dateien. Sofern der Compiler jedoch nicht auch über die Repository-Bäume Bescheid weiß, ist dies der Fall
nicht finden können .h Dateien, die nur in einem Repository vorhanden sind. Wenn zum Beispiel die Hallo c
Die Datei enthält die Hallo h Datei in ihrem aktuellen Verzeichnis:

% cons -R /usr/all/repository Hallo
gcc -c /usr/all/repository/hello.c -o hello.o
/usr/all/repository/hello.c:1: hello.h: Keine solche Datei oder kein solches Verzeichnis

Die Lösung dieses Problems stellt bestimmte Anforderungen an die Bauumgebung
definiert und auf die Art und Weise, wie die C-Präprozessoranweisung „#include“ zum Einbinden von Dateien verwendet wird.

Um den Compiler über die Repository-Bäume zu informieren, fügt Cons das entsprechende „-I“ hinzu.
Flags für die Kompilierungsbefehle. Dies bedeutet, dass die Variable „CPPPATH“ in der
Die Konstruktumgebung muss explizit alle Unterverzeichnisse angeben, die durchsucht werden sollen
für enthaltene Dateien, einschließlich des aktuellen Verzeichnisses. Folglich können wir das oben Gesagte beheben
Beispiel durch Ändern der Umgebungserstellung in der Konstruieren Datei wie folgt:

$env = neue Nachteile(
CC => 'gcc',
CPPPATH => '.',
LIBS => 'libworld.a',
);

Aufgrund der Definition der Variablen „CPPPATH“ ergibt sich dies, wenn wir die erneut ausführen
Befehl:

% cons -R /usr/all/repository Hallo
gcc -c -I. -I/usr/all/repository /usr/all/repository/hello.c -o hello.o
gcc -o hallo hallo.o /usr/all/repository/libworld.a

Die Reihenfolge der „-I“-Flags repliziert für den C-Präprozessor dasselbe Repository-
Verzeichnissuchpfad, den Cons für seine eigene Abhängigkeitsanalyse verwendet. Wenn es gibt
Mehrere Repositorys und mehrere „CPPPATH“-Verzeichnisse, Cons wird das Repository anhängen
Verzeichnisse an den Anfang jedes „CPPPATH“-Verzeichnisses setzen und die Zahl schnell vervielfachen
von „-I“-Flaggen. Als extremes Beispiel a Konstruieren Datei mit:

Repository qw(
/u1
/u2
);

$env = neue Nachteile(
CPPPATH => 'a:b:c',
);

Würde einen Kompilierungsbefehl ergeben von:

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

Denn Cons verlässt sich auf die „-I“-Flags des Compilers, um die Reihenfolge zu kommunizieren
Repository-Verzeichnisse müssen durchsucht werden, Cons‘ Umgang mit Repository-Verzeichnissen hingegen schon
Grundsätzlich inkompatibel mit der Verwendung von doppelten Anführungszeichen für die „#include“-Direktiven in Ihrem C
Quellcode:

#include "file.h" /* VERWENDEN SIE KEINE DOPPELTEN ANführungszeichen WIE DIESES */

Dies liegt daran, dass die meisten C-Präprozessoren, wenn sie mit einer solchen Anweisung konfrontiert werden, immer zuerst vorgehen
Durchsuchen Sie das Verzeichnis, das die Quelldatei enthält. Dies untergräbt das ausgefeilte „-Ich“
Optionen, die Cons erstellt, um den Präprozessor an seine bevorzugte Suche anzupassen
Pfad.

Wenn Sie also Repository-Bäume in Cons verwenden, immer Verwenden Sie für den Lieferumfang spitze Klammern
Dateien:

#enthalten /* STATT SPITZE KLAMMER VERWENDEN */

Repository_List

Cons bietet einen „Repository_List“-Befehl, um eine Liste aller Repository-Verzeichnisse zurückzugeben
in ihrer aktuellen Suchreihenfolge. Dies kann zum Debuggen oder zur Ausführung komplexerer Perl-Programme verwendet werden
Zeug:

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

Dokumente Interaktion mit Sonstiges Nachteile Funktionen

Die Handhabung von Repository-Bäumen durch Cons interagiert korrekt mit anderen Cons-Funktionen – und zwar
Das heißt, es macht im Allgemeinen das, was Sie erwarten würden.

Vor allem interagieren Repository-Bäume korrekt und recht wirkungsvoll mit dem „Link“.
Befehl. Ein Repository-Baum kann ein oder mehrere Unterverzeichnisse für Versionsbuilds enthalten
über „Link“ zu einem Quellunterverzeichnis erstellt. Cons sucht nach abgeleiteten Dateien in
die entsprechenden Build-Unterverzeichnisse im Repository-Baum.

Standard Ziele


Bisher haben wir den Aufruf von Cons mit einem expliziten Ziel zum Erstellen demonstriert:

% Nachteile Hallo

Normalerweise erstellt Cons nichts, es sei denn, ein Ziel wird angegeben, aber die Angabe von „.“
(das aktuelle Verzeichnis) wird alles erstellen:

% cons # baut nichts auf

% Nachteile . # erstellt alles im Verzeichnis der obersten Ebene

Hinzufügen der Methode „Default“ zu allen Konstruieren or Wehrpflicht Datei fügt das angegebene hinzu
Ziele zu einer Liste von Standardzielen hinzufügen. Nachteile werden diese Standardeinstellungen erstellen, wenn keine vorhanden sind
in der Befehlszeile angegebene Ziele. Fügen Sie also die folgende Zeile zur obersten Ebene hinzu
Konstruieren Die Datei ahmt das typische Verhalten von Make nach, bei dem standardmäßig alles erstellt wird:

Standard '.';

Das Folgende würde das hinzufügen HELLO und Auf Wiedersehen Befehle (im selben Verzeichnis wie die
Konstruieren or Wehrpflicht Datei) zur Standardliste hinzufügen:

Standard-qw(
HELLO
Auf Wiedersehen
);

Die Methode „Default“ kann mehr als einmal verwendet werden, um Ziele zur Standardliste hinzuzufügen.

Selektiv baut


Cons bietet zwei Methoden zum Reduzieren der Größe eines bestimmten Builds. Die erste Möglichkeit besteht in der Spezifizierung
Ziele auf der Befehlszeile, und die zweite ist eine Methode zum Bereinigen des Build-Baums. Also
Berücksichtigen Sie zunächst die Zielspezifikation.

Selektiv Targeting

Wie make ermöglicht Cons die Angabe von „Zielen“ auf der Befehlszeile. Kontraziele
Dabei kann es sich entweder um Dateien oder Verzeichnisse handeln. Bei der Angabe eines Verzeichnisses handelt es sich lediglich um eine kurze
Handnotation für jedes abgeleitete Produkt – das Cons kennt – in der angegebenen
Verzeichnis und darunter. Zum Beispiel:

% Nachteile build/hello/hello.o

bedeutet bauen hallo.o und alles was das ist hallo.o Könnte gebrauchen. Dies ist von einem früheren
Version des Hallo, Welt! Programm, in dem hallo.o hing davon ab
export/include/world.h. Wenn diese Datei nicht aktuell ist (weil jemand sie geändert hat
src/world/world.h), dann wird es neu erstellt, auch wenn es sich in einem entfernten Verzeichnis befindet
bauen/Hallo.

In diesem Beispiel:

% Nachteile bauen

Alles in der bauen Bei Bedarf wird ein Verzeichnis erstellt. Auch dies kann zu weiteren Dateien führen
soll gebaut werden. Insbesondere beides export/include/world.h und export/lib/libworld.a sind
erforderlich von der bauen/Hallo Verzeichnis und werden daher erstellt, wenn sie veraltet sind.

Wenn wir das tun, dann:

% Nachteile Export

dann werden nur die Dateien neu erstellt, die im Exportverzeichnis installiert werden sollen, wenn
erforderlich, und dann dort installiert. Beachten Sie, dass „cons build“ möglicherweise Dateien erstellt, die „cons
export' wird nicht erstellt und umgekehrt.

Nein „besonders“ Ziele

Bei Cons sind keine „speziellen“ Ziele im Make-Stil erforderlich. Das einfachste Analogon mit Cons
ist es, etwas Besonderes zu verwenden exportieren stattdessen Verzeichnisse. Nehmen wir zum Beispiel an, Sie haben eine
Eine ganze Reihe von Unit-Tests, die Ihrem Code zugeordnet sind. Die Tests live im
Quellverzeichnis in der Nähe des Codes. Normalerweise möchten Sie diese Tests jedoch nicht erstellen.
Eine Lösung besteht darin, alle Build-Anweisungen zum Erstellen der Tests bereitzustellen und diese dann auszuführen
Installieren Sie die Tests in einem separaten Teil des Baums. Wenn wir die Tests auf einer obersten Ebene installieren
Verzeichnis aufgerufen Tests, Dann gilt:

% Nachteile Tests

wird alle Tests erstellen.

% Nachteile Export

wird die Produktionsversion des Systems erstellen (aber nicht die Tests) und:

% Nachteile bauen

sollte wahrscheinlich vermieden werden (da dadurch Tests unnötig kompiliert werden).

Wenn Sie nur einen einzelnen Test erstellen möchten, können Sie den Test explizit benennen (in
entweder Tests Verzeichnis oder die bauen Verzeichnis). Sie können die Tests auch aggregieren
in eine praktische Hierarchie innerhalb des Testverzeichnisses eingefügt. Diese Hierarchie muss nicht
zwangsläufig mit der Quellhierarchie übereinstimmen, und zwar auf die gleiche Weise wie die Include-Hierarchie
stimmt wahrscheinlich nicht mit der Quellhierarchie überein (die Include-Hierarchie wird wahrscheinlich nicht mehr sein).
mehr als zwei Ebenen tief, für C-Programme).

Wenn Sie absolut alles im Baum erstellen möchten (vorbehaltlich Ihrer Optionen).
auswählen), können Sie Folgendes verwenden:

% Nachteile .

Dies ist nicht besonders effizient, da alle Bäume redundant durchlaufen werden.
einschließlich des Quellbaums. Der Quellbaum kann natürlich baubare Objekte enthalten
es – nichts hindert Sie daran, dies zu tun, selbst wenn Sie normalerweise in einem separaten Build bauen
Baum.

Bauen Beschneidung


Im Zusammenhang mit der Zielauswahl bauen Beschneidung kann verwendet werden, um den Umfang der zu reduzieren
bauen. Im vorherigen Beispiel von peAcH und baNaNa haben wir bereits gesehen, wie skriptgesteuert funktioniert
Build Pruning kann verwendet werden, um für einen bestimmten Build nur die Hälfte des potenziellen Builds verfügbar zu machen
Aufruf von „cons“. Cons bietet der Einfachheit halber auch eine Befehlszeilenkonvention
Hier können Sie angeben, welche Wehrpflicht Dateien werden tatsächlich „erstellt“, das heißt, integriert
in den Build-Baum. Zum Beispiel:

% Nachteile bauen +Welt

Das Argument „+“ führt einen regulären Perl-Ausdruck ein. Dies muss natürlich unter zitiert werden
die Shell-Ebene, wenn der Ausdruck Shell-Metazeichen enthält. Der
Ausdruck wird mit jedem abgeglichen Wehrpflicht Datei, die in einem „Build“ erwähnt wurde
Anweisung, und nur die Skripte mit übereinstimmenden Namen werden tatsächlich in die Anweisung integriert
Baum bauen. Es sind mehrere solcher Argumente zulässig. In diesem Fall erfolgt eine Übereinstimmung mit jedem dieser Argumente
reicht aus, um die Einbindung eines Skripts zu veranlassen.

Im obigen Beispiel ist das HELLO Das Programm wird nicht erstellt, da es keine Nachteile gibt
Kenntnis des Drehbuchs Hallo/Rekrutdem „Vermischten Geschmack“. Seine libworld.a Das Archiv wird jedoch erstellt, wenn
muss sein.

Es gibt mehrere Einsatzmöglichkeiten für die Build-Bereinigung über die Befehlszeile. Vielleicht das Nützlichste
ist die Fähigkeit, lokale Änderungen vorzunehmen, und zwar mit ausreichender Kenntnis der
Beschränken Sie die Größe des Build-Baums, um die Folgen dieser Änderungen zu beschleunigen
die Umbauzeit. Eine zweite Verwendungsmöglichkeit für Build Pruning besteht darin, die Neukompilierung aktiv zu verhindern
bestimmter Dateien, von denen Sie wissen, dass sie beispielsweise aufgrund einer geänderten Header-Datei neu kompiliert werden.
Möglicherweise wissen Sie, dass entweder die Änderungen an der Header-Datei unerheblich sind oder dass die
Zu Testzwecken können Änderungen für den größten Teil des Baums ignoriert werden. Mit Cons kann das
Die Ansicht ist, dass es pragmatisch ist, diese Art von Verhalten zuzugeben, mit dem Verständnis, dass
Beim nächsten vollständigen Build wird alles vorhanden sein, was neu erstellt werden muss. Es gibt kein Äquivalent
auf einen „make touch“-Befehl, um Dateien als dauerhaft aktuell zu markieren. Also kein Risiko
Der durch Build Pruning entstehende Aufwand wird gemindert. Für Arbeit in Release-Qualität empfehlen wir natürlich
dass Sie kein Build-Pruning verwenden (es ist jedoch völlig in Ordnung, es während der Integration zu verwenden).
zum Überprüfen der Kompilierung usw. Stellen Sie einfach sicher, dass Sie vor dem Festschreiben einen uneingeschränkten Build durchführen
die Integration).

Befristet Überschreibungen


Cons bietet einen sehr einfachen Mechanismus zum Überschreiben von Aspekten eines Builds. Das Wesentliche ist
dass Sie eine Override-Datei schreiben, die einen oder mehrere „Override“-Befehle enthält, und Sie
Geben Sie dies in der Befehlszeile an, wenn Sie „cons“ ausführen:

% cons -o über den Export

werde die bauen exportieren Verzeichnis, wobei alle abgeleiteten Dateien den vorhandenen Überschreibungen unterliegen
der übrig Datei. Wenn Sie die Option „-o“ weglassen, müssen Sie alles entfernen, was erforderlich ist
Alle Überschreibungen werden neu erstellt.

Überschreiben Umwelt Variablen

Die Override-Datei kann zwei Arten von Overrides enthalten. Die erste ist die eingehende Umgebung
Variablen. Diese sind normalerweise über die zugänglich Konstruieren Datei aus dem „%ENV“-Hash
Variable. Diese können in der Override-Datei einfach überschrieben werden, indem die festgelegt werden
entsprechende Elemente von „%ENV“ (diese könnten auch in der Benutzerumgebung überschrieben werden,
Na sicher).

Das Überschreiben Befehl

Die zweite Art der Überschreibung wird mit dem Befehl „Override“ erreicht, der wie folgt aussieht:
Dies:

Überschreiben , => , => , ...;

Der reguläre Ausdruck regexp wird mit jeder abgeleiteten Datei abgeglichen, die ein Kandidat ist
für den Bau. Wenn die abgeleitete Datei übereinstimmt, werden die Variablen/Wert-Paare verwendet
Überschreiben Sie die Werte in der Konstruktionsumgebung, die der abgeleiteten Datei zugeordnet ist.

Nehmen wir an, dass wir eine Bauumgebung wie diese haben:

$CONS = neue Nachteile(
COPT => '',
CDBG => '-g',
CFLAGS => '%COPT %CDBG',
);

Dann, wenn wir eine Override-Datei haben übrig enthält diesen Befehl:

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

dann jeder „cons“-Aufruf mit „-o over“, der erstellt .o Dateien über diese Umgebung werden
bewirken, dass sie mit „-O“ und ohne „-g“ kompiliert werden. Die Überschreibung könnte natürlich sein
durch die entsprechende Auswahl eines regulären Ausdrucks auf ein einzelnes Verzeichnis beschränkt werden.

Hier ist die Originalversion von Hello, World! Programm, das mit dieser Umgebung erstellt wurde.
Beachten Sie, dass Cons die entsprechenden Teile neu erstellt, wenn die Überschreibung angewendet oder entfernt wird:

% Nachteile Hallo
cc -g -c hallo.c -o hallo.o
cc -o hallo hallo.o
% cons -o über hallo
cc -O -c hallo.c -o hallo.o
cc -o hallo hallo.o
% cons -o über hallo
Nachteile: „Hallo“ ist aktuell.
% Nachteile Hallo
cc -g -c hallo.c -o hallo.o
cc -o hallo hallo.o

Es ist wichtig, dass der Befehl „Override“ nur vorübergehend und spontan verwendet wird
Für die Entwicklung erforderliche Überschreibungen, da die Überschreibungen nicht plattformunabhängig sind und
weil sie sich zu sehr auf die genaue Kenntnis der Funktionsweise der Drehbücher verlassen. Für
Für eine vorübergehende Nutzung sind sie jedoch genau das, was Sie wollen.

Beachten Sie, dass es immer noch nützlich ist, beispielsweise die Möglichkeit bereitzustellen, eine vollständig optimierte Version zu erstellen
Version eines Systems für den Produktionseinsatz – von der Konstruieren und Wehrpflicht Dateien. Hier entlang
Sie können das optimierte System an die Plattform anpassen. Wo Optimierungskompromisse stattfinden müssen
erstellt (bestimmte Dateien werden beispielsweise möglicherweise nicht mit vollständiger Optimierung kompiliert).
Diese können für die Nachwelt (und Reproduzierbarkeit) direkt in den Skripten festgehalten werden.

Mehr on Baugewerbe Umgebungen


Standard Baugewerbe Variablen

Wir haben das Konzept von a erwähnt und verwendet Baugewerbe Umwelt, viele Male in der
vorhergehenden Seiten. Jetzt ist es an der Zeit, dies etwas konkreter zu machen. Mit den folgenden
Aussage:

$env = neue Nachteile();

Es wird ein Verweis auf eine neue Standardkonstruktionsumgebung erstellt. Darin ist eine Zahl enthalten
von Konstruktionsvariablen und einigen Methoden. Zum jetzigen Zeitpunkt ist die Standardliste von
Konstruktionsvariablen sind wie folgt definiert:

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

Auf Win32-Systemen (Windows NT) werden die folgenden Konstruktionsvariablen im überschrieben
Standard:

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

Diese Variablen werden von den verschiedenen mit der Umgebung verbundenen Methoden verwendet
Insbesondere ersetzt jede Methode, die letztendlich einen externen Befehl aufruft, diese
Variablen gegebenenfalls in den letzten Befehl einfügen. Beispielsweise dauert die Methode „Objekte“.
eine Reihe von Quelldateien und veranlasst bei Bedarf die Ableitung des entsprechenden Objekts
Dateien. Zum Beispiel:

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

Dieser wird bei Bedarf die Erstellung veranlassen foo.o und bar.o. Der aufgerufene Befehl ist einfach
„%CCCOM“, das durch Ersetzung auf den entsprechenden erforderlichen externen Befehl erweitert wird
um jedes Objekt zu bauen. Wir werden die Substitutionsregeln unter „Befehl“ weiter untersuchen.
Methode unten.

Die Konstruktionsvariablen werden auch für andere Zwecke verwendet. Beispielsweise lautet „CPPPATH“.
Wird verwendet, um einen durch Doppelpunkte getrennten Pfad von Include-Verzeichnissen anzugeben. Das sollen diese sein
werden an den C-Präprozessor übergeben und auch von der C-Datei-Scanmaschinerie verwendet
Bestimmen Sie die Abhängigkeiten, die an einer C-Kompilierung beteiligt sind. Variablen beginnend mit
Unterstrich, werden mit verschiedenen Methoden erstellt und sollten normalerweise als „intern“ betrachtet werden.
Variablen. Zum Beispiel, wenn eine Methode aufgerufen wird, die die Erstellung eines Objekts erfordert
Aus einer C-Quelle wird die Variable „_IFLAGS“ erstellt: Dies entspricht den Schaltern „-I“.
Wird vom C-Compiler benötigt, um die durch „CPPPATH“ angegebenen Verzeichnisse darzustellen.

Beachten Sie, dass der Wert einer Variablen für jede bestimmte Umgebung einmal und dann festgelegt wird
niemals zurücksetzen (um eine Variable zu ändern, müssen Sie eine neue Umgebung erstellen. Methoden werden bereitgestellt
zum Kopieren vorhandener Umgebungen zu diesem Zweck). Einige interne Variablen, wie z
„_IFLAGS“ werden bei Bedarf erstellt, aber sobald sie festgelegt sind, bleiben sie für die gesamte Lebensdauer des festgelegt
Umwelt.

Die Variablen „CFLAGS“, „LDFLAGS“ und „ARFLAGS“ bieten alle einen Ort für die Übergabe von Optionen
der Compiler, Loader und Archiver. Weniger offensichtlich ist das „INCDIRPREFIX“
Die Variable gibt die Optionszeichenfolge an, die am Anfang jedes Include angehängt werden soll
Verzeichnis, damit der Compiler weiß, wo es zu finden ist .h Dateien. Ebenso die
Die Variable „LIBDIRPREFIX“ gibt die Optionszeichenfolge an, die am Anfang angehängt werden soll
jedes Verzeichnis, das der Linker nach Bibliotheken durchsuchen soll.

Eine weitere Variable, „ENV“, wird verwendet, um die Systemumgebung während der Ausführung zu bestimmen
eines externen Befehls. Standardmäßig ist „PATH“ als einzige Umgebungsvariable festgelegt.
Dies ist der Ausführungspfad für einen UNIX-Befehl. Für größtmögliche Reproduzierbarkeit sollten Sie Folgendes tun
Richten Sie wirklich Ihren eigenen Ausführungspfad auf Ihrer obersten Ebene ein Konstruieren Datei (oder
vielleicht durch Importieren eines entsprechenden Baupakets mit dem Perl-Befehl „use“. Der
Standardvariablen sollen Ihnen den Einstieg erleichtern.

Interpolieren Baugewerbe Variablen

Konstruktionsumgebungsvariablen können in die Quell- und Zieldateinamen interpoliert werden
indem dem Konstruktionsvariablennamen „%“ vorangestellt wird.

$env = neue Nachteile(
DESTDIR => 'Programme',
SRCDIR => 'src',
);
Programm $env '%DESTDIR/hello', '%SRCDIR/hello.c';

Die Erweiterung von Konstruktionsvariablen erfolgt rekursiv, also der Datei Name(s) werden wieder-
erweitert, bis keine Ersetzungen mehr möglich sind. Wenn eine Konstruktionsvariable nicht vorhanden ist
in der Umgebung definiert ist, wird die Nullzeichenfolge ersetzt.

Standard Baugewerbe Methoden


Die Liste der Standardkonstruktionsmethoden umfasst Folgendes:

Das „neu“ Konstruktor

Die „neue“ Methode ist ein Perl-Objektkonstruktor. Das heißt, es wird nicht über eine Referenz aufgerufen
an eine bestehende Bauumgebung Referenz, sondern eher statisch unter Verwendung des Namens
des Perl Paket wo der Konstruktor definiert ist. Die Methode wird wie folgt aufgerufen:

$env = neue Nachteile( );

Die Umgebung, die Sie zurückerhalten, wird in das Paket „Nachteile“ aufgenommen, was bedeutet, dass dies der Fall ist
haben die unten beschriebenen Standardmethoden damit verknüpft. Individuelle Konstruktion
Variablen können überschrieben werden, indem Name/Wert-Paare in einer Überschreibungsliste bereitgestellt werden. Beachten Sie, dass
Um eine Befehlsumgebungsvariable (z. B. alles unter „ENV“) zu überschreiben, müssen Sie dies tun
überschreiben Sie alle. Sie können dieses Problem umgehen, indem Sie die Methode „Kopieren“ auf einem verwenden
bestehende Bauumgebung.

Das „Klonen“ Methode

Die Methode „Klonen“ erstellt einen Klon einer vorhandenen Bauumgebung und kann dies auch tun
aufgerufen wie im folgenden Beispiel:

$env2 = $env1->clone( );

Sie können auf die übliche Weise Überschreibungen bereitstellen, um eine andere Umgebung als die zu erstellen
Original. Wenn Sie nur einen neuen Namen für dieselbe Umgebung wünschen (was hilfreich sein kann, wenn
(Exportieren von Umgebungen in vorhandene Komponenten) können Sie einfach eine einfache Zuweisung verwenden.

Das „kopieren“ Methode

Die Methode „Kopieren“ extrahiert die extern definierten Konstruktionsvariablen aus einem
Umgebung und gibt sie als Liste von Name/Wert-Paaren zurück. Es können auch Überschreibungen erfolgen
vorausgesetzt, in diesem Fall werden die überschriebenen Werte gegebenenfalls zurückgegeben. Der
Die zurückgegebene Liste kann einem Hash zugewiesen werden, wie im Prototyp unten gezeigt, aber das ist auch möglich
auf andere Weise manipuliert werden:

%env = $env1->copy( );

Der Wert von „ENV“, der selbst ein Hash ist, wird ebenfalls in einen neuen Hash kopiert, daher kann dies der Fall sein
geändert werden, ohne befürchten zu müssen, dass die ursprüngliche Umgebung beeinträchtigt wird. Also zum Beispiel, wenn Sie wirklich
Wenn Sie nur die Variable „PATH“ in der Standardumgebung überschreiben möchten, können Sie Folgendes tun
wie folgt vor:

%cons = new cons()->copy();
$cons{ENV}{PATH} = " ";
$cons = neue Nachteile(%cons);

Dadurch bleibt alles übrig, was sich möglicherweise in der Standardausführungsumgebung befindet
ungestört.

Das „Installieren“ Methode

Die Methode „Install“ sorgt dafür, dass die angegebenen Dateien im angegebenen Verzeichnis installiert werden
Verzeichnis. Die Installation ist optimiert: Die Datei wird nicht kopiert, wenn sie verlinkt werden kann. Wenn
Da dies nicht das gewünschte Verhalten ist, müssen Sie zur Installation eine andere Methode verwenden
Datei. Es heißt wie folgt:

Installieren Sie $env , ;

Beachten Sie, dass die zu installierenden Dateien zwar beliebig benannt werden können, jedoch nur die letzte
Die Komponente jedes Namens wird für den installierten Zielnamen verwendet. Also zum Beispiel, wenn Sie
Veranlassen Sie die Installation foo/bar in baz, dadurch wird ein erstellt Bar Datei in das baz Verzeichnis (nicht
foo/bar).

Das „Installieren als“ Methode

Die Methode „InstallAs“ richtet sich nach der angegebenen Quelle Datei(s) als installiert werden
angegebenes Ziel Datei(S). Mehrere Dateien sollten als Dateiliste angegeben werden. Der
Die Installation ist optimiert: Die Datei wird nicht kopiert, wenn sie verlinkt werden kann. Wenn dies nicht der Fall ist
Um das gewünschte Verhalten zu erzielen, müssen Sie eine andere Methode zum Installieren der Datei verwenden. Es ist
wie folgt aufgerufen:

„InstallAs“ funktioniert auf zwei Arten:

Einzeldateiinstallation:

InstallAs $env TgtFile, SrcFile;

Installation mehrerer Dateien:

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

Oder sogar als:

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

Sowohl die Ziel- als auch die Quellenliste sollten die gleiche Länge haben.

Das „Kostbar“ Methode

Die „Precious“-Methode fordert die Benutzer auf, die angegebene Datei oder Dateiliste vorher nicht zu löschen
sie wieder aufzubauen. Es wird aufgerufen als:

Wertvoll ;

Dies ist besonders nützlich, um inkrementelle Aktualisierungen von Bibliotheken oder das Debuggen zu ermöglichen
Informationsdateien, die jedes Mal aktualisiert und nicht neu erstellt werden. Nachteile werden immer noch
Löschen Sie die Dateien, wenn das Flag „-r“ angegeben ist.

Das „Befehl“ Methode

Die „Command“-Methode ist eine Sammelmethode, mit der beliebige externe Befehle arrangiert werden können
Befehl, der aufgerufen werden soll, um das Ziel zu aktualisieren. Für diesen Befehl eine Zieldatei und eine Liste von
Eingänge zur Verfügung gestellt. Darüber hinaus wird eine oder mehrere Konstruktionsbefehlszeilen als bereitgestellt
Zeichenfolge (in diese Zeichenfolge können mehrere Befehle eingebettet sein, die durch „new“ getrennt sind
Linien). „Befehl“ heißt wie folgt:

Befehl $env , , ;

Das Ziel wird von der Liste der angegebenen Eingabedateien abhängig gemacht, und die Eingaben müssen erfolgen
erfolgreich erstellt werden, oder Cons wird nicht versuchen, das Ziel zu erstellen.

Innerhalb des Konstruktionsbefehls kann jede Variable aus der Konstruktionsumgebung verwendet werden
eingeführt, indem dem Namen der Konstruktionsvariablen „%“ vorangestellt wird. Das ist rekursiv:
Der Befehl wird solange erweitert, bis keine Ersetzungen mehr möglich sind. Wenn eine Konstruktion
Wenn die Variable in der Umgebung nicht definiert ist, wird sie durch die Nullzeichenfolge ersetzt. A
Doppeltes „%%“ wird im Konstruktionsbefehl durch ein einzelnes „%“ ersetzt.

Es gibt mehrere Pseudovariablen, die ebenfalls erweitert werden:

%> Der Name der Zieldatei (in einem Befehl mit mehreren Zielen ist dies immer das erste Ziel
erwähnt).

%0 Identisch mit „%>“.

%1, %2, ..., %9
Diese beziehen sich jeweils auf die erste bis neunte Eingabedatei.

%< Der vollständige Satz von Eingaben. Wenn eines davon irgendwo anders in der verwendet wurde
aktuelle Befehlszeile (über „%1“, „%2“ usw.), dann werden diese aus der gelöscht
Liste bereitgestellt von „%<“. Betrachten Sie den folgenden Befehl in a Wehrpflicht Datei
der Test Verzeichnis:

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

If tgt aktualisiert werden müsste, würde dies zur Ausführung des führen
Folgende Befehle werden ausgeführt, vorausgesetzt, dass keine Neuzuordnung für die erstellt wurde Test
Verzeichnis:

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

Auf jede der oben genannten Pseudovariablen kann unmittelbar eine der folgenden folgen
Suffixe, um einen Teil des erweiterten Pfadnamens auszuwählen:

:a der absolute Pfad zum Dateinamen
:b das Verzeichnis plus den Dateinamen ohne Suffix
:d das Verzeichnis
:f der Dateiname
:s das Dateinamensuffix
:F Der Dateiname ohne Suffix

Um mit dem obigen Beispiel fortzufahren, würde „%<:f“ zu „foo bar baz“ erweitert werden, und „%':d> würde.“
Erweitern Sie es auf „Test“.

Es ist möglich, einen Teil des Befehls programmgesteuert umzuschreiben, indem man einen Teil davon einschließt
zwischen „%[“ und „%]“. Dadurch wird die als erstes Wort genannte Konstruktionsvariable aufgerufen
in Klammern als Perl-Code-Referenz eingeschlossen; Die Ergebnisse dieses Aufrufs werden verwendet
um den Inhalt der Klammern in der Befehlszeile zu ersetzen. Zum Beispiel gegeben an
vorhandene Eingabedatei mit dem Namen tgt.in:

@keywords = qw(foo bar baz);
$env = new cons(X_COMMA => sub { join(",", @_) });
Befehl $env 'tgt', 'tgt.in', qq(
echo '# Schlüsselwörter: %[X_COMMA @keywords %]' > %>
Katze %< >> %>
);

Dadurch wird Folgendes ausgeführt:

echo '# Schlüsselwörter: foo,bar,baz' > tgt
cat tgt.in >> tgt

Nach der Ersetzung werden Zeichenfolgen mit Leerzeichen in einzelne Leerzeichen umgewandelt
Führende und nachfolgende Leerzeichen werden eliminiert. Eine Einführung ist daher nicht möglich
Leerzeichen variabler Länge in Zeichenfolgen, die an einen Befehl übergeben werden, ohne dass auf einige zurückgegriffen werden muss
Eine Art Shell-Zitat.

Wenn eine mehrzeilige Befehlszeichenfolge bereitgestellt wird, werden die Befehle nacheinander ausgeführt. Wenn überhaupt
Wenn einer der Befehle fehlschlägt, wird keiner der übrigen Befehle ausgeführt und das Ziel wird nicht als markiert
aktualisiert, d. h. es wird keine neue Signatur für das Ziel hinterlegt.

Normalerweise, wenn alle Befehle erfolgreich sind und einen Nullstatus zurückgeben (oder auf welcher Plattform auch immer),
(Wenn eine konkrete Erfolgsmeldung erforderlich ist), wird für den eine neue Signatur hinterlegt
Ziel. Wenn ein Befehl auch nach einem Fehlschlag fälschlicherweise einen Erfolg meldet, wird dies bei Cons der Fall sein
Gehen Sie davon aus, dass die durch diesen Befehl erstellte Zieldatei korrekt und aktuell ist.

Es wird davon ausgegangen, dass das erste Wort jeder Befehlszeichenfolge nach der Erweiterung eine ausführbare Datei ist
Der Befehl hat in der Umgebungsvariablen „PATH“ nachgeschlagen (die wiederum durch angegeben wird).
Konstruktionsvariable „ENV“). Wenn dieser Befehl im Pfad gefunden wird, wird dies auch beim Ziel der Fall sein
verlassen Sie sich darauf: Der Befehl wird daher bei Bedarf automatisch erstellt. Es ist
Es ist möglich, für einige Shells mehrteilige Befehle zu schreiben, die durch Semikolons getrennt sind. Nur der
Das erste Befehlswort hängt jedoch davon ab, ob Sie also Ihre Befehlszeichenfolgen schreiben
Auf diese Weise müssen Sie entweder explizit eine Abhängigkeit einrichten (mit der Methode „Depends“) oder
Stellen Sie sicher, dass der von Ihnen verwendete Befehl ein erwarteter Systembefehl ist
verfügbar. Wenn es nicht verfügbar ist, erhalten Sie natürlich eine Fehlermeldung.

Wenn ein Befehl (auch einer innerhalb eines mehrzeiligen Befehls) mit „[perl]“ beginnt, gilt der Rest
dieser Befehlszeile wird vom laufenden Perl ausgewertet, anstatt von geforkt zu werden
Hülse. Wenn beim Parsen des Perls ein Fehler auftritt oder der Perl-Ausdruck 0 zurückgibt oder
undef, der Befehl wird als fehlgeschlagen betrachtet. Hier ist zum Beispiel ein einfaches
Befehl, der eine Datei „foo“ direkt aus Perl erstellt:

$env = neue Nachteile();
Befehl $env 'foo',
qq([perl] open(FOO,'>foo');print FOO "hi\\n"; close(FOO); 1);

Beachten Sie, dass Sie sich beim Ausführen des Befehls im selben Paket befinden wie beim Ausführen des Befehls Konstruieren
or Wehrpflicht Die Datei wurde gelesen, sodass Sie darin definierte Perl-Funktionen aufrufen können
Konstruieren or Wehrpflicht Datei, in der der „Befehl“ vorkommt:

$env = neue Nachteile();
sub create_file {
meine $datei = Verschiebung;
open(FILE, ">$file");
print FILE „hi\n“;
Datei schließen);
Rückkehr 1;
}
Befehl $env 'foo', "[perl] &create_file('%>')";

Der Perl-String wird verwendet, um die Signatur für die abgeleitete Datei zu generieren
Ändern Sie die Zeichenfolge, die Datei wird neu erstellt. Der Inhalt aller von Ihnen aufgerufenen Unterprogramme,
sind jedoch nicht Teil der Signatur. Wenn Sie also eine aufgerufene Unterroutine ändern, z
`create_file' oben, das Ziel wird nicht wieder aufgebaut werden. Vorsichtsmaßnahme Benutzer.

Cons gibt normalerweise einen Befehl aus, bevor er ausgeführt wird. Dieses Verhalten wird unterdrückt, wenn die
Das erste Zeichen des Befehls ist „@“. Beachten Sie, dass Sie möglicherweise das „@“ von trennen müssen
Geben Sie den Befehlsnamen ein oder maskieren Sie ihn, um zu verhindern, dass „@cmd“ wie ein Array in Perl-Anführungszeichen aussieht
Operatoren, die Interpolation durchführen:

# Die erste Befehlszeile ist falsch,
# weil „@cp“ wie ein Array aussieht
# zur Perl qq//-Funktion.
# Verwenden Sie stattdessen das zweite Formular.
Befehl $env 'foo', 'foo.in', qq(
@cp %< temporäre Datei
@ cp tempfile %>
);

Wenn irgendwo in der erweiterten Befehlszeile Shell-Metazeichen vorhanden sind, z. B. „<“,
`>', Anführungszeichen oder Semikolon, dann wird der Befehl tatsächlich durch Aufrufen von a ausgeführt
Hülse. Das bedeutet, dass ein Befehl wie:

CD foo

allein schlägt normalerweise fehl, da der Pfad keinen Befehl „cd“ enthält. Aber der Befehl
Zeichenfolge:

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

Wenn es erweitert ist, enthält es weiterhin das Shell-Metazeichen Semikolon und eine Shell
aufgerufen, um den Befehl zu interpretieren. Da „cd“ von dieser Sub-Shell interpretiert wird, ist der Befehl
wird wie erwartet ausgeführt.

Um einen Befehl mit mehreren Zielen anzugeben, können Sie einen Verweis auf eine Liste von angeben
Ziele. In Perl kann eine Listenreferenz erstellt werden, indem eine Liste in eckige Klammern eingeschlossen wird.
Daher der folgende Befehl:

Befehl $env ['foo.h', 'foo.c'], 'foo.template', q(
Generation %1
);

könnte in einem Fall verwendet werden, in dem der Befehl „gen“ zwei Dateien erstellt, beide foo.h und foo.c.

Das „Objekte“ Methode

Die Methode „Objects“ sorgt dafür, dass die Objektdateien erstellt werden, die den angegebenen entsprechen
Quelldaten. Der Aufruf erfolgt wie folgt:

@files = Objekte $env ;

Unter Unix enden Quelldateien auf .s und .c werden derzeit unterstützt und werden kompiliert
in einen Namen derselben Datei mit der Endung .o. Standardmäßig werden alle Dateien durch Aufrufen erstellt
der externe Befehl, der sich aus der Erweiterung der Konstruktionsvariablen „CCCOM“ ergibt, mit
„%<“ und „%>“ werden auf die Quell- bzw. Objektdateien gesetzt (siehe die Methode „Command“)
für Einzelheiten zur Erweiterung). Die Variable „CPPPATH“ wird auch beim Scannen von Quelldateien verwendet
für Abhängigkeiten. Dies ist eine durch Doppelpunkte getrennte Liste von Pfadnamen, die auch zum Erstellen verwendet wird
die Konstruktionsvariable „_IFLAGS“, die die entsprechende Liste von „I“ enthält.
Optionen für die Zusammenstellung. Alle relativen Pfadnamen in „CPPPATH“ werden relativ interpretiert
in das Verzeichnis, in dem die zugehörige Konstruktionsumgebung erstellt wurde (absolut).
Es können auch Namen mit relativen Top-Relativnamen verwendet werden. Diese Variable wird von „CCCOM“ verwendet. Das Verhalten
Dieser Befehl kann durch Ändern einer der interpolierten Variablen geändert werden
in „CCCOM“, wie „CC“, „CFLAGS“ und indirekt „CPPPATH“. Es ist auch möglich
Ersetzen Sie den Wert von „CCCOM“ selbst. Der Einfachheit halber gibt diese Datei die Liste von zurück
Objektdateinamen.

Das „Programm“ Methode

Die Methode „Programm“ sorgt dafür, dass das angegebene Programm mit dem angegebenen Objekt verknüpft wird
Dateien. Der Aufruf erfolgt wie folgt:

Programm $env , ;

An den Programmnamen wird der Wert der Konstruktionsvariablen „SUFEXE“ angehängt (durch
Standardmäßig „.exe“ auf Win32-Systemen, nichts auf Unix-Systemen), wenn das Suffix noch nicht vorhanden ist
Geschenk.

Quelldateien können anstelle von Objektdateien angegeben werden – die Methode „Objekte“ ist dies
aufgerufen, um die Konvertierung aller Dateien in Objektdateien und damit aller Dateien zu veranlassen
Die obigen Beobachtungen zur Methode „Objekte“ gelten auch für diese Methode.

Die eigentliche Verknüpfung des Programms erfolgt durch einen daraus resultierenden externen Befehl
vom Erweitern der Konstruktionsvariablen „LINKCOM“, wobei „%<“ auf die Objektdateien gesetzt ist
verknüpft werden (in der angegebenen Reihenfolge) und „%>“ auf das Ziel gesetzt wird (siehe die Methode „Befehl“)
für Einzelheiten zur Erweiterung). Der Benutzer kann in der Konstruktion zusätzliche Variablen festlegen
Umgebung, einschließlich „LINK“, um zu definieren, welches Programm zum Verknüpfen verwendet werden soll, „LIBPATH“, a
Durch Doppelpunkte getrennte Liste von Bibliothekssuchpfaden zur Verwendung mit Bibliotheksspezifikationen der
unten stehende Formular -llibund „LIBS“, wobei die Liste der Bibliotheken angegeben wird, mit denen verknüpft werden soll (in beiden Fällen). -llib
Form oder einfach als Pfadnamen. Relative Pfadnamen sowohl in „LIBPATH“ als auch in „LIBS“ werden interpretiert
relativ zum Verzeichnis, in dem die zugehörige Konstruktionsumgebung erstellt wird
(Absolute und top-relative Namen können ebenfalls verwendet werden). Nachteile werden automatisch eingerichtet
Abhängigkeiten von allen in „LIBS“ genannten Bibliotheken: Diese Bibliotheken werden vorher erstellt
Der Befehl ist verknüpft.

Das „Bibliothek“ Methode

Die Methode „Library“ sorgt dafür, dass die angegebene Bibliothek aus dem angegebenen Objekt erstellt wird
Dateien. Der Aufruf erfolgt wie folgt:

Bibliothek $env , ;

An den Bibliotheksnamen wird der Wert der Konstruktionsvariablen „SUFLIB“ angehängt (von
Standardmäßig „.lib“ auf Win32-Systemen, „.a“ ​​auf Unix-Systemen), wenn das Suffix noch nicht vorhanden ist
Geschenk.

Quelldateien können anstelle von Objektdateien angegeben werden – die Methode „Objekte“ ist dies
aufgerufen, um die Konvertierung aller Dateien in Objektdateien und damit aller Dateien zu veranlassen
Die obigen Beobachtungen zur Methode „Objekte“ gelten auch für diese Methode.

Die eigentliche Erstellung der Bibliothek erfolgt durch einen externen Befehl, der daraus resultiert
vom Erweitern der Konstruktionsvariablen „ARCOM“, wobei „%<“ auf die Bibliotheksmitglieder gesetzt ist (in
in der angezeigten Reihenfolge) und „%>“ in die zu erstellende Bibliothek (siehe die Methode „Befehl“ für).
Erweiterungsdetails). Der Benutzer kann in der Konstruktionsumgebung Variablen festlegen, die dies tun
Auswirkungen auf die Ausführung des Befehls haben. Dazu gehören „AR“, das zu verwendende Archivprogramm,
„ARFLAGS“, mit dem die Flags geändert werden können, die dem durch „AR“ angegebenen Programm zugewiesen wurden.
und „RANLIB“, der Name eines Archivindex-Generierungsprogramms, falls erforderlich (sofern dies der Fall ist).
Wenn Sie die letztgenannte Funktionalität nicht benötigen, muss „ARCOM“ in „nicht“ umdefiniert werden
Referenz „RANLIB“).

Mit der Methode „Bibliothek“ kann dieselbe Bibliothek in mehreren Methoden angegeben werden
Aufrufe. Alle beitragenden Objekte aus allen Aufrufen (die möglicherweise von stammen
verschiedene Verzeichnisse) werden durch einen einzigen Archivierungsbefehl zusammengefasst und generiert. Notiz,
Wenn Sie jedoch einen Build bereinigen, sodass nur ein Teil einer Bibliothek angegeben wird, dann nur
Dieser Teil der Bibliothek wird generiert (der Rest verschwindet!).

Das „Modul“ Methode

Die Methode „Module“ ist eine Kombination aus den Methoden „Program“ und „Command“. Statt
Wenn Sie direkt ein ausführbares Programm generieren möchten, können Sie mit diesem Befehl Ihr eigenes Programm angeben
Befehl, um tatsächlich ein Modul zu generieren. Die Methode wird wie folgt aufgerufen:

Modul $env , , ;

Dieser Befehl ist in Fällen nützlich, in denen Sie beispielsweise dynamisch erstellen möchten
geladene Module oder statisch verknüpfte Codebibliotheken.

Das „Hängt davon ab“ Methode

Mit der Methode „Depends“ können Sie zusätzliche Abhängigkeiten für ein Ziel angeben. Es ist
wie folgt aufgerufen:

Hängt von $env ab , ;

Dies kann gelegentlich nützlich sein, insbesondere in Fällen, in denen kein Scanner vorhanden ist (oder ist).
beschreibbar) für bestimmte Dateitypen. Normalerweise werden Abhängigkeiten berechnet
automatisch aus einer Kombination der von der Methode eingerichteten expliziten Abhängigkeiten
Aufruf oder durch Scannen von Quelldateien.

Mithilfe eines Verweises auf kann ein Satz identischer Abhängigkeiten für mehrere Ziele angegeben werden
eine Liste von Zielen. In Perl kann eine Listenreferenz erstellt werden, indem eine Liste in ein Quadrat eingeschlossen wird
Klammern. Daher der folgende Befehl:

Hängt davon ab: $env ['foo', 'bar'], 'input_file_1', 'input_file_2';

gibt an, dass beide foo und Bar Dateien hängen von den aufgelisteten Eingabedateien ab.

Das „Ignorieren“ Methode

Mit der Methode „Ignorieren“ können Sie explizit Abhängigkeiten ignorieren, die Cons daraus ableitet
eigen. Der Aufruf erfolgt wie folgt:

Ignorieren ;

Dies kann verwendet werden, um Neukompilierungen aufgrund von Änderungen in System-Header-Dateien oder zu vermeiden
Dienstprogramme, von denen bekannt ist, dass sie die generierten Ziele nicht beeinflussen.

Wenn beispielsweise ein Programm in einem NFS-gemounteten Verzeichnis auf mehreren Systemen erstellt wird
habe verschiedene Exemplare davon stdio.h, die Unterschiede wirken sich auf die Unterschriften aller aus
Abgeleitete Ziele, die aus Quelldateien erstellt wurden, die „#include“ enthalten '. Das wird alles verursachen
Diese Ziele müssen bei einem Systemwechsel neu erstellt werden. Wenn dies kein erwünschtes Verhalten ist,
dann entfernt die folgende Zeile die Abhängigkeiten von stdio.h Datei:

Ignorieren Sie '^/usr/include/stdio\.h$';

Beachten Sie, dass die Argumente der Methode „Ignore“ reguläre Ausdrücke sind, also etwas Besonderes
Zeichen müssen mit Escapezeichen versehen werden und Sie möchten möglicherweise den Anfang oder das Ende des Zeichens verankern
Ausdruck mit den Zeichen „^“ oder „$“.

Das „Salz“ Methode

Die „Salt“-Methode fügt der Signaturberechnung für jede Ableitung einen konstanten Wert hinzu
Datei. Der Aufruf erfolgt wie folgt:

Salz $string;

Durch Ändern des Salt-Werts wird eine vollständige Neuerstellung jeder abgeleiteten Datei erzwungen. Das kann sein
Wird verwendet, um unter bestimmten gewünschten Umständen Neuaufbauten zu erzwingen. Zum Beispiel,

Salz `uname -s`;

Würde eine vollständige Neuerstellung jeder abgeleiteten Datei erzwingen, wenn das Betriebssystem eingeschaltet ist
in dem der Build ausgeführt wird (wie von „uname -s“ gemeldet), ändert sich.

Das „UseCache“ Methode

Die Methode „UseCache“ weist Cons an, einen Cache mit abgeleiteten Dateien zur gemeinsamen Nutzung zu verwalten
zwischen separaten Build-Bäumen desselben Projekts.

UseCache("cache/ ") ⎪⎪ warn("Cache-Verzeichnis nicht gefunden");

Das „SourcePath“ Methode

Die Mathode „SourcePath“ gibt den tatsächlichen Quellpfadnamen einer Datei zurück, im Gegensatz zum
Pfadname innerhalb eines Build-Verzeichnisses. Der Aufruf erfolgt wie folgt:

$path = SourcePath ;

Das „ConsPath“ Methode

Die Methode „ConsPath“ gibt „true“ zurück, wenn der angegebene Pfad eine ableitbare Datei ist, und gibt zurück
undef (false), andernfalls. Der Aufruf erfolgt wie folgt:

$result = ConsPath ;

Das „SplitPath“ Methode

Die Methode „SplitPath“ sucht standardmäßig nach mehreren Pfadnamen in einer Zeichenfolge, getrennt durch die Standardeinstellung
Pfadtrennzeichen für das Betriebssystem („:“ auf UNIX-Systemen, „;“ auf Windows NT) und
gibt die vollständig qualifizierten Namen zurück. Der Aufruf erfolgt wie folgt:

@paths = SplitPath ;

Die „SplitPath“-Methode konvertiert Namen mit dem Präfix „#“ in den entsprechenden Build der obersten Ebene
name (ohne das „#“) und wandelt relative Namen in Namen der obersten Ebene um.

Das „DirPath“ Methode

Die Methode „DirPath“ gibt den Build-Pfad zurück Name(s) eines Verzeichnisses oder einer Liste von Verzeichnissen.
Der Aufruf erfolgt wie folgt:

$cwd = DirPath ;

Die häufigste Verwendung der Methode „DirPath“ ist:

$cwd = DirPath '.';

um den Pfad zum aktuellen Verzeichnis einer Tochtergesellschaft abzurufen Wehrpflicht Datei.

Das „Dateipfad“ Methode

Die Methode „FilePath“ gibt den Build-Pfad zurück Name(s) einer Datei oder Liste von Dateien. Es ist
wie folgt aufgerufen:

$file = Dateipfad ;

Das „Hilfe“ Methode

Die Methode „Help“ gibt den Hilfetext an, der angezeigt wird, wenn der Benutzer „cons“ aufruft
-H'. Dies kann zur Dokumentation spezifischer Ziele, Werte und Builds verwendet werden
Optionen usw. für den Build-Baum. Der Aufruf erfolgt wie folgt:

Helfen ;

Die Methode „Help“ darf nur einmal aufgerufen werden und sollte normalerweise oben angegeben werden.
Grad des Konstruieren Datei.

Erweitern Nachteile


Überschreiben Baugewerbe Variablen

Es gibt verschiedene Möglichkeiten, Cons zu erweitern, die sich im Schwierigkeitsgrad unterscheiden. Das einfachste
Die Methode besteht darin, Ihre eigene Konstruktionsumgebung basierend auf der Standardumgebung zu definieren.
aber angepasst, um Ihre speziellen Bedürfnisse widerzuspiegeln. Dies reicht oft für C-basierte aus
Anwendungen. Sie können den Konstruktor „new“ sowie die Methoden „clone“ und „copy“ verwenden
Erstellen Sie hybride Umgebungen. Diese Änderungen können für den Basiswert völlig transparent sein
Wehrpflicht Dateien.

Hinzufügen neu Methoden

Für etwas anspruchsvollere Änderungen möchten Sie möglicherweise neue Methoden zu den „Nachteilen“ hinzufügen.
Paket. Hier ist ein Beispiel für eine sehr einfache Erweiterung, „InstallScript“, die a installiert
tcl-Skript an einem angeforderten Speicherort, bearbeitet das Skript jedoch zuerst, um eine Plattform-
abhängiger Pfad, der im Skript installiert werden muss:

# cons::InstallScript – Erstellen Sie eine plattformabhängige Version einer Shell
#-Skript durch Ersetzen der Zeichenfolge „#!your-path-here“ durch plattformspezifisch
# Pfad $BIN_DIR.

sub cons::InstallScript {
my ($env, $dst, $src) = @_;
Befehl $env $dst, $src, qq(
sed s+your-path-here+$BIN_DIR+ %< > %>
chmod oug+x %>
);
}

Beachten Sie, dass diese Methode direkt im Paket „cons“ definiert ist (durch Voranstellen des Namens).
mit „cons::“). Eine auf diese Weise vorgenommene Änderung ist global für alle Umgebungen sichtbar.
und könnte wie im folgenden Beispiel aufgerufen werden:

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

Für eine kleine Verbesserung der Allgemeinheit könnte die Variable „BINDIR“ als übergeben werden
Argument oder aus der Konstruktionsumgebung übernommen – als „%BINDIR“.

Überschreiben Methoden

Anstatt die Methode zum Namensraum „cons“ hinzuzufügen, könnten Sie ein neues Paket definieren
die vorhandene Methoden aus dem Paket „cons“ erbt und andere überschreibt oder hinzufügt. Das
kann mithilfe der Vererbungsmechanismen von Perl erfolgen.

Das folgende Beispiel definiert ein neues Paket „cons::switch“, das den Standard überschreibt
Methode „Bibliothek“. Die überschriebene Methode erstellt verknüpfte Bibliotheksmodule und keine Bibliothek
Archiv. Ein neuer Konstruktor wird bereitgestellt. Mit diesem Konstruktor erstellte Umgebungen werden dies tun
habe die neue Bibliotheksmethode; andere werden es nicht tun.

Paketnachteile::switch;
BEGIN {@ISA = 'cons'}

Unter neu {
Schicht;
segne neue Nachteile(@_);
}

Unterbibliothek {
my($env) = Verschiebung;
my($lib) = Verschiebung;
my(@objs) = Objekte $env @_;
Befehl $env $lib, @objs, q(
%LD -r %LDFLAGS %< -o %>
);
}

Diese Funktionalität könnte wie im folgenden Beispiel aufgerufen werden:

$env = neue Nachteile::switch(@overrides);
...
Bibliothek $env 'lib.o', 'foo.c', 'bar.c';

Aufrufen Nachteile


Der Befehl „cons“ wird normalerweise im Stammverzeichnis des Build-Baums aufgerufen. A Konstruieren Datei
muss in diesem Verzeichnis vorhanden sein. Wenn das Argument „-f“ verwendet wird, dann eine Alternative Konstruieren
Datei kann verwendet werden (und möglicherweise ein alternatives Stammverzeichnis, da „cons“ dorthin kopiert wird). Konstruieren
Verzeichnis, in dem die Datei enthalten ist).

Wenn „cons“ von einem untergeordneten Element der Wurzel des Build-Baums mit dem Argument „-t“ aufgerufen wird, wird es
wird die Verzeichnishierarchie nach oben gehen und nach einem suchen Konstruieren Datei. (Ein alternativer Name kann sein
weiterhin mit „-f“ angegeben werden.) Die auf der Befehlszeile angegebenen Ziele werden geändert
relativ zum Entdeckten sein Konstruieren Datei. Zum Beispiel aus einem Verzeichnis mit
ein Spitzenniveau Konstruieren Datei, der folgende Aufruf:

% cd libfoo/subdir
% cons -t Ziel

ist genau gleichbedeutend mit:

% Nachteile libfoo/subdir/target

Wenn in der Verzeichnishierarchie „Standard“-Ziele angegeben sind Konstruieren or
Wehrpflicht Dateien, nur die Standardziele in oder unterhalb des Verzeichnisses, aus dem „cons -t“ stammt
aufgerufen wurde, wird erstellt.

Der Befehl wird wie folgt aufgerufen:

Nachteile --

woher Argumente kann in beliebiger Reihenfolge Folgendes sein:

Ziel Erstellen Sie das angegebene Ziel. Wenn Ziel ist ein Verzeichnis und wird dann rekursiv erstellt
alles in diesem Verzeichnis.

+Muster Begrenzen Sie die Wehrpflicht Es werden nur diejenigen Dateien berücksichtigt, die übereinstimmen Anleitungen, Das ist
ein regulärer Perl-Ausdruck. Es werden mehrere „+“-Argumente akzeptiert.

Name=
Sets Name schätzen Welle im „ARG“-Hash, der an die oberste Ebene übergeben wird Konstruieren Datei.

„-cc“ Zeigt den Befehl an, der beim Abrufen aus dem Cache ausgeführt worden wäre. NEIN
es wird angezeigt, dass die Datei abgerufen wurde; das ist nützlich für
Generieren von Build-Protokollen, die mit echten Build-Protokollen verglichen werden können.

„-cd“ Deaktiviert sämtliches Caching. Nicht aus dem Cache abrufen oder in den Cache leeren.

„-cr“ Abhängigkeiten in zufälliger Reihenfolge erstellen. Dies ist nützlich, wenn Sie mehrere erstellen
Ähnliche Bäume mit aktiviertem Caching.

„-cs“ Synchronisiert vorhandene Build-Ziele, die mit dem Cache auf dem neuesten Stand sind.
Dies ist nützlich, wenn das Caching mit -cc deaktiviert oder erst kürzlich aktiviert wurde
mit UseCache.

„-d“ Aktiviert das Debuggen von Abhängigkeiten.

„-f“
Verwenden Sie stattdessen die angegebene Datei Konstruieren (Aber zuerst auf „Containing“ umstellen
Verzeichnis von Datei).

„-h“ Zeigt eine lokale Hilfemeldung für den aktuellen Build an, sofern eine solche definiert ist, und beendet den Vorgang.

`-k' Nach Fehlern so weit wie möglich fortfahren.

„-o“
Override-Datei lesen Datei.

`-p' Bauprodukte in bestimmten Bäumen anzeigen. Es wird kein Buildversuch unternommen.

`-pa' Bauprodukte und zugehörige Aktionen anzeigen. Es wird kein Buildversuch unternommen.

„-pw“ Zeigt Produkte und wo sie definiert sind. Es wird kein Buildversuch unternommen.

`-q' Seien Sie beim Installieren und Entfernen von Zielen nicht ausführlich.

„-r“ Bauprodukte entfernen, die mit verknüpft sind . Es wird kein Buildversuch unternommen.

„-R“
Suchen Sie nach Dateien in repos. Mehrere -R repos Verzeichnisse werden im durchsucht
Reihenfolge angegeben.

`-t' Durchsuchen Sie die Verzeichnishierarchie nach oben und suchen Sie nach einem Konstruieren Datei, falls keine vorhanden ist
im aktuellen Verzeichnis. Ziele werden so geändert, dass sie relativ zum sind
Konstruieren Datei.

„-v“ „Cons“-Version anzeigen und mit der Verarbeitung fortfahren.

„-V“ „Cons“-Version anzeigen und beenden.

„-wf“
Schreiben Sie alle berücksichtigten Dateinamen hinein Datei.

„-x“ Zeigt eine Hilfemeldung ähnlich dieser an und beendet den Vorgang.

Und Konstruktargumente Dies können beliebige Argumente sein, die Sie im verarbeiten möchten Konstruieren Datei.
Beachten Sie, dass es eine geben sollte -- Trennen Sie die Argumente in Nachteile und die Argumente, die Sie haben
verarbeiten möchten Konstruieren Datei.

Verarbeitung von Konstruktargumente kann mit jedem Standardpaket wie durchgeführt werden Getopt oder ihre
Varianten oder ein beliebiges benutzerdefiniertes Paket. Nachteile wird in der passieren Konstruktargumente as @ARGV und
Ich werde nicht versuchen, irgendetwas danach zu interpretieren --.

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

würde folgendes an cons weitergeben

-R /usr/local/repository -d os=solaris +driver

und das Folgende auf die oberste Ebene Konstruieren Datei als @ARGV

-c test -f DEBUG

Beachten Sie, dass „cons -r.“ entspricht einem vollständig rekursiven „Make Clean“, erfordert jedoch keines
Unterstützung in der Konstruieren Datei oder irgendwas Wehrpflicht Dateien. Dies ist am nützlichsten, wenn Sie es sind
Kompilieren von Dateien in Quellverzeichnissen (wenn Sie die bauen und exportieren Verzeichnisse,
dann können Sie einfach die Verzeichnisse entfernen).

Die Optionen „-p“, „-pa“ und „-pw“ sind äußerst nützlich als Lesehilfe
Skripte zu erstellen oder sie zu debuggen. Wenn Sie wissen möchten, welches Skript installiert wird export/include/foo.h,
Geben Sie zum Beispiel einfach Folgendes ein:

% cons -pw export/include/foo.h

Die richtigen und Schreiben Abhängigkeit Scanner


QuickScan ermöglicht die Einrichtung einfacher zielunabhängiger Scanner für Quelldateien. Nur
Ein QuickScan-Scanner kann jeder Quelldatei und Umgebung zugeordnet werden.

QuickScan wird wie folgt aufgerufen:

QuickScan CONSENV CODEREF, DATEINAME [, PFAD]

Von der von CODEREF referenzierten Unterroutine wird erwartet, dass sie eine Liste der enthaltenen Dateinamen zurückgibt
direkt per DATEI. Diese Dateinamen werden wiederum gescannt. Das optionale PATH-Argument
Stellt einen Suchpfad zum Suchen von FILENAME und/oder Dateien bereit, die vom Benutzer bereitgestellt wurden
Subroutine. Der PATH kann ein Verweis auf ein Array von Suchverzeichnisnamen oder ein sein
Zeichenfolge von Namen, getrennt durch das Trennzeichen des Systems (':' auf UNIX-Systemen, ';' auf
Windows NT).

Die Unterroutine wird einmal für jede Zeile in der Datei aufgerufen, wobei $_ auf die aktuelle Zeile gesetzt wird.
Wenn die Unterroutine zusätzliche Zeilen oder die gesamte Datei betrachten muss,
dann kann es sie selbst aus dem Dateihandle SCAN lesen. Es kann auch die Schleife beenden, wenn
Durch Schließen des Dateihandles weiß es, dass keine weiteren Include-Informationen verfügbar sind.

Unabhängig davon, ob ein Suchpfad angegeben ist oder nicht, versucht QuickScan zunächst, die Datei zu suchen
relativ zum aktuellen Verzeichnis (für die Datei der obersten Ebene, die direkt an QuickScan bereitgestellt wird),
oder aus dem Verzeichnis, das die Datei enthält, die auf die Datei verwiesen hat. Das ist nicht sehr
allgemein, scheint aber gut genug zu sein – vor allem, wenn Sie den Luxus haben, Ihre eigenen zu schreiben
Dienstprogramme und können die Verwendung des Suchpfads auf standardmäßige Weise steuern. Endlich, das
Der Suchpfad ist derzeit durch Doppelpunkte getrennt. Das dürfte das NT-Lager nicht glücklich machen.

Hier ist ein reales Beispiel, entnommen aus a Konstruieren Datei hier:

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

[BEACHTEN Sie, dass die Form „$env->QuickScan ...“ und „$env->Command ...“ nicht sein sollte
notwendig, aber aus irgendeinem Grund für diesen speziellen Aufruf erforderlich. Dies erscheint
ein Fehler in Perl oder ein Missverständnis meinerseits sein; Bei diesem Aufrufstil ist dies nicht der Fall
scheinen immer notwendig zu sein.]

Dadurch werden alle Namen des Formulars gefunden .smf in der Datei. Es werden die Namen zurückgegeben, auch wenn
Sie werden in Kommentaren gefunden, aber das ist in Ordnung (der Mechanismus verzeiht zusätzliche Dateien;
Sie werden einfach ignoriert, in der Annahme, dass die fehlende Datei bemerkt wird, wenn die
(das Programm, in diesem Beispiel smfgen, wird tatsächlich aufgerufen).

Ein Scanner wird für eine bestimmte Quelldatei nur dann aufgerufen, wenn er von einem Ziel in der Datei benötigt wird
Baum. Es wird immer nur einmal für eine bestimmte Quelldatei aufgerufen.

Hier ist eine andere Möglichkeit, denselben Scanner zu bauen. Dieser verwendet eine explizite Codereferenz,
und liest außerdem (in diesem Fall unnötigerweise) die gesamte Datei selbst:

sub myscan {
mein(@includes);
tun
push(@includes, /\b\S*?\.smf\b/g);
} während ;
@includes
}

Beachten Sie, dass die Reihenfolge der Schleife umgekehrt ist und der Schleifentest am Ende steht. Das ist
denn die erste Zeile ist bereits für Sie vorgelesen. Dieser Scanner kann an eine Quelle angeschlossen werden
Datei von:

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

SUPPORT UND VORSCHLÄGE


Nachteile werden von der Benutzergemeinschaft gepflegt. Um sich anzumelden, senden Sie eine E-Mail an Nachteile-diskutieren-
[E-Mail geschützt] mit Körper Abonnieren.

Bitte melden Sie alle Vorschläge über die [E-Mail geschützt] Mailingliste.

Nutzen Sie Nachteile online mit den Diensten von onworks.net


Kostenlose Server & Workstations

Laden Sie Windows- und Linux-Apps herunter

  • 1
    turkdevops
    turkdevops
    TurkDevOps a�?k kaynak yaz?l?m
    geli?tirici topluluklar? DevTurks-Team
    Taraf?ndan desteklenmektedir..
    Funktionen: https://github.com/turkdevopshttps://turkdevops.g...
    Laden Sie turkdevops herunter
  • 2
    asamdf
    asamdf
    *asammdf* ist ein schneller Python-Parser und
    Redakteur für ASAM (Association for
    Standardisierung von Automatisierung und
    Messsysteme) MDF / MF4
    (Messdatenformat...
    asamdf herunterladen
  • 3
    LAME (Lame Aint an MP3 Encoder)
    LAME (Lame Aint an MP3 Encoder)
    LAME ist ein zu verwendendes Lehrmittel
    zum Erlernen der MP3-Kodierung. Das
    Ziel des LAME-Projekts ist es, sich zu verbessern
    die Psychoakustik, Qualität und Geschwindigkeit
    von Abgeordneten ...
    Laden Sie LAME herunter (Lame Aint an MP3 Encoder)
  • 4
    wxPython
    wxPython
    Eine Reihe von Python-Erweiterungsmodulen, die
    Wrappen Sie die plattformübergreifenden GUI-Klassen aus
    wxWidgets. Zielgruppe: Entwickler. Benutzer
    Schnittstelle: X Window System (X11), Win32 ...
    Laden Sie wxPython herunter
  • 5
    Packdateimanager
    Packdateimanager
    Dies ist der Dateimanager des Total War-Pakets
    Projekt ab Version 1.7. EIN
    kurze Einführung in Warscape
    Modding: ...
    Laden Sie den Packfilemanager herunter
  • 6
    IPerf2
    IPerf2
    Ein Tool zum Messen des Netzwerkverkehrs
    TCP- und UDP-Leistung mit Metriken
    um sowohl den Durchsatz als auch die Latenz. Der
    Zu den Zielen gehört die Aufrechterhaltung eines aktiven Zustands
    Iperf-Kabeljau...
    IPerf2 herunterladen
  • Mehr »

Linux-Befehle

Ad