EngelsFransSpaans

Ad


OnWorks-favicon

nadelen - Online in de cloud

Voer nadelen uit in de gratis hostingprovider van OnWorks via Ubuntu Online, Fedora Online, Windows online emulator of MAC OS online emulator

Dit zijn de nadelen van de opdracht die kunnen worden uitgevoerd in de gratis hostingprovider van OnWorks met behulp van een van onze meerdere gratis online werkstations zoals Ubuntu Online, Fedora Online, Windows online emulator of MAC OS online emulator

PROGRAMMA:

NAAM


Nadelen - Een softwareconstructiesysteem

PRODUCTBESCHRIJVING


Een handleiding en referentie voor versie 2.2.0

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

Dit programma is gratis software; u kunt het opnieuw distribueren en/of wijzigen onder de voorwaarden van:
de GNU General Public License zoals gepubliceerd door de Free Software Foundation; of
versie 2 van de Licentie, of (naar uw keuze) een latere versie.

Dit programma wordt verspreid in de hoop dat het nuttig zal zijn, maar ZONDER ENIGE GARANTIE;
zonder zelfs de impliciete garantie van VERKOOPBAARHEID of GESCHIKTHEID VOOR EEN BEPAALD DOEL.
Zie de GNU General Public License voor meer details.

U zou samen met dit programma een kopie van de GNU General Public License moeten hebben ontvangen;
zie het bestand COPYING. Zo niet, schrijf dan naar de Free Software Foundation, Inc., 59 Temple
Plaats - Suite 330, Boston, MA 02111-1307, VS.

Introductie


NADELEN is een systeem voor het construeren van voornamelijk software, maar verschilt nogal van
eerdere softwareconstructiesystemen. Cons is vanaf de basis ontworpen om te dealen
eenvoudig met de constructie van software verspreid over meerdere bronmappen. Nadelen
maakt het gemakkelijk om build-scripts te maken die eenvoudig, begrijpelijk en onderhoudbaar zijn.
Cons zorgt ervoor dat complexe software eenvoudig en nauwkeurig reproduceerbaar is.

Cons gebruikt een aantal technieken om dit allemaal te bereiken. Bouwscripts zijn gewoon
Perl-scripts, waardoor ze zowel gemakkelijk te begrijpen als zeer flexibel zijn. Mondiale verkenning van
variabelen is vervangen door een import-/exportmechanisme voor het delen van informatie tussen
scripts, waardoor de leesbaarheid en onderhoudbaarheid van elk script aanzienlijk wordt verbeterd.
Bouw omgevingen worden geïntroduceerd: dit zijn Perl-objecten die de
informatie die nodig is voor het besturen van het bouwproces. Er worden meerdere omgevingen gebruikt
wanneer verschillende semantiek vereist is voor het genereren van producten in de bouwboom. Nadelen
implementeert automatische afhankelijkheidsanalyse en gebruikt deze om het geheel globaal te sequencen
bouwen. Variantbuilds kunnen eenvoudig worden geproduceerd vanuit één bronboom. Intelligent gebouwd
subsetting is mogelijk bij het werken aan gelokaliseerde veranderingen. Overschrijvingen kunnen worden ingesteld
overschrijf eenvoudig bouwinstructies zonder scripts te wijzigen. MD5 cryptografisch
handtekeningen zijn gekoppeld aan afgeleide bestanden en worden gebruikt om nauwkeurig te bepalen of
een bepaald bestand moet opnieuw worden opgebouwd.

Hoewel Cons al het bovenstaande en meer biedt, blijft het eenvoudig en gebruiksvriendelijk. Dit zal,
hopelijk wordt dit duidelijk als u de rest van dit document leest.

Waarom nadelen? Waarom niet Maken?


Nadelen zijn een maken vervanging. In de volgende paragrafen bekijken we enkele van de
ongewenste kenmerken van make--en typische bouwomgevingen gebaseerd op make--that
motiveerde de ontwikkeling van Cons.

Bouw ingewikkeldheid

Traditionele, op merken gebaseerde systemen van welke omvang dan ook hebben de neiging behoorlijk complex te worden. Het originele merk
Nut en zijn afgeleiden hebben op een aantal manieren aan deze tendens bijgedragen. Maak het
niet goed in het omgaan met systemen die verspreid zijn over meerdere mappen. Diverse werk-
Arounds worden gebruikt om deze moeilijkheid te overwinnen; de gebruikelijke keuze is om make aan te roepen
zichzelf recursief voor elke submap van een build. Dit leidt tot ingewikkelde code, in
waarbij het vaak onduidelijk is hoe een variabele wordt ingesteld, of welk effect de instelling van een variabele heeft
zal hebben op de bouw als geheel. De make-scripttaal is geleidelijk uitgebreid
om meer mogelijkheden te bieden, maar deze hebben grotendeels gediend om een ​​reeds onoverzichtelijk geheel te maken
overdreven taalgebruik. Vaak worden builds in meerdere passen uitgevoerd om te voorzien
geschikte producten van de ene map naar de andere map. Dit vertegenwoordigt een verdere
toename van de complexiteit van het bouwen.

Bouw reproduceerbaarheid

De vloek van alle merken is altijd de juiste omgang met afhankelijkheden geweest. Meestal is een
Er wordt geprobeerd om op redelijke wijze de afhankelijkheden binnen een enkele directory uit te voeren, maar nee
Er wordt een serieuze poging gedaan om het werk tussen mappen te doen. Zelfs als er afhankelijkheden zijn
correct werkt, vertrouwt u op een eenvoudige tijdstempelvergelijking om te bepalen of
een dossier met betrekking tot zijn personen ten laste is, is daar in het algemeen niet geschikt voor
bepalen wanneer een bestand opnieuw moet worden opgehaald. Als er bijvoorbeeld een externe bibliotheek is
opnieuw opgebouwd en vervolgens op hun plaats ``vastgeklikt'', kunnen de tijdstempels op de nieuw gemaakte bestanden dat wel zijn
het zal wel eerder zijn dan de laatste lokale build, aangezien deze werd gebouwd voordat deze zichtbaar werd.

Variant bouwt

Make biedt slechts beperkte faciliteiten voor het verwerken van variantbuilds. Met de proliferatie
van hardwareplatforms en de behoefte aan debugbare versus geoptimaliseerde code, de mogelijkheid om dat te doen
Het eenvoudig maken van deze varianten is essentieel. Belangrijker nog: als er varianten worden gemaakt, wordt dat ook gedaan
is belangrijk om de varianten te kunnen scheiden of te kunnen reproduceren
origineel of variant naar keuze. Met make is het erg moeilijk om de builds in elkaar te scheiden
meerdere build-mappen, gescheiden van de broncode. En als deze techniek niet wordt gebruikt,
Het is ook vrijwel onmogelijk om op elk moment te garanderen welke variant aanwezig is
de boom, zonder toevlucht te nemen tot een volledige herbouw.

Vindplaatsen

Make biedt slechts beperkte ondersteuning voor het bouwen van software op basis van code die bestaat in een
centrale mapstructuur van de repository. De VPATH-functie van GNU make (en enkele andere
make implementaties) is bedoeld om hierin te voorzien, maar werkt niet zoals verwacht: it
verandert het pad van het doelbestand te vroeg in de analyse naar de VPATH-naam, en daarom
zoekt naar alle afhankelijkheden in de VPATH-directory. Om een ​​correcte ontwikkeling te garanderen
builds, is het belangrijk om een ​​bestand in een lokale build-directory te kunnen maken en
alle bestanden in een coderepository (een VPATH-map, in make-termen) die afhankelijk zijn van de lokale
bestand correct opnieuw opgebouwd. Dit is niet mogelijk met VPATH, zonder veel te coderen
complexe repository-kennis rechtstreeks in de makefiles.

Bewaring it simpel


Een paar van de problemen met make zijn hierboven genoemd. In dit en daarna
secties zullen we de nadelen introduceren en laten zien hoe deze problemen worden aangepakt.

Perl scripts

Nadelen zijn gebaseerd op Perl. Dat wil zeggen, tegens-scripts--Dienstplichtige en Bouwen bestanden, het equivalent
naar Makefile or makefile--zijn allemaal geschreven in Perl. Dit levert direct voordeel op: de
taal voor het schrijven van scripts is bekend. Zelfs als je geen Perl bent
programmeur helpt het om te weten dat Perl in feite slechts een eenvoudige declaratieve taal is,
met een goed gedefinieerde controlestroom en vertrouwde semantiek. Het heeft variabelen die zich gedragen
eigenlijk zoals je zou verwachten, subroutines, controlestroom, enzovoort. Daar
Er is geen speciale syntaxis geïntroduceerd voor Cons. Het gebruik van Perl als scripttaal
vereenvoudigt de taak om de juiste oplossing voor het vaak complexe uit te drukken
vereisten van een constructie.

Hallo, Wereld!

Om de volgende discussie te onderbouwen: hier leest u hoe u de Hallo, Wereld! C
toepassing met nadelen:

$env = nieuwe nadelen();
Programma $env 'hallo', 'hallo.c';

Als u dit script in een map installeert, geeft u het script een naam Bouwenen maak het
hallo.c source-bestand in dezelfde map, dan kun je `cons hello' typen om het
toepassing:

% nadelen hallo
cc -c hallo.c -o hallo.o
cc -o hallo hallo.o

Bouw omgevingen

Een belangrijke vereenvoudiging van Cons is het idee van a bouw milieu. Een constructie
omgeving is een object gekenmerkt door een set sleutel/waarde-paren en een set van werkwijzen.
Om Cons te vertellen hoe je iets moet bouwen, roep je de juiste methode aan via een
passende bouwomgeving. Beschouw het volgende voorbeeld:

$env = nieuwe nadelen(
CC => 'gcc',
LIBS => 'libworld.a'
);

Programma $env 'hallo', 'hallo.c';

In dit geval hebben we niet de standaard bouwomgeving gebruikt, zoals die nu is
de waarde van `CC' overschreven, zodat in plaats daarvan het GNU C Compiler-equivalent wordt gebruikt. Sinds
deze versie van Hallo, Wereld! vereist een bibliotheek, libworld.a, we hebben gespecificeerd dat elk
programma dat in deze omgeving is gekoppeld, moet aan die bibliotheek zijn gekoppeld. Als de bibliotheek
bestaat al, goed en wel, maar als dat niet het geval is, dan moeten we ook de verklaring opnemen:

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

Als u nu `nadelen hallo' typt, wordt de bibliotheek gebouwd voordat het programma wordt gekoppeld, en
uiteraard zal `gcc' worden gebruikt om beide modules te compileren:

% nadelen hallo
gcc -c hallo.c -o hallo.o
gcc -c wereld.c -o wereld.o
ar r libworld.a wereld.o
ar: libworld.a creëren
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

Automatisch en compleet afhankelijkheid analyse

Met Cons worden afhankelijkheden automatisch afgehandeld. Ga verder met het vorige voorbeeld, let op
dat wanneer we wijzigen wereld.c, wereld.o is opnieuw samengesteld, libworld.a opnieuw gemaakt, en hallo
opnieuw gekoppeld:

% vi wereld.c
[EDIT]
% nadelen hallo
gcc -c wereld.c -o wereld.o
ar r libworld.a wereld.o
ar: libworld.a creëren
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

Dit is een relatief eenvoudig voorbeeld: Nadelen ``weet'' wereld.o hangt af van wereld.comdat
de afhankelijkheid wordt expliciet ingesteld door de `Bibliotheek'-methode. Dat weet het ook libworld.a
hangt af van wereld.o en dat hallo hangt af van libworld.a, allemaal om soortgelijke redenen.

Nu blijkt dat hallo.c bevat ook het interfacedefinitiebestand, wereld.h:

% emacs wereld.h
[EDIT]
% nadelen hallo
gcc -c hallo.c -o hallo.o
gcc -o hallo hallo.o libworld.a

Hoe weet Cons dat? hallo.c omvat wereld.hEn dat hallo.o moet dus zijn
opnieuw samengesteld? Voor nu volstaat het om dat te zeggen als we overwegen of het wel of niet het geval is hallo.o is op-
tot nu toe beroept Cons zich op een scanner vanwege zijn afhankelijkheid, hallo.c. Deze scanner somt de
bestanden opgenomen door hallo.c om met een lijst van verdere afhankelijkheden te komen, die verder gaan dan deze
expliciet gemaakt door het Cons-script. Dit proces is recursief: alle bestanden opgenomen door
meegeleverde bestanden worden ook gescand.

Is dit niet duur? Het antwoord is: het hangt ervan af. Als u een volledige build van een groot systeem uitvoert,
de scantijd is onbeduidend. Als je een groot systeem opnieuw opbouwt, zullen Cons dat ook doen
besteed er behoorlijk wat tijd aan om erover na te denken voordat het besluit dat er niets hoeft te gebeuren
gedaan (hoewel niet noodzakelijkerwijs meer tijd dan nodig is!). Het goede nieuws is dat Cons het haalt
het is heel gemakkelijk om uw build op een intelligente manier in te delen, wanneer u aan gelokaliseerde wijzigingen werkt.

Automatisch globaal bouw sequencing

Omdat Cons een volledige en nauwkeurige afhankelijkheidsanalyse uitvoert, en dit wereldwijd, voor de
Tijdens de gehele build kan Cons deze informatie gebruiken om de volledige controle over de sequencing
van de bouw. Deze volgorde is duidelijk zichtbaar in de bovenstaande voorbeelden en is gelijkwaardig aan wat
je zou verwachten van make, gegeven een volledige reeks afhankelijkheden. Met Cons breidt dit zich uit
triviaal tot grotere builds met meerdere mappen. Als gevolg hiervan komt alle complexiteit met zich mee
om ervoor te zorgen dat een build correct is georganiseerd, inclusief hiërarchische meerdere doorgangen
opbouwt – wordt geëlimineerd. We zullen dit in de volgende paragrafen verder bespreken.

Gebouw Groot bomen – nog steeds voor slechts as simpel


A hiërarchie of bouw scripts

Een grotere build, in Cons, wordt georganiseerd door een hiërarchie van te creëren bouw scripts. Op de top
van de boom is een script genaamd Bouwen. De rest van de scripts zijn volgens afspraak elk
Dit betekent dat we onszelf en onze geliefden praktisch vergiftigen. Dienstplichtige. Deze scripts zijn heel eenvoudig met elkaar verbonden door de `Build',
De opdrachten 'Exporteren' en 'Importeren'.

De Bouw commando

Het `Build'-commando neemt een lijst met Dienstplichtige bestandsnamen en zorgt ervoor dat deze worden weergegeven
opgenomen in de bouw. Bijvoorbeeld:

Bouw qw(
chauffeurs/display/dienstplichtige
chauffeurs/muis/dienstplichtige
parser / dienstplichtige
nutsbedrijven / dienstplichtige
);

Dit is een eenvoudige hiërarchie van build-scripts op twee niveaus: alle dochterondernemingen Dienstplichtige bestanden
worden vermeld op het hoogste niveau Bouwen bestand. Merk op dat niet alle mappen in de boom
Er zijn noodzakelijkerwijs build-scripts aan gekoppeld.

Dit kan ook worden geschreven als een script met meerdere niveaus. Bijvoorbeeld de Bouwen bestand zou kunnen
bevatten deze opdracht:

Bouw qw(
parser / dienstplichtige
chauffeurs / dienstplichtige
nutsbedrijven / dienstplichtige
);

en Dienstplichtige bestand in de chauffeurs directory kan dit bevatten:

Bouw qw(
tonen/dienstplichtig
muis / dienstplichtige
);

De ervaring heeft geleerd dat het vorige model iets gemakkelijker te begrijpen is, aangezien de
De hele bouwboom ligt voor je klaar, op het hoogste niveau. Hybride regelingen zijn dat wel
ook mogelijk. Een afzonderlijk onderhouden component die moet worden opgenomen in een
build tree kan bijvoorbeeld op één plek in de build tree aansluiten, maar zijn eigen plek definiëren
bouwhiërarchie.

Standaard verandert Cons de werkmap niet naar de map met a
dochteronderneming Dienstplichtige bestand dat het bevat. Dit gedrag kan worden ingeschakeld voor een build by
specificeren, op het hoogste niveau Bouwen file:

dienstplichtig_chdir 1;

Indien ingeschakeld, veranderen Cons naar de dochteronderneming Dienstplichtige map die het bestand bevat
tijdens het lezen van dat bestand, en ga vervolgens terug naar de map op het hoogste niveau zodra het bestand is geopend
is verwerkt.

Er wordt verwacht dat dit gedrag de standaard zal worden in een toekomstige versie van Cons.
Ter voorbereiding op deze transitie zijn builds nodig die verwachten dat Cons aan de top van de build blijft
terwijl het een dochteronderneming inleest Dienstplichtige bestand moet deze functie expliciet uitschakelen als
volgt:

dienstplichtig_chdir 0;

Familielid, top-familielid, en absoluut filet namen

Het is je misschien opgevallen dat de bestandsnamen die bij de opdracht Build zijn opgegeven, relatief zijn ten opzichte van
de locatie van het script waaruit het wordt aangeroepen. Dit geldt over het algemeen voor andere bestandsnamen
argumenten ook voor andere commando's, hoewel we dat hier net zo goed kunnen vermelden als je begint
een bestandsnaam met een hekje, ``#'', dan wordt dat bestand geïnterpreteerd ten opzichte van de bovenste
niveaumap (waar de Bouwen bestand zich bevindt). En, niet verrassend, als je ermee begint
met ``/'', dan wordt het beschouwd als een absolute padnaam. Dit geldt zelfs voor systemen
die een schuine streep naar achteren gebruiken in plaats van een schuine streep naar voren om absolute paden te benoemen.

gebruik modules in bouw scripts

U kunt in elk modules trekken Dienstplichtige bestand met de normale Perl `use' of `require'
verklaringen:

gebruik Engels;
vereist Mijn::Module;

Elk ‘gebruik’ of ‘vereiste’ heeft alleen invloed op dat ene Dienstplichtige bestand waarin het voorkomt. Om een ​​te gebruiken
module in meerdere Dienstplichtige bestanden, moet u in elk bestand een `use'- of `require'-verklaring plaatsen
één die de module nodig heeft.

strekking of variabelen

Het hoogste niveau Bouwen bestand en al Dienstplichtige bestanden beginnen hun leven in een gemeenschappelijke, afzonderlijke Perl
pakket. NADELEN bestuurt de symbooltabel voor het pakket, zodat de symbooltabel voor
elk script is leeg, behalve de Bouwen bestand, dat een deel van de opdrachtregel overneemt
argumenten. Alle variabelen die worden ingesteld of gebruikt, worden daarom door het script ingesteld
zelf - niet door een extern script.

Variabelen kunnen expliciet zijn geïmporteerd door een script uit het bovenliggende script. Om een
variabel, dat moet het geweest zijn geëxporteerd door de ouder en geïnitialiseerd (anders een fout
zal voorkomen).

De Exporteren commando

Het commando `Exporteren' wordt gebruikt zoals in het volgende voorbeeld:

$env = nieuwe nadelen();
$INCLUDE = "#exporteren/insluiten";
$LIB = "#export/lib";
Exporteer qw( env INCLUDE LIB );
Bouw qw( util/Conscript );

De waarden van de eenvoudige variabelen die in de lijst 'Exporteren' worden genoemd, worden weggesluisd
door eventuele daaropvolgende `Build'-opdrachten. Met het commando `Exporteren' wordt alleen Perl geëxporteerd scalair
variabelen, dat wil zeggen variabelen waarvan de naam begint met `$'. Andere variabelen, objecten, enz.
kan via referentie worden geëxporteerd, maar alle scripts verwijzen naar hetzelfde object, en dit
object moet door de subsidiaire scripts en door het origineel als alleen-lezen worden beschouwd
script exporteren. Het is echter acceptabel om een ​​nieuwe waarde toe te wijzen aan de geëxporteerde scalaire waarde
variabele - dat verandert de onderliggende variabele waarnaar wordt verwezen niet. Deze reeks, voor
is bijvoorbeeld oké:

$env = nieuwe nadelen();
Exporteer qw( env INCLUDE LIB );
Bouw qw( util/Conscript );
$env = nieuwe nadelen(CFLAGS => '-O');
Bouw qw(andere/dienstplichtige);

Het maakt niet uit of de variabele vóór of na het `Export'-commando wordt ingesteld. De
Het belangrijkste is de waarde van de variabele op het moment dat het `Build'-commando wordt uitgevoerd.
Dit is wat weggegooid wordt. Eventuele daaropvolgende `Export'-opdrachten
maak de eerste ongeldig: u moet op elke variabele alle variabelen vermelden die u wilt exporteren
Commando 'Exporteren'.

De import commando

Variabelen die door het commando `Exporteren' worden geëxporteerd, kunnen door de
Commando `Importeren'. Het subsidiaire script importeert variabelen altijd rechtstreeks uit het
superieur schrift. Beschouw dit voorbeeld:

Importeer qw( env INCLUDE );

Dit is alleen legaal als het bovenliggende script zowel `$env' als `$INCLUDE' exporteert. Het moet ook
hebben aan elk van deze variabelen waarden gegeven. Het is prima dat alleen het subscript wordt gebruikt
importeer een subset van de geëxporteerde variabelen (in dit voorbeeld `$LIB', die werd geëxporteerd door
het vorige voorbeeld wordt niet geïmporteerd).

Alle geïmporteerde variabelen worden automatisch opnieuw geëxporteerd, dus de volgorde:

Qw importeren (env INCLUDE);
Bouw qw (onder mij/dienstplichtig);

zal zowel `$env' als `$INCLUDE' aan het subbestand leveren. Als er maar `$env' moet zijn
geëxporteerd, dan is het volgende voldoende:

Qw importeren (env INCLUDE);
qw exporteren (env);
Bouw qw (onder mij/dienstplichtig);

Het is onnodig om te zeggen dat de variabelen lokaal kunnen worden gewijzigd voordat `Build' op het
ondergeschikt script.

Bouw script evaluatie bestellen

De enige beperking voor de volgorde van build-scripts is dat scripts superieur zijn
geëvalueerd vóór hun inferieure scripts. Het hoogste niveau Bouwen bestand is bijvoorbeeld
eerst geëvalueerd, gevolgd door eventuele inferieure scripts. Dit is alles wat je echt moet weten
over de evaluatievolgorde, aangezien de volgorde doorgaans niet relevant is. Stel je de volgende situatie voor
Commando `Bouw':

Bouw qw(
chauffeurs/display/dienstplichtige
chauffeurs/muis/dienstplichtige
parser / dienstplichtige
nutsbedrijven / dienstplichtige
);

We hebben ervoor gekozen om de scriptnamen in alfabetische volgorde te zetten, simpelweg omdat dat het meeste is
handig voor onderhoudsdoeleinden. Het wijzigen van de volgorde zal geen verschil maken voor de
bouwen.

A Model For delen bestanden


sommige simpel conventies

In elk complex softwaresysteem moet er een methode zijn voor het delen van buildproducten
gevestigd. We stellen een eenvoudige reeks conventies voor die triviaal zijn om mee te implementeren
Nadelen, maar zeer effectief.

De basisregel is om te eisen dat iedereen producten bouwt die onderling gedeeld moeten worden
mappen worden gedeeld via een tussenliggende map. Meestal hebben we dit genoemd
exporteren, en, in een C-omgeving, voorzien van conventionele submappen van deze map,
zoals omvatten, lib, bak, Etc.

Deze mappen worden gedefinieerd door het hoogste niveau Bouwen bestand. Een eenvoudige Bouwen bestand voor
a Hallo, Wereld! applicatie, georganiseerd met behulp van meerdere mappen, zou er als volgt uit kunnen zien:

# Constructbestand voor Hallo, wereld!

# Waar we al onze gedeelde producten kunnen plaatsen.
$EXPORT = '#exporteren';

Exporteer qw(CONS INCLUDE LIB BIN);

# Standaardmappen voor het delen van producten.
$INCLUDE = "$EXPORT/include";
$LIB = "$EXPORT/lib";
$BIN = "$EXPORT/bak";

# Een standaard bouwomgeving.
$CONS = nieuwe nadelen (
CPPPATH => $INCLUDE, # Inclusief pad voor C-compilaties
LIBPATH => $LIB, # Bibliotheekpad voor het koppelen van programma's
LIBS => '-lworld', # Lijst met standaardbibliotheken
);

Bouw qw(
hallo / dienstplichtige
wereld/dienstplichtig
);

De wereld directory's Dienstplichtige bestand ziet er zo uit:

# Dienstplichtig bestand voor directorywereld
Importeer qw(CONS INCLUSIEF LIB);

# Installeer de producten van deze map
Installeer $CONS $LIB, 'libworld.a';
Installeer $CONS $INCLUDE, 'world.h';

# Interne producten
Bibliotheek $CONS 'libworld.a', 'world.c';

en hallo directory's Dienstplichtige bestand ziet er zo uit:

# Dienstplichtig bestand voor directory hallo
Importeer qw(CONS BIN);

# Geëxporteerde producten
Installeer $CONS $BIN, 'hallo';

# Interne producten
Programma $CONS 'hallo', 'hallo.c';

om een ​​construct te construeren Hallo, Wereld! programma met deze mapstructuur, ga naar het hoogste niveau
map, en roep `cons' aan met de juiste argumenten. In het volgende voorbeeld hebben wij
vertel Cons om de directory te bouwen exporteren. Om een ​​directory te bouwen, bouwt Cons recursief alles op
bekende producten in die map (uiteraard alleen als ze opnieuw moeten worden opgebouwd). Als een van
die producten afhankelijk zijn van andere producten in andere mappen, dan zullen die worden gebouwd,
ook.

% nadelen export
Installeer world/world.h als export/include/world.h
cc -Iexport/include -c hallo/hallo.c -o hallo/hallo.o
cc -Iexport/include -c wereld/wereld.c -o wereld/wereld.o
ar wereld/libworld.a wereld/wereld.o
ar: wereld/libworld.a creëren
ranlib wereld/libworld.a
Installeer world/libworld.a als export/lib/libworld.a
cc -o hallo/hallo hallo/hallo.o -Lexport/lib -lworld
Installeer hallo/hallo als export/bin/hallo

Schoon, begrijpelijk, locatie-onafhankelijk scripts

Je zult merken dat de twee Dienstplichtige bestanden zijn zeer schoon en to-the-point. Zij eenvoudig
specificeer producten van de directory en hoe deze producten moeten worden gebouwd. De bouwinstructies
zijn minimaal: ze specificeren welke bouwomgeving moet worden gebruikt, de naam van het product,
en de naam van de ingangen. Merk ook op dat de scripts locatie-onafhankelijk zijn: if you
Als u uw bronboom wilt reorganiseren, bent u vrij om dat te doen: u hoeft alleen de
Bouwen -bestand (in dit voorbeeld), om de nieuwe locaties van het Dienstplichtige bestanden. De
het gebruik van een exportboom maakt dit doel eenvoudig.

Merk ook op hoe Cons voor de kleine details zorgt. Al de exporteren mappen, voor
werden bijvoorbeeld automatisch gemaakt. En de geïnstalleerde bestanden waren echt hard gekoppeld aan het
respectieve exportmappen, om ruimte en tijd te besparen. Deze aandacht voor detail bespaart
aanzienlijk werk, en maakt het nog eenvoudiger om eenvoudige, onderhoudbare scripts te produceren.

Scheiden (bron) en bouw bomen


Het is vaak wenselijk om afgeleide bestanden van de build volledig gescheiden te houden van de
bronbestanden. Dit maakt het veel gemakkelijker om bij te houden wat een bronbestand is, en
maakt het ook eenvoudiger te hanteren variant builds, vooral als je de variantbuilds wilt
naast elkaar bestaan.

Scheiden bouw en (bron) directories gebruik de Link commando

Cons biedt een eenvoudig mechanisme dat aan al deze vereisten voldoet. De `Link'
commando wordt aangeroepen zoals in dit voorbeeld:

Link 'build' => 'src';

De opgegeven mappen zijn ``gekoppeld'' aan de opgegeven bronmap. Laten we veronderstellen
dat u een bronmap instelt, src, met de submappen wereld en hallo onder het,
zoals in het vorige voorbeeld. U kunt dan de originele bouwlijnen vervangen door de
volgende:

Bouw qw(
bouwen/wereld/dienstplichtig
bouwen/hallo/dienstplichtig
);

Merk op dat u de Dienstplichtige bestand alsof het in de build-directory bestaat. Nu als
u typt hetzelfde commando als voorheen, u krijgt de volgende resultaten:

% nadelen export
Installeer 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 maken
ranlib build/world/libworld.a
Installeer build/world/libworld.a als export/lib/libworld.a
cc -o build/hello/hello build/hello/hello.o -Lexport/lib -lworld
Installeer build/hello/hello als export/bin/hello

Nogmaals, Cons heeft de details voor u geregeld. Vooral dat merk je allemaal
de builds worden uitgevoerd met behulp van bronbestanden en objectbestanden uit de build-directory. Voor
voorbeeld, bouwen/wereld/wereld.o is samengesteld uit build/wereld/wereld.c en
export/include/world.h is geïnstalleerd vanaf build/wereld/wereld.h. Bij de meeste is dit gelukt
systemen door het simpele hulpmiddel van het ``hard'' koppelen van de vereiste bestanden van elke bron
map naar de juiste buildmap.

De links worden correct onderhouden door Cons, ongeacht wat u met de bronmap doet.
Als u een bronbestand wijzigt, kan uw redacteur dit 'ter plekke' doen of de naam ervan wijzigen
eerst en maak een nieuw bestand. In het laatste geval gaat elke harde link verloren. Nadelen zullen
detecteert deze toestand de volgende keer dat het bronbestand nodig is, en zal het opnieuw koppelen
op gepaste wijze.

Dat merk je trouwens ook geen Er waren veranderingen nodig aan de onderliggende waarde Dienstplichtige
bestanden. En we kunnen nog verder gaan, zoals we in de volgende sectie zullen zien.

Variant bouwt


Hallo, Wereld! For banaan en perzik besturingssystemen

Variantbuilds vereisen slechts een eenvoudige uitbreiding. Laten we als voorbeeld a nemen
vereiste om builds toe te staan ​​voor zowel de baNaNa- als de peAcH-besturingssystemen. In dit geval,
we gebruiken een gedistribueerd bestandssysteem, zoals NFS om toegang te krijgen tot het specifieke systeem, en
voor een bepaalde aanroep hoeft slechts het ene of het andere systeem te worden gecompileerd
`nadelen'. Hier is een manier waarop we de Bouwen bestand voor onze Hallo, Wereld!
toepassing:

# Constructbestand voor Hallo, wereld!

die qq(OS moet worden opgegeven) tenzij $OS = $ARG{OS};
die qq(OS moet "perzik" of "banaan" zijn)
if $OS ne "perzik" && $OS ne "banaan";

# Waar we al onze gedeelde producten kunnen plaatsen.
$EXPORT = "#export/$OS";

Exporteer qw(CONS INCLUDE LIB BIN);

# Standaardmappen voor het delen van producten.
$INCLUDE = "$EXPORT/include";
$LIB = "$EXPORT/lib";
$BIN = "$EXPORT/bak";

# Een standaard bouwomgeving.
$CONS = nieuwe nadelen (
CPPPATH => $INCLUDE, # Inclusief pad voor C-compilaties
LIBPATH => $LIB, # Bibliotheekpad voor het koppelen van programma's
LIBS => '-lworld', # Lijst met standaardbibliotheken
);

# $BUILD is waar we alles uit zullen halen.
$BUILD = "#build/$OS";

# Vertel de nadelen waar de bronbestanden voor $BUILD zijn.
Link $BUILD => 'src';

Bouwen (
"$BUILD/hallo/dienstplichtig",
"$BUILD/wereld/Dienstplichtige",
);

Als we nu inloggen op een peAcH-systeem, kunnen we ons Hallo, Wereld! daarvoor een aanvraag indienen
platform:

% nadelen export OS=perzik
Installeer 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 maken
ranlib build/peach/world/libworld.a
Installeer 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
Installeer build/peach/hello/hello als export/peach/bin/hello

Variaties on a thema

Andere varianten van dit model zijn mogelijk. U kunt bijvoorbeeld besluiten dat u dat wilt
om uw include-bestanden op te delen in platformafhankelijke en platformonafhankelijke bestanden.
In dit geval zou u een alternatief voor `$INCLUDE' moeten definiëren voor platformafhankelijk
bestanden. Meest Dienstplichtige bestanden, die puur platform-onafhankelijke include-bestanden genereren, zouden dat wel doen
hoeft niet te veranderen.

Misschien wilt u ook uw hele systeem kunnen compileren met foutopsporing of profilering,
bijvoorbeeld ingeschakeld. U kunt dit doen met de juiste opdrachtregelopties, zoals
`DEBUG=aan'. Dit wordt dan vertaald naar het juiste platformspecifieke
vereisten om foutopsporing in te schakelen (dit kan het uitschakelen van optimalisatie omvatten, bijvoorbeeld
voorbeeld). U kunt optioneel de naamruimte variëren voor deze verschillende soorten systemen,
maar zoals we in het volgende gedeelte zullen zien, is dat niet het geval essentieel om dit te doen, aangezien Cons mooi is
slim in het opnieuw opbouwen van dingen als je van optie verandert.

handtekeningen


MD5 cryptografische handtekeningen

Telkens wanneer Cons een afgeleid bestand maakt, slaat het een handtekening voor dat bestand. De handtekening
wordt opgeslagen in een apart bestand, één per map. Nadat het vorige voorbeeld was samengesteld,
de .verzenden bestand in de bouwen/perzik/wereld map zag er als volgt uit:

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

Het eerste getal is een tijdstempel; voor UNIX-systemen is dit doorgaans het getal van
seconden sinds 1 januari 1970. De tweede waarde is een MD5-controlesom. De Bericht Verteren
Algoritme is een algoritme dat, gegeven een invoerreeks, een sterke cryptografie berekent
handtekening voor die string. De MD5-controlesom opgeslagen in het .verzenden bestand is in feite een
samenvatting van alle afhankelijkheidsinformatie voor het opgegeven bestand. Dus bijvoorbeeld voor de
wereld.o bestand, dit omvat in ieder geval de wereld.c bestand, en ook alle headerbestanden die Cons
daarvan op de hoogte is, worden er direct of indirect door opgenomen wereld.c. Niet alleen dat, maar de
daadwerkelijke opdrachtregel die werd gebruikt om te genereren wereld.o wordt ook meegenomen in de berekening van
de handtekening. Op dezelfde manier, libworld.a krijgt een handtekening die alle 'bevat'
handtekeningen van zijn kiezers (en dus, transitief, de handtekeningen van hun
bestanddelen), evenals de opdrachtregel waarmee het bestand is gemaakt.

De handtekening van een niet-afgeleid bestand wordt standaard berekend door het huidige bestand te nemen
wijzigingstijd van het bestand en de invoernaam van het bestand (tenzij er toevallig een
actueel .verzenden invoer voor dat bestand, in welk geval die handtekening wordt gebruikt).

Merk op dat het niet nodig is dat een afgeleid bestand afhankelijk is van een bepaald bestand Bouwen or
Dienstplichtige bestand - als wijzigingen in deze bestanden van invloed zijn op het betreffende bestand, dan is dit het geval
automatisch weerspiegeld in de handtekening, aangezien relevante delen van de opdrachtregel dat wel zijn
opgenomen in de handtekening. Niet-gerelateerde wijzigingen hebben geen effect.

Wanneer Cons overweegt of een bepaald bestand moet worden afgeleid, berekent het eerst de
verwachte handtekening van het bestand. Vervolgens vergelijkt het de laatste wijzigingstijd van het bestand met
de tijd geregistreerd in de .verzenden invoeren, als die bestaat. Als deze tijden overeenkomen, dan is de
handtekening opgeslagen in de .verzenden bestand wordt als accuraat beschouwd. Als het bestand een vorig bestand is
handtekening niet overeenkomt met de nieuwe, verwachte handtekening, dan moet het bestand opnieuw worden afgeleid.

Merk op dat een bestand opnieuw wordt afgeleid wanneer er iets aan een afhankelijk bestand verandert. In
let daar vooral op elke wijzigen naar het wijzigingstijdstip van een afhankelijke (vooruit of
terug in de tijd) zal hercompilatie van het afgeleide bestand forceren.

Het gebruik van deze handtekeningen is een uiterst eenvoudige, efficiënte en effectieve methode
het dramatisch verbeteren van de reproduceerbaarheid van een systeem.

We zullen dit aantonen met een eenvoudig voorbeeld:

# Eenvoudig "Hallo, wereld!" Bestand samenstellen
$CFLAGS = '-g' als $ARG{DEBUG} eq 'aan';
$CONS = nieuwe nadelen(CFLAGS => $CFLAGS);
Programma $CONS 'hallo', 'hallo.c';

Merk op hoe Cons op de juiste momenten opnieuw compileert:

% nadelen hallo
cc -c hallo.c -o hallo.o
cc -o hallo hallo.o
% nadelen hallo
nadelen: "hallo" is up-to-date.
% nadelen DEBUG=op hallo
cc -g -c hallo.c -o hallo.o
cc -o hallo hallo.o
% nadelen DEBUG=op hallo
nadelen: "hallo" is up-to-date.
% nadelen hallo
cc -c hallo.c -o hallo.o
cc -o hallo hallo.o

Code Vindplaatsen


Veel softwareontwikkelingsorganisaties hebben een of meer centrale repositorydirectory's
bomen die de huidige broncode voor een of meer projecten bevatten, evenals de daarvan afgeleide code
objectbestanden, bibliotheken en uitvoerbare bestanden. Om onnodige hercompilatie te voorkomen,
het is handig om bestanden uit de repository te gebruiken om ontwikkelingssoftware te bouwen, ervan uitgaande dat
natuurlijk dat er geen nieuwer afhankelijkheidsbestand bestaat in de lokale buildboom.

bewaarplaats

Cons biedt een mechanisme om een ​​lijst met codeopslagplaatsen op te geven die zullen worden doorzocht,
in de juiste volgorde, voor bronbestanden en afgeleide bestanden die niet in de lokale build-directoryboom voorkomen.

De volgende regels in a Bouwen bestand zal Cons instrueren om eerst onder de
/usr/experiment/repository map en vervolgens onder de /usr/product/repository directory:

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

De opgegeven repositorymappen kunnen bronbestanden, afgeleide bestanden (objecten,
bibliotheken en uitvoerbare bestanden), of beide. Als er geen lokaal bestand (bron of afgeleid) onder staat
de directory waarin Cons wordt uitgevoerd, waarna het eerste exemplaar van een gelijknamig bestand wordt gevonden
onder een repositorymap zal worden gebruikt om lokaal afgeleide bestanden te bouwen.

Cons onderhoudt één globale lijst met repositorydirectory's. Nadelen zullen de
huidige map en eventuele niet-bestaande mappen uit de lijst.

Het vinden van de Bouwen filet in a bewaarplaats

Nadelen zullen ook zoeken naar Bouwen en Dienstplichtige bestanden in de repositoryboom of -bomen.
Dit leidt echter tot een kip-en-ei-situatie: hoe zie je eruit in een repositoryboom
voor een Bouwen bestand als de Bouwen bestand vertelt u waar de repository is? Krijgen
hieromheen kunnen repositories worden opgegeven via `-R' opties op de opdrachtregel:

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

Alle repositorymappen die zijn opgegeven in het Bouwen or Dienstplichtige bestanden worden toegevoegd
naar de repositorymappen gespecificeerd door de `-R'-opties op de opdrachtregel.

bewaarplaats (bron) bestanden

Als de broncode (inclusief de Dienstplichtige bestand) voor de bibliotheekversie van het Hallo,
Wereld! C-applicatie bevindt zich in een repository (zonder afgeleide bestanden), Cons zal de
bronbestanden uit de repository om de lokale objectbestanden en het uitvoerbare bestand te maken:

% nadelen -R /usr/src_only/repository hallo
gcc -c /usr/src_only/repository/hello.c -o hallo.o
gcc -c /usr/src_only/repository/world.c -o wereld.o
ar r libworld.a wereld.o
ar: libworld.a creëren
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

Door een lokaal bronbestand te maken, zal Cons het juiste afgeleide bestand opnieuw opbouwen of
bestanden:

% pico wereld.c
[EDIT]
% nadelen -R /usr/src_only/repository hallo
gcc -c wereld.c -o wereld.o
ar r libworld.a wereld.o
ar: libworld.a creëren
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

En als u het lokale bronbestand verwijdert, keert Cons terug naar het bouwen van het afgeleide bestand
bestanden uit de repositorybron:

% rm wereld.c
% nadelen -R /usr/src_only/repository hallo
gcc -c /usr/src_only/repository/world.c -o wereld.o
ar r libworld.a wereld.o
ar: libworld.a creëren
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

bewaarplaats afgeleide bestanden

Als een repositorystructuur afgeleide bestanden bevat (meestal objectbestanden, bibliotheken of
uitvoerbare bestanden), zal Cons de normale handtekeningberekening uitvoeren om te beslissen of de
het repositorybestand is up-to-date of er moet lokaal een afgeleid bestand worden gebouwd. Dit betekent dat,
Om een ​​correcte handtekeningberekening te garanderen, moet een repositoryboom ook de
.verzenden bestanden die door Cons zijn gemaakt bij het genereren van de afgeleide bestanden.

Dit wordt doorgaans bereikt door de software in de repository te bouwen (of,
alternatief, in een build-directory en vervolgens het resultaat naar de repository kopiëren):

% cd /usr/all/repository
% nadelen hallo
gcc -c hallo.c -o hallo.o
gcc -c wereld.c -o wereld.o
ar r libworld.a wereld.o
ar: libworld.a creëren
ranlib libworld.a
gcc -o hallo hallo.o libworld.a

(Dit is veilig, zelfs als de Bouwen bestand vermeldt de /usr/all/repository map in een
Het commando `Repository' omdat Cons de huidige map uit de repository zal verwijderen
lijst.)

Als we nu een kopie van de applicatie willen bouwen met onze eigen applicatie hallo.c bestand, we hebben alleen nodig
om het ene noodzakelijke bronbestand te maken, en gebruik de optie `-R' om Cons andere te laten gebruiken
bestanden uit de repository:

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

Merk op dat Cons niet de moeite heeft genomen om een ​​local opnieuw te creëren libworld.a bibliotheek (of compileer de
wereld.o module), maar gebruikt in plaats daarvan de reeds gecompileerde versie uit de repository.

Omdat de MD5-handtekeningen die Cons in de .verzenden bestand bevat tijdstempels voor de
afgeleide bestanden, moeten de tijdstempels van de handtekening overeenkomen met de tijdstempels van het bestand voor een handtekening
als geldig worden beschouwd.

Sommige softwaresystemen kunnen de tijdstempels op repositorybestanden wijzigen (door ze te kopiëren,
bijv.), in welk geval Cons standaard zal aannemen dat de handtekeningen van de repository ongeldig zijn
en bestanden onnodig opnieuw opbouwen. Dit gedrag kan worden gewijzigd door het volgende op te geven:

Repository_Sig_Times_OK 0;

Dit vertelt Cons om tijdstempels te negeren bij het beslissen of een handtekening geldig is. (Opmerking
dat het vermijden van deze sanity check betekent dat er een goede controle over de repository moet zijn
boom om ervoor te zorgen dat de afgeleide bestanden niet kunnen worden gewijzigd zonder de .verzenden
handtekening.)

Lokale kopieën of bestanden

Als de repositoryboom de volledige resultaten van een build bevat, en we proberen van daaruit te bouwen
de repository zonder enige bestanden in onze lokale boom, iets redelijk verrassend
gebeurt:

% mkdir $HOME/build2
% cd $HOME/build2
% nadelen -R /usr/all/repository hallo
nadelen: "hallo" is up-to-date.

Waarom zegt Cons dat de hallo programma is up-to-date als er geen is hallo programma in
de lokale buildmap? Omdat de repository (niet de lokale map) de
up-to-date hallo programma, en Cons stelt correct vast dat er niets aan hoeft te worden gedaan
bouw deze bijgewerkte kopie van het bestand opnieuw op.

Er zijn echter vele gevallen waarin het passend is ervoor te zorgen dat een lokale kopie van een
bestand bestaat altijd. Een verpakkings- of testscript kan daar bijvoorbeeld van uitgaan
gegenereerde bestanden bestaan ​​lokaal. In plaats van deze subscripts bewust te maken van de
repository directory, kan het commando `Local' worden toegevoegd aan a Bouwen or Dienstplichtige bestand naar
specificeer dat een bepaald bestand of bepaalde bestanden in de lokale build-directory moeten verschijnen:

Lokale qw(
hallo
);

Als we vervolgens dezelfde opdracht opnieuw uitvoeren, zal Cons een lokale kopie van het programma maken vanuit het
repository-kopie (waarin u wordt verteld dat dit gebeurt):

% nadelen -R /usr/all/repository hallo
Lokale kopie van hello uit /usr/all/repository/hello
nadelen: "hallo" is up-to-date.

Merk op dat, omdat het maken van de lokale kopie niet wordt beschouwd als een "build" van het
hallo bestand meldt Cons nog steeds dat het up-to-date is.

Het maken van lokale kopieën is vooral handig voor bestanden die worden geïnstalleerd in een
tussenliggende map (om te delen met andere mappen) via het `Install'-commando.
Het begeleiden van het `Install'-commando voor een bestand met het begeleidende `Local'-commando is zo
Het is gebruikelijk dat Cons een `Install_Local'-opdracht levert als een handige manier om beide te doen:

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

is precies gelijk aan:

Installeer $env '#export', 'hallo';
Lokaal '#export/hallo';

Zowel de opdrachten `Local' als `Install_Local' werken het lokale bestand bij .verzenden bestand met de
juiste bestandshandtekeningen, zodat toekomstige builds correct worden uitgevoerd.

bewaarplaats afhankelijkheid analyse

Dankzij de ingebouwde scanfunctie zoekt Cons naar de opgegeven repositorybomen
.h bestanden. Tenzij de compiler ook op de hoogte is van de repositorybomen, zal dit wel het geval zijn
kan niet vinden .h bestanden die alleen in een repository bestaan. Als bijvoorbeeld de hallo.c
bestand bevat de hallo.h bestand in de huidige map:

% nadelen -R /usr/all/repository hallo
gcc -c /usr/all/repository/hello.c -o hallo.o
/usr/all/repository/hello.c:1: hello.h: Een dergelijk bestand of map bestaat niet

Het oplossen van dit probleem stelt een aantal eisen aan de manier waarop bouwomgevingen zijn
gedefinieerd en op de manier waarop de preprocessorrichtlijn C `#include' wordt gebruikt om bestanden op te nemen.

Om de compiler te informeren over de repositorybomen, zal Cons de juiste `-I' toevoegen
vlaggen voor de compilatieopdrachten. Dit betekent dat de variabele `CPPPATH' in de
construct-omgeving moet expliciet alle submappen specificeren waarin moet worden gezocht
voor opgenomen bestanden, inclusief de huidige map. Daarom kunnen we het bovenstaande oplossen
bijvoorbeeld door het veranderen van de omgevingscreatie in de Bouwen bestand als volgt:

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

Vanwege de definitie van de `CPPPATH'-variabele levert dit op, wanneer we de
opdracht:

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

De volgorde van de `-I'-vlaggen repliceert voor de C-preprocessor dezelfde repository-
directoryzoekpad dat Cons gebruikt voor zijn eigen afhankelijkheidsanalyse. Als er zijn
meerdere repositories en meerdere `CPPPATH'-mappen, Cons zal de repository toevoegen
mappen naar het begin van elke `CPPPATH'-map, waardoor het aantal snel wordt vermenigvuldigd
van '-I'-vlaggen. Als extreem voorbeeld: a Bouwen bestand met:

Opslagplaats qw(
/u1
/u2
);

$env = nieuwe nadelen(
CPPPATH => 'a:b:c',
);

Zou een compilatieopdracht opleveren van:

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

Omdat Cons afhankelijk is van de `-I'-vlaggen van de compiler om de volgorde door te geven
repository-mappen moeten worden doorzocht, de manier waarop Cons met repository-mappen omgaat is dat
fundamenteel onverenigbaar met het gebruik van dubbele aanhalingstekens in de `#include'-richtlijnen in uw C
broncode:

#include "file.h" /* GEBRUIK GEEN DUBBELE QUOTES ZOALS DIT */

Dit komt omdat de meeste C-preprocessors, wanneer ze met een dergelijke richtlijn worden geconfronteerd, altijd als eerste zullen optreden
doorzoek de map die het bronbestand bevat. Dit ondermijnt de uitgebreide ‘-ik’
opties die Cons construeert om de preprocessor te laten voldoen aan de gewenste zoekopdracht
pad.

Bijgevolg, bij het gebruik van repositorybomen in Cons, altijd gebruik hoekbeugels voor meegeleverd
bestanden:

#erbij betrekken /* GEBRUIK IN PLAATS VAN HOEKBEUGELS */

Repository_Lijst

Cons biedt een opdracht `Repository_List' om een ​​lijst met alle repositorymappen terug te geven
in hun huidige zoekvolgorde. Dit kan worden gebruikt voor het debuggen of om complexere Perl uit te voeren
spullen:

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

bewaarplaats wisselwerking Met anders NADELEN functionaliteiten

De manier waarop Cons met repositorybomen omgaat, werkt correct samen met andere Cons-functies, namelijk
om te zeggen: het doet over het algemeen wat je zou verwachten.

Het meest opvallend is dat repositorybomen correct en tamelijk krachtig samenwerken met de 'Link'
commando. Een repositoryboom kan een of meer submappen bevatten voor versiebuilds
tot stand gebracht via `Link' naar een bronsubmap. Cons zal zoeken naar afgeleide bestanden in
de juiste build-submappen onder de repositoryboom.

Standaard doelen


Tot nu toe hebben we gedemonstreerd dat we Cons aanroepen met een expliciet doel om te bouwen:

% nadelen hallo

Normaal gesproken bouwt Cons niets, tenzij er een doel is gespecificeerd, maar met '.'
(de huidige map) zal alles bouwen:

% nadelen # bouwt niets

% nadelen. # bouwt alles onder de map op het hoogste niveau

Het toevoegen van de `Default'-methode aan elk Bouwen or Dienstplichtige bestand voegt het opgegeven
doelen toevoegen aan een lijst met standaarddoelen. Tegens zullen deze standaardinstellingen opbouwen als die er niet zijn
doelen die zijn opgegeven op de opdrachtregel. Dus voeg de volgende regel toe aan het hoogste niveau
Bouwen bestand zal het typische gedrag van Make nabootsen waarbij alles standaard wordt gebouwd:

Standaard '.';

Het volgende zou de hallo en Vaarwel commando's (in dezelfde map als de
Bouwen or Dienstplichtige bestand) naar de standaardlijst:

Standaard qw(
hallo
Vaarwel
);

De `Default'-methode kan meerdere keren worden gebruikt om doelen aan de standaardlijst toe te voegen.

Selectief bouwt


Cons biedt twee methoden om de grootte van een bepaalde build te verkleinen. De eerste is door te specificeren
targets op de opdrachtregel, en de tweede is een methode voor het snoeien van de build-boom. Goed
denk eerst na over de doelspecificatie.

Selectief targeting

Net als make staat Cons de specificatie van ``targets'' op de opdrachtregel toe. Nadelen doelstellingen
kunnen bestanden of mappen zijn. Wanneer een map is opgegeven, is dit eenvoudigweg een korte-
handnotatie voor elk afleidbaar product – waar Cons van op de hoogte is – in het gespecificeerde
map en hieronder. Bijvoorbeeld:

% nadelen build/hello/hello.o

betekent bouwen hallo.o en alles wat hallo.o zou nodig kunnen hebben. Dit is van een vorige
versie van de Hallo, Wereld! programma waarin hallo.o Afhangen van
export/include/world.h. Als dat bestand niet up-to-date is (omdat iemand het heeft gewijzigd
src/wereld/wereld.h), dan wordt het opnieuw opgebouwd, ook al bevindt het zich in een map op afstand
bouwen/hallo.

In dit voorbeeld:

% nadelen bouwen

Alles in de bouw map wordt indien nodig opgebouwd. Nogmaals, dit kan meer bestanden veroorzaken
om gebouwd te worden. In het bijzonder beide export/include/world.h en export/lib/libworld.a zijn
vereist door de bouwen/hallo directory, en dus zullen ze worden gebouwd als ze verouderd zijn.

Als we dat doen, in plaats daarvan:

% nadelen export

dan worden alleen de bestanden die in de exportmap moeten worden geïnstalleerd opnieuw opgebouwd, als
nodig, en vervolgens daar geïnstalleerd. Merk op dat `cons build' bestanden kan bouwen die `cons
export' bouwt niet op, en omgekeerd.

Nee ``speciaal'' doelen

Met Cons zijn 'speciale' doelen in de vorm van een stijl niet vereist. De eenvoudigste analoog met Cons
is speciaal te gebruiken exporteren mappen, in plaats daarvan. Stel dat u bijvoorbeeld een
hele reeks unit-tests die aan uw code zijn gekoppeld. De tests wonen in de
bronmap in de buurt van de code. Normaal gesproken wilt u deze tests echter niet bouwen.
Eén oplossing is om alle bouwinstructies voor het maken van de tests te verstrekken, en deze vervolgens te gebruiken
installeer de tests in een apart deel van de boom. Als we de tests op een topniveau installeren
directory gebeld testen, Dan:

% nadelen testen

zal alle tests bouwen.

% nadelen export

bouwt de productieversie van het systeem (maar niet de tests), en:

% nadelen bouwen

moet waarschijnlijk worden vermeden (aangezien het onnodig tests zal compileren).

Als u slechts één enkele test wilt bouwen, kunt u de test expliciet een naam geven (in
hetzij de testen map of de bouw map). Je kunt de tests ook samenvoegen
in een handige hiërarchie binnen de testdirectory. Deze hiërarchie hoeft niet
noodzakelijkerwijs overeenkomen met de bronhiërarchie, op vrijwel dezelfde manier als de include-hiërarchie
komt waarschijnlijk niet overeen met de bronhiërarchie (het is onwaarschijnlijk dat de include-hiërarchie groter is
dan twee niveaus diep, voor C-programma's).

Als je absoluut alles in de boom wilt bouwen (afhankelijk van de opties die je hebt).
selecteren), kunt u gebruik maken van:

% nadelen.

Dit is niet bijzonder efficiënt, omdat het onnodig door alle bomen zal lopen,
inclusief de bronboom. De bronboom kan uiteraard bouwbare objecten bevatten
it--niets houdt je tegen om dit te doen, zelfs als je normaal gesproken een aparte build inbouwt
boom.

Bouw Snoeien


In combinatie met doelselectie, bouw snoeien kan worden gebruikt om de reikwijdte van de maatregel te verkleinen
bouwen. In het vorige peAcH- en baNaNa-voorbeeld hebben we al gezien hoe scriptgestuurd
build-snoei kan worden gebruikt om slechts de helft van de potentiële build voor een bepaald gegeven beschikbaar te maken
aanroeping van 'tegens'. Cons biedt, voor het gemak, ook een opdrachtregelconventie
kunt u opgeven welke Dienstplichtige bestanden worden daadwerkelijk ``gebouwd'', dat wil zeggen, opgenomen
in de bouwboom. Bijvoorbeeld:

% nadelen bouwen +wereld

Het argument `+' introduceert een reguliere Perl-expressie. Dit moet uiteraard worden geciteerd op
het shell-niveau als er shell-metatekens in de expressie voorkomen. De
expressie wordt met elkaar vergeleken Dienstplichtige bestand dat is vermeld in een `Build'
statement, en alleen die scripts met overeenkomende namen worden daadwerkelijk opgenomen in de
boom bouwen. Meerdere van dergelijke argumenten zijn toegestaan, in welk geval een match met een van deze argumenten mogelijk is
is voldoende om ervoor te zorgen dat er een script wordt opgenomen.

In het bovenstaande voorbeeld is de hallo programma zal niet worden gebouwd, omdat Cons geen zal hebben
kennis van het schrift hallo / dienstplichtige. De libworld.a archief zal echter worden gebouwd als
hoeft te zijn.

Er zijn een aantal toepassingen voor het snoeien van builds via de opdrachtregel. Misschien wel het nuttigst
is het vermogen om lokale veranderingen door te voeren, en dan, met voldoende kennis van de
gevolgen van die veranderingen, beperk de grootte van de bouwboom om te versnellen
de wederopbouwtijd. Een tweede toepassing van build-snoei is het actief voorkomen van hercompilatie
van bepaalde bestanden waarvan u weet dat ze opnieuw zullen worden gecompileerd vanwege bijvoorbeeld een gewijzigd headerbestand.
U weet wellicht dat de wijzigingen in het headerbestand niet van belang zijn, of dat de
wijzigingen kunnen voor testdoeleinden voor het grootste deel van de boom veilig worden genegeerd
De visie is dat het pragmatisch is om dit soort gedrag toe te laten, met dien verstande dat
bij de volgende volledige build zal alles dat opnieuw moet worden opgebouwd, zijn. Er is geen equivalent
tot een ``make touch''-opdracht, om bestanden als permanent up-to-date te markeren. Dus welk risico dan ook
De kosten die voortvloeien uit het snoeien van gebouwen worden verzacht. Voor werk van releasekwaliteit raden we uiteraard aan
dat u geen build-pruning gebruikt (het is prima om tijdens de integratie te gebruiken, maar
voor het controleren van de compilatie, enz. Zorg er wel voor dat u een onbeperkte build uitvoert voordat u een commit maakt
de integratie).

tijdelijk overschrijvingen


Cons biedt een heel eenvoudig mechanisme voor het overschrijven van aspecten van een build. De essentie is
dat u een override-bestand schrijft dat een of meer `Override'-opdrachten bevat, en u
specificeer dit op de opdrachtregel, wanneer u `cons' uitvoert:

% nadelen -o ten opzichte van export

zal de bouwen exporteren map, waarbij alle afgeleide bestanden onderworpen zijn aan de aanwezige overschrijvingen
in de over bestand. Als je de `-o' optie weglaat, dan moet al het nodige verwijderd worden
alle overschrijvingen worden opnieuw opgebouwd.

Dwingend milieu variabelen

Het overschrijvingsbestand kan twee soorten overschrijvingen bevatten. De eerste is de inkomende omgeving
variabelen. Deze zijn normaal gesproken toegankelijk via de Bouwen bestand van de `%ENV'-hash
variabel. Deze kunnen triviaal worden overschreven in het override-bestand door de
geschikte elementen van `%ENV' (deze kunnen ook worden overschreven in de gebruikersomgeving,
natuurlijk).

De Override commando

Het tweede type overschrijving wordt bereikt met het commando `Overschrijven', dat er zo uitziet
deze:

Overschrijven , => , => , ...;

De reguliere expressie regexp wordt vergeleken met elk afgeleid bestand dat in aanmerking komt
voor de bouw. Als het afgeleide bestand overeenkomt, worden de variabelen/waarde-paren gebruikt
overschrijven de waarden in de constructieomgeving die aan het afgeleide bestand zijn gekoppeld.

Laten we aannemen dat we een bouwomgeving als deze hebben:

$CONS = nieuwe nadelen(
COPT => '',
CDBG => '-g',
CFLAGS => '%COPT %CDBG',
);

Als we dan een overschrijvingsbestand hebben over met daarin deze opdracht:

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

dan elke `cons'-aanroep met `-o over' die creëert .o bestanden via deze omgeving wel
zorgen ervoor dat ze worden gecompileerd met `-O 'en geen `-g'. Overschrijven zou natuurlijk kunnen
beperkt tot een enkele map door de juiste selectie van een reguliere expressie.

Hier is de originele versie van de Hello, World! programma, gebouwd met deze omgeving.
Merk op dat Cons de juiste stukken opnieuw opbouwt wanneer de override wordt toegepast of verwijderd:

% nadelen hallo
cc -g -c hallo.c -o hallo.o
cc -o hallo hallo.o
% nadelen -o meer dan hallo
cc -O -c hallo.c -o hallo.o
cc -o hallo hallo.o
% nadelen -o meer dan hallo
nadelen: "hallo" is up-to-date.
% nadelen hallo
cc -g -c hallo.c -o hallo.o
cc -o hallo hallo.o

Het is belangrijk dat het `Override'-commando alleen tijdelijk wordt gebruikt
overschrijvingen die nodig zijn voor ontwikkeling omdat de overschrijvingen niet platformonafhankelijk zijn en
omdat ze te veel vertrouwen op grondige kennis van de werking van de scripts. Voor
tijdelijk gebruik, maar ze zijn precies wat u zoekt.

Merk op dat het nog steeds nuttig is om bijvoorbeeld de mogelijkheid te bieden om een ​​volledig geoptimaliseerde versie te maken
versie van een systeem voor productiegebruik - van de Bouwen en Dienstplichtige bestanden. Deze kant op
u kunt het geoptimaliseerde systeem afstemmen op het platform. Waar er afwegingen tussen optimalisaties moeten worden gemaakt
gemaakt (bepaalde bestanden worden bijvoorbeeld niet volledig geoptimaliseerd) dan
deze kunnen rechtstreeks in de scripts worden vastgelegd voor het nageslacht (en voor reproduceerbaarheid).

Meer on bouw omgevingen


Standaard bouw variabelen

We hebben het concept van a genoemd en gebruikt bouw milieu, vele malen in de
voorgaande pagina's. Nu is het tijd om dit wat concreter te maken. Met het volgende
uitspraak:

$env = nieuwe nadelen();

er wordt een verwijzing naar een nieuwe, standaard bouwomgeving gecreëerd. Hierin staat een nummer
van constructievariabelen en enkele methoden. Op dit moment is de standaardlijst van
constructievariabelen wordt als volgt gedefinieerd:

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 => 'zoals',
ASFLAGS => '',
ASCOM => '%AS %ASFLAGS %< -o %>',
LD => 'ld',
LDFLAGS => '',
PREFLIB => 'lib',
SUFLIB => '.a',
SUFLIBS => '.dus:.a',
SUFOBJ => '.o',
ENV => { 'PAD' => '/ bin:/ Usr / bin'},

Op Win32-systemen (Windows NT) worden de volgende constructievariabelen overschreven in het
default:

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',

Deze variabelen worden gebruikt door de verschillende methoden die verband houden met de omgeving, in
met name elke methode die uiteindelijk een extern commando aanroept, zal deze vervangen
variabelen in de uiteindelijke opdracht, indien van toepassing. De methode `Objects' gebruikt bijvoorbeeld
een aantal bronbestanden en zorgt ervoor dat, indien nodig, het bijbehorende object wordt afgeleid
bestanden. Bijvoorbeeld:

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

Deze zal ervoor zorgen dat, indien nodig, foo.o en bar.o. Het aangeroepen commando is eenvoudig
`%CCCOM', dat door vervanging wordt uitgebreid naar het juiste externe commando dat nodig is
om elk object te bouwen. We zullen de vervangingsregels verder onderzoeken onder het commando 'Opdracht'
methode, hieronder.

De constructievariabelen worden ook voor andere doeleinden gebruikt. 'CPPPATH' is bijvoorbeeld
gebruikt om een ​​door dubbele punten gescheiden pad van include-mappen op te geven. Deze zijn zo bedoeld
doorgegeven aan de C-preprocessor en worden ook gebruikt door de C-bestandsscanmachines
bepaal de afhankelijkheden die betrokken zijn bij een C-compilatie. Variabelen beginnend met
onderstrepingstekens, worden op verschillende manieren gemaakt en moeten normaal gesproken als 'intern' worden beschouwd
variabelen. Bijvoorbeeld wanneer een methode wordt aangeroepen die vraagt ​​om het maken van een object
vanuit een C-bron wordt de variabele `_IFLAGS' aangemaakt: deze komt overeen met de `-I'-schakelaars
vereist door de C-compiler om de mappen weer te geven die zijn gespecificeerd door `CPPPATH'.

Houd er rekening mee dat voor elke specifieke omgeving de waarde van een variabele één keer wordt ingesteld, en daarna
nooit opnieuw instellen (om een ​​variabele te wijzigen, moet u een nieuwe omgeving maken. Er worden methoden verstrekt
voor het kopiëren van bestaande omgevingen voor dit doel). Sommige interne variabelen, zoals
`_IFLAGS' worden op aanvraag gemaakt, maar eenmaal ingesteld, blijven ze vast gedurende de levensduur van de
milieu.

De variabelen `CFLAGS', `LDFLAGS' en `ARFLAGS' bieden allemaal een plek voor het doorgeven van opties aan
respectievelijk de compiler, lader en archiver. Minder voor de hand liggend is de `INCDIRPREFIX'
variabele specificeert de optietekenreeks die aan het begin van elke include moet worden toegevoegd
directory, zodat de compiler weet waar hij het kan vinden .h bestanden. Op dezelfde manier is de
De variabele 'LIBDIRPREFIX' specificeert de optietekenreeks die aan het begin van moet worden toegevoegd
elke map waarin de linker naar bibliotheken moet zoeken.

Een andere variabele, `ENV', wordt gebruikt om de systeemomgeving tijdens de uitvoering te bepalen
van een extern commando. Standaard is de enige omgevingsvariabele die is ingesteld `PATH',
dat is het uitvoeringspad voor een UNIX-opdracht. Voor de grootst mogelijke reproduceerbaarheid zou u dat moeten doen
zorg er echt voor dat u uw eigen uitvoeringspad bepaalt, op uw hoogste niveau Bouwen bestand (of
misschien door een geschikt constructiepakket te importeren met het Perl `use'-commando). De
standaardvariabelen zijn bedoeld om u van de grond te krijgen.

Interpoleren bouw variabelen

Variabelen uit de bouwomgeving kunnen worden geïnterpoleerd in de bron- en doelbestandsnamen
door de naam van de constructievariabele vooraf te laten gaan door `%'.

$env = nieuwe nadelen(
DESTDIR => 'programma's',
SRCDIR => 'src',
);
Programma $env '%DESTDIR/hello', '%SRCDIR/hello.c';

Uitbreiding van constructievariabelen is recursief, dat wil zeggen: het bestand naam(s) zullen opnieuw worden
uitgebreid totdat er geen vervanging meer mogelijk is. Als een constructievariabele dat niet is
gedefinieerd in de omgeving, dan wordt de nulreeks vervangen.

Standaard bouw methoden


De lijst met standaardconstructiemethoden omvat het volgende:

De `nieuw' aannemer

De `nieuwe' methode is een Perl-objectconstructor. Dat wil zeggen dat er geen beroep op wordt gedaan via een verwijzing
aan een bestaande bouwomgeving referentie, maar eerder statisch, waarbij de naam wordt gebruikt
van de Perl pakket waar de constructor is gedefinieerd. De methode wordt als volgt aangeroepen:

$env = nieuwe nadelen( );

Het milieu dat u terugkrijgt, wordt gezegend in het pakket 'nadelen', wat betekent dat dit ook het geval zal zijn
hebben de hieronder beschreven standaardmethoden eraan gekoppeld. Individuele constructie
variabelen kunnen worden overschreven door naam/waarde-paren op te geven in een overschrijflijst. Let daar op
om elke opdrachtomgevingsvariabele (dat wil zeggen alles onder `ENV') te overschrijven, moet u dit doen
overschrijf ze allemaal. U kunt dit probleem omzeilen door de `kopieer'-methode op een
bestaande bouwomgeving.

De `kloon' methode

De 'kloon'-methode creëert een kloon van een bestaande bouwomgeving, en dat kan ook
genoemd zoals in het volgende voorbeeld:

$env2 = $env1->kloon( );

U kunt op de gebruikelijke manier overschrijvingen opgeven om een ​​andere omgeving te creëren dan de
origineel. Als u gewoon een nieuwe naam voor dezelfde omgeving wilt (wat handig kan zijn als u
omgevingen exporteren naar bestaande componenten), kunt u gewoon een eenvoudige toewijzing gebruiken.

De `kopie' methode

De 'copy'-methode extraheert de extern gedefinieerde constructievariabelen uit een
omgeving en retourneert deze als een lijst met naam/waarde-paren. Overschrijven kan ook
op voorwaarde dat, in welk geval de overschreven waarden, indien van toepassing, worden geretourneerd. De
De geretourneerde lijst kan worden toegewezen aan een hash, zoals weergegeven in het prototype hieronder, maar dat kan ook
op andere manieren worden gemanipuleerd:

%env = $env1->kopie( );

De waarde van `ENV', die zelf een hash is, wordt ook gekopieerd naar een nieuwe hash, dus dit kan
veranderd zonder angst de oorspronkelijke omgeving te beïnvloeden. Dus als je bijvoorbeeld echt
Als je alleen de `PATH'-variabele in de standaardomgeving wilt overschrijven, kun je het volgende doen
volgende:

%nadelen = nieuwe nadelen()->kopie();
$cons{ENV}{PATH} = " ";
$nadelen = nieuwe nadelen(%nadelen);

Hierdoor blijft al het andere dat zich mogelijk in de standaarduitvoeringsomgeving bevindt, achter
ongestoord.

De `Installeren' methode

De `Install'-methode zorgt ervoor dat de opgegeven bestanden in het opgegeven bestand worden geïnstalleerd
map. De installatie is geoptimaliseerd: het bestand wordt niet gekopieerd als het gekoppeld kan worden. Als
Dit is niet het gewenste gedrag. U zult een andere methode moeten gebruiken om het
bestand. Het wordt als volgt genoemd:

Installeer $env , ;

Houd er rekening mee dat, hoewel de te installeren bestanden een willekeurige naam kunnen hebben, alleen de laatste
component van elke naam wordt gebruikt voor de geïnstalleerde doelnaam. Dus als je bijvoorbeeld
regelen om te installeren foe/bar in baz, hierdoor ontstaat een bars bestand in de baz map (niet
foe/bar).

De `InstallerenAs' methode

De `InstallAs'-methode regelt de opgegeven bron filet(s) te installeren als de
gespecificeerd doel filet(S). Er moeten meerdere bestanden worden opgegeven als een bestandslijst. De
installatie is geoptimaliseerd: het bestand wordt niet gekopieerd als het kan worden gekoppeld. Als dit niet de
gewenst gedrag, moet u een andere methode gebruiken om het bestand te installeren. Het is
als volgt genoemd:

`InstallAs' werkt op twee manieren:

Installatie met één bestand:

InstallAs $env TgtFile, SrcFile;

Installatie van meerdere bestanden:

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

Of zelfs als:

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

Zowel de doel- als de bronnenlijst moeten dezelfde lengte hebben.

De `Kostbaar' methode

De `Precious'-methode vraagt ​​de nadelen om het opgegeven bestand of de lijst met bestanden niet eerder te verwijderen
ze opnieuw bouwen. Het wordt aangeroepen als:

Schitterend ;

Dit is vooral handig als u incrementele updates van bibliotheken of foutopsporing wilt toestaan
informatiebestanden die worden bijgewerkt in plaats van elke keer opnieuw te worden opgebouwd. Nadelen zullen nog steeds
verwijder de bestanden wanneer de vlag `-r' is opgegeven.

De `Commando' methode

De `Command'-methode is een verzamelmethode die kan worden gebruikt om externe instellingen te regelen
opdracht die moet worden aangeroepen om het doel bij te werken. Voor deze opdracht zijn een doelbestand en een lijst met
ingangen zijn voorzien. Daarnaast is er een constructieopdrachtregel of -regels beschikbaar als a
string (in deze string kunnen meerdere opdrachten zijn ingebed, gescheiden door new
lijnen). 'Commando' wordt als volgt aangeroepen:

Commando $env , , ;

Het doel wordt afhankelijk gemaakt van de lijst met opgegeven invoerbestanden, en de invoer moet dat ook zijn
succesvol worden gebouwd, anders zullen Cons niet proberen het doelwit te bouwen.

Binnen de bouwopdracht kan elke variabele uit de bouwomgeving voorkomen
geïntroduceerd door de naam van de constructievariabele vooraf te laten gaan door `%'. Dit is recursief:
het commando wordt uitgebreid totdat er geen vervangingen meer kunnen worden uitgevoerd. Indien een constructie
variabele niet is gedefinieerd in de omgeving, wordt de nulreeks vervangen. A
verdubbelde `%%' zal worden vervangen door een enkele `%' in het constructiecommando.

Er zijn verschillende pseudovariabelen die ook zullen worden uitgebreid:

%> De naam van het doelbestand (bij een opdracht met meerdere doelen is dit altijd het eerste doel
genoemd).

%0 Hetzelfde als `%>'.

%1, %2, ..., %9
Deze verwijzen respectievelijk naar het eerste tot en met het negende invoerbestand.

%< De volledige set ingangen. Als een van deze ergens anders in de
huidige opdrachtregel (via `%1', `%2', enz.), dan zullen deze worden verwijderd uit het
lijst geleverd door `%<'. Beschouw het volgende commando in a Dienstplichtige filet
in de proef directory:

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

If TGT moest worden bijgewerkt, dan zou dit resulteren in de uitvoering van de
volgende opdrachten, ervan uitgaande dat er geen nieuwe toewijzing is ingesteld voor de proef
directory:

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

Elk van de bovenstaande pseudovariabelen kan onmiddellijk worden gevolgd door een van de volgende
achtervoegsels om een ​​deel van de uitgebreide padnaam te selecteren:

:a het absolute pad naar de bestandsnaam
:b de map plus de bestandsnaam, ontdaan van elk achtervoegsel
:d de map
:f de bestandsnaam
:s het achtervoegsel van de bestandsnaam
:F de bestandsnaam ontdaan van elk achtervoegsel

Als we verder gaan met het bovenstaande voorbeeld, zou `%<:f' uitbreiden naar `foo bar baz', en `%':d> zou
uitbreiden naar 'testen'.

Het is mogelijk om een ​​deel van de opdracht programmatisch te herschrijven door een deel ervan in te sluiten
tussen `%[' en `%]'. Hierdoor wordt de constructievariabele genoemd als het eerste woord aangeroepen
tussen haakjes ingesloten als Perl-codereferentie; de resultaten van deze oproep zullen worden gebruikt
om de inhoud van de haakjes op de opdrachtregel te vervangen. Gegeven bijvoorbeeld een
bestaand invoerbestand met de naam tgt.in:

@trefwoorden = qw(foo bar baz);
$env = nieuwe nadelen(X_COMMA => sub { join(",", @_) });
Commando $env 'tgt', 'tgt.in', qq(
echo '# Trefwoorden: %[X_COMMA @keywords %]' > %>
kat %< >> %>
);

Dit zal uitvoeren:

echo '# Trefwoorden: foo,bar,baz' > tgt
cat tgt.in >> tgt

Nadat vervanging heeft plaatsgevonden, worden reeksen witruimte omgezet in enkele spaties, en
voor- en achterliggende witruimte worden geëlimineerd. Het is daarom niet mogelijk om in te voeren
witte ruimten met variabele lengte in tekenreeksen die in een opdracht worden doorgegeven, zonder toevlucht te nemen tot enkele
een soort shell-citaat.

Als er een opdrachtreeks van meerdere regels wordt opgegeven, worden de opdrachten opeenvolgend uitgevoerd. Indien aanwezig
van de opdrachten mislukt, waarna geen van de overige wordt uitgevoerd en het doel niet wordt gemarkeerd als
bijgewerkt, dwz dat er geen nieuwe handtekening voor het doel wordt opgeslagen.

Normaal gesproken, als alle opdrachten slagen en een nulstatus retourneren (of welk platform dan ook),
specifieke indicatie van succes vereist is), dan wordt een nieuwe handtekening opgeslagen voor de
doel. Als een commando ten onrechte succes rapporteert, zelfs na een mislukking, dan zal Cons dat ook doen
neem aan dat het doelbestand dat door die opdracht is gemaakt, nauwkeurig en up-to-date is.

Er wordt aangenomen dat het eerste woord van elke opdrachtreeks, na uitbreiding, een uitvoerbaar bestand is
commando opgezocht naar de omgevingsvariabele `PATH' (die op zijn beurt wordt gespecificeerd door de
constructievariabele ‘ENV’). Als dit commando op het pad wordt gevonden, zal het doel dat ook doen
ervan afhangen: het commando zal daarom indien nodig automatisch worden gebouwd. Zijn
Het is mogelijk om meerdelige opdrachten naar sommige shells te schrijven, gescheiden door puntkomma's. Alleen de
Het eerste commandowoord zal echter afhankelijk zijn van het schrijven van uw commandostrings
op deze manier moet u ofwel expliciet een afhankelijkheid instellen (met de `Depends'-methode), of
Zorg ervoor dat de opdracht die u gebruikt een systeemopdracht is, wat naar verwachting ook het geval zal zijn
beschikbaar. Als deze niet beschikbaar is, krijgt u uiteraard een foutmelding.

Als een commando (zelfs één binnen een commando van meerdere regels) begint met `[perl]', de rest
van die opdrachtregel zal worden geëvalueerd door de actieve Perl in plaats van te worden gevorkt door de
schelp. Als er een fout optreedt bij het parseren van de Perl of als de Perl-expressie 0 of retourneert
undef, wordt de opdracht als mislukt beschouwd. Hier is bijvoorbeeld een eenvoudige
commando dat rechtstreeks vanuit Perl een bestand `foo' aanmaakt:

$env = nieuwe nadelen();
Commando $env 'foo',
qq([perl] open(FOO,'>foo');print FOO "hi\\n"; close(FOO); 1);

Merk op dat wanneer de opdracht wordt uitgevoerd, u zich in hetzelfde pakket bevindt als wanneer de Bouwen
or Dienstplichtige bestand is gelezen, zodat u Perl-functies kunt aanroepen die u daarin hebt gedefinieerd
Bouwen or Dienstplichtige bestand waarin de `Command' verschijnt:

$env = nieuwe nadelen();
sub maak_bestand {
mijn $bestand = shift;
open(BESTAND, ">$bestand");
BESTAND afdrukken "hallo\n";
sluiten(BESTAND);
1 terug;
}
Commando $env 'foo', "[perl] &create_file('%>')";

De Perl-string wordt gebruikt om de handtekening voor het afgeleide bestand te genereren, dus als u
verander de string, het bestand zal opnieuw opgebouwd worden. De inhoud van eventuele subroutines die u oproept,
maken echter geen deel uit van de handtekening, dus als u een aangeroepen subroutine wijzigt, zoals
`create_file' hierboven, zal het doel dat doen niet herbouwd worden. Waarschuwing gebruiker.

Nadelen print normaal gesproken een opdracht voordat deze wordt uitgevoerd. Dit gedrag wordt onderdrukt als de
het eerste teken van het commando is `@'. Houd er rekening mee dat u mogelijk de `@' moet scheiden van
de opdrachtnaam of escape deze om te voorkomen dat `@cmd' eruitziet als een array voor Perl-citaat
operators die interpolatie uitvoeren:

# De eerste opdrachtregel is onjuist,
# omdat "@cp" op een array lijkt
# naar de Perl qq// functie.
# Gebruik in plaats daarvan het tweede formulier.
Commando $env 'foo', 'foo.in', qq(
@cp %< tijdelijk bestand
@ cp tijdelijke bestand %>
);

Als er ergens in de uitgebreide opdrachtregel shell-metatekens staan, zoals `<',
`>', aanhalingstekens of puntkomma's, dan wordt het commando daadwerkelijk uitgevoerd door het aanroepen van a
schelp. Dit betekent dat een commando zoals:

cd foe

alleen zal doorgaans mislukken, omdat er geen commando `cd' op het pad staat. Maar het commando
draad:

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

wanneer uitgevouwen zal het nog steeds de puntkomma van het shell-metateken bevatten, en een shell zal dat zijn
aangeroepen om het commando te interpreteren. Omdat `cd' door deze sub-shell wordt geïnterpreteerd, kan het commando
zal uitvoeren zoals verwacht.

Om een ​​opdracht met meerdere doelen op te geven, kunt u een verwijzing naar een lijst opgeven
doelen. In Perl kan een lijstverwijzing worden gemaakt door een lijst tussen vierkante haakjes te plaatsen.
Vandaar het volgende commando:

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

kan worden gebruikt in een geval waarin het commando `gen' twee bestanden aanmaakt, beide foo.h en foo.c.

De `Objecten' methode

De `Objects'-methode zorgt ervoor dat de objectbestanden worden gemaakt die overeenkomen met het opgegeven bestand
bronbestanden. Het wordt aangeroepen zoals hieronder weergegeven:

@files = Objecten $env ;

Onder Unix worden bronbestanden die eindigen op .s en .c worden momenteel ondersteund en zullen worden gecompileerd
in een naam van hetzelfde bestand dat eindigt op .o. Standaard worden alle bestanden gemaakt door een beroep te doen op
het externe commando dat resulteert uit het uitbreiden van de constructievariabele `CCCOM', met
`%<' en `%>' zijn respectievelijk ingesteld op de bron- en objectbestanden (zie de `Command'-methode
voor uitbreidingsdetails). De variabele `CPPPATH' wordt ook gebruikt bij het scannen van bronbestanden
voor afhankelijkheden. Dit is een door dubbele punten gescheiden lijst met padnamen, en wordt ook gebruikt om een ​​pad te maken
de constructievariabele `_IFLAGS', die de juiste lijst met -`I' zal bevatten
opties voor de compilatie. Alle relatieve padnamen in `CPPPATH' worden relatief geïnterpreteerd
naar de directory waarin de bijbehorende bouwomgeving is aangemaakt (absolute
en top-relatieve namen kunnen ook worden gebruikt). Deze variabele wordt gebruikt door `CCCOM'. Het gedrag
van dit commando kan worden gewijzigd door een van de variabelen die worden geïnterpoleerd te wijzigen
in `CCCOM', zoals `CC', `CFLAGS' en, indirect, `CPPPATH'. Het is ook mogelijk
vervang de waarde van `CCCOM' zelf. Voor uw gemak retourneert dit bestand de lijst met
bestandsnamen van objecten.

De `Programma' methode

De `Program'-methode zorgt ervoor dat het opgegeven programma aan het opgegeven object wordt gekoppeld
bestanden. Het wordt op de volgende manier aangeroepen:

Programma $env , ;

Aan de programmanaam wordt de waarde van de constructievariabele `SUFEXE' toegevoegd (by
standaard `.exe' op Win32-systemen, niets op Unix-systemen) als het achtervoegsel nog niet bestaat
aanwezig is.

Bronbestanden kunnen worden gespecificeerd in plaats van objectbestanden; de `Objects'-methode zal dat zijn
aangeroepen om de conversie van alle bestanden naar objectbestanden te regelen, en dus alle
observaties over de `Objects'-methode hierboven zijn ook op deze methode van toepassing.

De daadwerkelijke koppeling van het programma wordt afgehandeld door een extern commando dat resulteert
van het uitbreiden van de `LINKCOM'-constructievariabele, met `%<' ingesteld op de objectbestanden tot
worden gekoppeld (in de weergegeven volgorde), en `%>' ingesteld op het doel (zie de `Command'-methode
voor uitbreidingsdetails). De gebruiker kan aanvullende variabelen in de constructie instellen
omgeving, inclusief `LINK', om te definiëren welk programma moet worden gebruikt voor het koppelen, `LIBPATH', a
door dubbele punten gescheiden lijst met bibliotheekzoekpaden, voor gebruik met bibliotheekspecificaties van de
formulier -llib, en `LIBS', waarbij de lijst met bibliotheken wordt gespecificeerd waarnaar moet worden gelinkt (in beide -llib
formulier of gewoon als padnamen. Relatieve padnamen in zowel `LIBPATH' als `LIBS' worden geïnterpreteerd
relatief ten opzichte van de map waarin de bijbehorende bouwomgeving is gemaakt
(absolute namen en relatieve namen mogen ook worden gebruikt). Nadelen worden automatisch ingesteld
afhankelijkheden van bibliotheken genoemd in `LIBS': deze bibliotheken zullen eerder worden gebouwd
de opdracht is gekoppeld.

De `Bibliotheek' methode

De `Bibliotheek'-methode regelt het creëren van de gespecificeerde bibliotheek van het gespecificeerde object
bestanden. Er wordt als volgt een beroep op gedaan:

Bibliotheek $env , ;

Aan de bibliotheeknaam wordt de waarde van de constructievariabele `SUFLIB' toegevoegd (by
standaard, `.lib' op Win32-systemen, `.a' op Unix-systemen) als het achtervoegsel nog niet is
aanwezig is.

Bronbestanden kunnen worden gespecificeerd in plaats van objectbestanden; de `Objects'-methode zal dat zijn
aangeroepen om de conversie van alle bestanden naar objectbestanden te regelen, en dus alle
observaties over de `Objects'-methode hierboven zijn ook op deze methode van toepassing.

De daadwerkelijke creatie van de bibliotheek zal worden afgehandeld door een extern commando dat resulteert
van het uitbreiden van de constructievariabele `ARCOM', waarbij `%<' is ingesteld op de bibliotheekleden (in
de weergegeven volgorde), en `%>' naar de bibliotheek die moet worden aangemaakt (zie de `Command'-methode voor
uitbreidingsdetails). De gebruiker kan variabelen instellen in de bouwomgeving
invloed hebben op de werking van het commando. Deze omvatten `AR', het archiefprogramma dat u moet gebruiken,
`ARFLAGS', die kan worden gebruikt om de vlaggen te wijzigen die aan het programma zijn gegeven door `AR',
en `RANLIB', de naam van een programma voor het genereren van archiefindexen, indien nodig (als het specifieke
behoefte deze laatste functionaliteit niet vereist, dan moet `ARCOM' opnieuw worden gedefinieerd om dit niet te doen
referentie `RANLIB').

Met de `Bibliotheek'-methode kan dezelfde bibliotheek in meerdere methoden worden gespecificeerd
aanroepingen. Alle bijdragende objecten van alle aanroepingen (die afkomstig kunnen zijn van
verschillende mappen) worden gecombineerd en gegenereerd door één archiefcommando. Opmerking,
echter, als u een build snoeit zodat slechts een deel van een bibliotheek wordt gespecificeerd, dan alleen
dat deel van de bibliotheek wordt gegenereerd (de rest verdwijnt!).

De `Module' methode

De `Module'-methode is een combinatie van de `Program'- en `Command'-methoden. Liever dan
Als u rechtstreeks een uitvoerbaar programma genereert, kunt u met deze opdracht uw eigen programma opgeven
commando om daadwerkelijk een module te genereren. De methode wordt als volgt aangeroepen:

Module $env , , ;

Deze opdracht is handig in gevallen waarin u bijvoorbeeld dynamisch wilt creëren
geladen modules of statisch gekoppelde codebibliotheken.

De `Hangt ervan af' methode

Met de methode `Depends' kunt u aanvullende afhankelijkheden voor een doel opgeven. Het is
als volgt ingeroepen:

Hangt af van $env , ;

Dit kan af en toe nuttig zijn, vooral in gevallen waarin er geen scanner bestaat (of is).
beschrijfbaar) voor bepaalde typen bestanden. Normaal gesproken worden afhankelijkheden berekend
automatisch uit een combinatie van de expliciete afhankelijkheden die door de methode zijn ingesteld
aanroepen of door bronbestanden te scannen.

Een reeks identieke afhankelijkheden voor meerdere doelen kan worden gespecificeerd met behulp van een verwijzing naar
een lijst met doelen. In Perl kan een lijstverwijzing worden gemaakt door een lijst in een vierkant te plaatsen
beugels. Vandaar het volgende commando:

Afhankelijk van $env ['foo', 'bar'], 'input_file_1', 'input_file_2';

geeft aan dat zowel de foo en bars bestanden zijn afhankelijk van de vermelde invoerbestanden.

De `Negeer' methode

Met de `Ignore'-methode kunt u expliciet de afhankelijkheden negeren die Cons ervan afleidt
eigen. Er wordt als volgt een beroep op gedaan:

Negeren ;

Dit kan worden gebruikt om hercompilaties te voorkomen als gevolg van wijzigingen in systeemheaderbestanden of
hulpprogramma's waarvan bekend is dat ze de gegenereerde doelen niet beïnvloeden.

Als een programma bijvoorbeeld in een NFS-gemounte map op meerdere systemen wordt gebouwd, kan dat
heb verschillende exemplaren van standaard.h, zullen de verschillen de handtekeningen van iedereen beïnvloeden
afgeleide doelen opgebouwd uit bronbestanden die `#include '. Dit zal alles veroorzaken
deze doelen moeten opnieuw worden opgebouwd bij het wisselen van systemen. Als dit geen wenselijk gedrag is,
dan verwijdert de volgende regel de afhankelijkheden van het standaard.h file:

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

Merk op dat de argumenten voor de `Ignore'-methode reguliere expressies zijn, dus speciaal
tekens moeten worden geëscaped en misschien wilt u het begin of einde van de
expressie met `^'- of `$'-tekens.

De `Zout' methode

De `Salt'-methode voegt voor elke afgeleide een constante waarde toe aan de handtekeningberekening
bestand. Er wordt als volgt een beroep op gedaan:

Zout $string;

Als u de Salt-waarde wijzigt, wordt een volledige herbouw van elk afgeleid bestand afgedwongen. Dit kan zijn
gebruikt om herbouwingen in bepaalde gewenste omstandigheden af ​​te dwingen. Bijvoorbeeld,

Zout `uname -s`;

Zou een volledige herbouw van elk afgeleid bestand forceren wanneer het besturingssysteem wordt ingeschakeld
waarop de build wordt uitgevoerd (zoals gerapporteerd door `uname -s') verandert.

De `Gebruik cache' methode

De `UseCache'-methode instrueert Cons om een ​​cache van afgeleide bestanden bij te houden die moeten worden gedeeld
tussen afzonderlijke bouwbomen van hetzelfde project.

UseCache("cache/ ") ⎪⎪ warn("cachemap niet gevonden");

De `Bronpad' methode

De `SourcePath'-wiskunde retourneert de echte bronpadnaam van een bestand, in tegenstelling tot de
padnaam binnen een buildmap. Er wordt als volgt een beroep op gedaan:

$pad = Bronpad ;

De `NadelenPad' methode

De methode `ConsPath' retourneert true als het opgegeven pad een afleidbaar bestand is, en retourneert
undef (onwaar) anders. Er wordt als volgt een beroep op gedaan:

$resultaat = ConsPath ;

De `Gesplitst pad' methode

De `SplitPath'-methode zoekt meerdere padnamen op in een string, gescheiden door de standaardwaarde
padscheidingsteken voor het besturingssysteem (':' op UNIX-systemen, ';' op Windows NT), en
retourneert de volledig gekwalificeerde namen. Er wordt als volgt een beroep op gedaan:

@paden = SplitPath ;

De `SplitPath'-methode converteert namen met het voorvoegsel '#' naar de juiste build op het hoogste niveau
naam (zonder de '#') en converteert relatieve namen naar namen op het hoogste niveau.

De `DirPath' methode

De `DirPath'-methode retourneert het buildpad naam(s) van een map of lijst met mappen.
Er wordt als volgt een beroep op gedaan:

$cwd = DirPath ;

Het meest voorkomende gebruik van de `DirPath'-methode is:

$cwd = DirPath '.';

om het pad naar de huidige map van een dochteronderneming op te halen Dienstplichtige bestand.

De `Bestandspad' methode

De `FilePath'-methode retourneert het buildpad naam(s) van een bestand of lijst met bestanden. Het is
als volgt ingeroepen:

$bestand = Bestandspad ;

De `Hulp' methode

De `Help'-methode specificeert helptekst die wordt weergegeven wanneer de gebruiker `cons
-H'. Dit kan worden gebruikt om documentatie te verschaffen over specifieke doelen, waarden en builds
opties, enz. voor de buildboom. Er wordt als volgt een beroep op gedaan:

Hulp ;

De `Help'-methode mag slechts één keer worden aangeroepen en moet normaal gesproken bovenaan worden gespecificeerd.
niveau Bouwen bestand.

Het uitbreiden NADELEN


Dwingend bouw variabelen

Er zijn verschillende manieren om Cons uit te breiden, die variëren in moeilijkheidsgraad. De makkelijkste
methode is om uw eigen bouwomgeving te definiëren, gebaseerd op de standaardomgeving,
maar aangepast om uw specifieke behoeften weer te geven. Voor C-gebaseerd zal dit vaak voldoende zijn
toepassingen. U kunt hiervoor de `new'-constructor en de `clone'- en `copy'-methoden gebruiken
hybride omgevingen creëren. Deze veranderingen kunnen volledig transparant zijn voor de onderliggende waarde
Dienstplichtige bestanden.

Het toevoegen van nieuwe methoden

Voor iets veeleisendere veranderingen wil je misschien nieuwe methoden toevoegen aan de 'nadelen'
pakket. Hier is een voorbeeld van een heel eenvoudige extensie, `InstallScript', die een
tcl-script op een gevraagde locatie, maar bewerkt het script eerst om een ​​platform weer te geven
afhankelijk pad dat in het script moet worden geïnstalleerd:

# nadelen::InstallScript - Maak een platformafhankelijke versie van een shell
# script door de tekenreeks ``#!uw-pad-hier'' te vervangen door platformspecifiek
# pad $BIN_DIR.

sub nadelen::InstallScript {
mijn ($env, $dst, $src) = @_;
Commando $env $dst, $src, qq(
sed s+uw-pad-hier+$BIN_DIR+ %< > %>
chmod oug+x %>
);
}

Merk op dat deze methode rechtstreeks in het pakket `cons' wordt gedefinieerd (door de naam
met `nadelen::'). Een verandering die op deze manier wordt doorgevoerd, zal wereldwijd zichtbaar zijn voor alle omgevingen,
en zou kunnen worden aangeroepen zoals in het volgende voorbeeld:

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

Voor een kleine verbetering in het algemeen zou de variabele `BINDIR' kunnen worden doorgegeven als een
argument of overgenomen uit de bouwomgeving - als `%BINDIR'.

Dwingend methoden

In plaats van de methode toe te voegen aan de naamruimte `cons', zou u een nieuw pakket kunnen definiëren
die bestaande methoden overneemt van het pakket 'cons' en andere overschrijft of toevoegt. Dit
kan worden gedaan met behulp van de overervingsmechanismen van Perl.

Het volgende voorbeeld definieert een nieuw pakket `cons::switch' dat de standaard overschrijft
'Bibliotheek'-methode. De overschreven methode bouwt gekoppelde bibliotheekmodules in plaats van een bibliotheek
archieven. Er wordt een nieuwe constructor geleverd. Omgevingen die met deze constructor zijn gemaakt, zullen dat wel doen
de nieuwe bibliotheekmethode hebben; anderen niet.

pakket nadelen::schakelaar;
BEGIN {@ISA = 'nadelen'}

sub nieuw {
verschuiving;
zegen nieuwe nadelen(@_);
}

subbibliotheek {
mijn($env) = verschuiving;
mijn($lib) = verschuiven;
mijn(@objs) = Objecten $env @_;
Commando $env $lib, @objs, q(
%LD -r %LDFLAGS %< -o %>
);
}

Deze functionaliteit kan worden aangeroepen zoals in het volgende voorbeeld:

$env = nieuwe nadelen::switch(@overrides);
...
Bibliotheek $env 'lib.o', 'foo.c', 'bar.c';

Het aanroepen NADELEN


Het commando `cons' wordt meestal aangeroepen vanuit de root van de build-boom. A Bouwen filet
moet in die map bestaan. Als het `-f'-argument wordt gebruikt, dan is er een alternatief Bouwen
bestand kan worden gebruikt (en mogelijk een alternatieve root, aangezien `cons' naar cd Bouwen
map die het bestand bevat).

Als `cons' wordt aangeroepen vanuit een kind van de root van de build-boom met het `-t'-argument,
loopt door de maphiërarchie op zoek naar een Bouwen bestand. (Een alternatieve naam mag
nog steeds worden gespecificeerd met `-f'.) De doelen die op de opdrachtregel worden opgegeven, worden gewijzigd
relatief zijn ten opzichte van het ontdekte Bouwen bestand. Bijvoorbeeld vanuit een map met
een topniveau Bouwen bestand, de volgende aanroep:

% cd libfoo/subdir
% nadelen -t doel

is precies gelijk aan:

% nadelen libfoo/subdir/target

Als er 'Standaard'-doelen zijn opgegeven in de maphiërarchie Bouwen or
Dienstplichtige bestanden, alleen de standaarddoelen in of onder de map waaruit `cons -t'
werd ingeroepen, zal worden gebouwd.

Het commando wordt als volgt aangeroepen:

nadelen --

WAAR argumenten kan een van de volgende zijn, in willekeurige volgorde:

doel Bouw het opgegeven doel. Als doel is een map en wordt vervolgens recursief opgebouwd
alles in die map.

+patroon Beperk de Dienstplichtige bestanden worden beschouwd als alleen de bestanden die overeenkomen patroonDit is
een reguliere Perl-expressie. Meerdere `+' argumenten worden geaccepteerd.

naam=
Sets naam waarderen golf in de `ARG'-hash doorgegeven aan het hoogste niveau Bouwen bestand.

`-cc' Toon de opdracht die zou zijn uitgevoerd bij het ophalen uit de cache. Nee
er wordt aangegeven dat het bestand is opgehaald; dit is handig voor
het genereren van buildlogs die kunnen worden vergeleken met echte buildlogs.

`-cd' Schakel alle caching uit. Niet ophalen uit de cache en niet doorspoelen naar de cache.

`-cr' Bouw afhankelijkheden in willekeurige volgorde. Dit is handig bij het bouwen van meerdere
soortgelijke bomen met caching ingeschakeld.

`-cs' Synchroniseer bestaande builddoelen waarvan is vastgesteld dat ze up-to-date zijn met cache.
Dit is handig als caching is uitgeschakeld met -cc of pas onlangs is ingeschakeld
met UseCache.

`-d' Foutopsporing op afhankelijkheid inschakelen.

`-f'
Gebruik het opgegeven bestand in plaats van Bouwen (maar verander eerst naar het bevatten
directory van filet).

`-h' Toon een helpbericht dat lokaal is voor de huidige build, als er zo een is gedefinieerd, en sluit af.

`-k' Blijf zo ver mogelijk doorgaan na fouten.

`-o'
Overschrijfbestand lezen filet.

`-p' Toon bouwproducten in gespecificeerde bomen. Er wordt geen poging ondernomen om te bouwen.

`-pa' Toon bouwproducten en bijbehorende acties. Er wordt geen poging ondernomen om te bouwen.

`-pw' Toon producten en waar ze zijn gedefinieerd. Er wordt geen poging ondernomen om te bouwen.

`-q' Wees niet breedsprakig over het installeren en verwijderen van doelen.

`-r' Verwijder bouwproducten die verband houden met . Er wordt geen poging ondernomen om te bouwen.

`-R'
Zoek naar bestanden in rust. Meerdere -R rust mappen worden doorzocht in de
bestelling opgegeven.

`-t' Doorloop de maphiërarchie op zoek naar a Bouwen bestand, als er geen bestaat
in de huidige map. De doelstellingen zullen worden aangepast zodat ze relatief zijn ten opzichte van de
Bouwen bestand.

`-v' Toon de `cons'-versie en ga door met verwerken.

`-V' Toon de `nadelen'-versie en sluit af.

`-wf'
Schrijf alle bestandsnamen in filet.

`-x' Toon een helpbericht dat lijkt op dit bericht en sluit af.

En construct-args kunnen alle argumenten zijn die u wilt verwerken in de Bouwen bestand.
Houd er rekening mee dat er een -- het scheiden van de argumenten van tegens en de argumenten die jij hebt
wilt verwerken in de Bouwen bestand.

Verwerken van construct-args kan met elk standaardpakket worden gedaan Getopt of zijn
varianten, of een door de gebruiker gedefinieerd pakket. tegens zal passeren in de construct-args as @ARGV en
zal niet proberen iets te interpreteren na de --.

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

zou het volgende doorgeven aan de nadelen

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

en het volgende, naar het hoogste niveau Bouwen bestand als @ARGV

-c test -f DEBUG

Merk op dat `cons -r .' is gelijk aan een volledig recursieve `make clean', maar vereist nee
ondersteuning in de Bouwen bestand of wat dan ook Dienstplichtige bestanden. Dit is vooral handig als u dat bent
het compileren van bestanden in bronmappen (als u de bouw en exporteren mappen,
dan kunt u de mappen gewoon verwijderen).

De opties `-p', `-pa' en `-pw' zijn uiterst nuttig als hulpmiddel bij het lezen
scripts of het debuggen ervan. Als je wilt weten welk script wordt geïnstalleerd export/include/foo.h,
typ bijvoorbeeld gewoon:

% nadelen -pw export/include/foo.h

gebruik en het schrijven van afhankelijkheid scanners


Met QuickScan kunnen eenvoudige doelonafhankelijke scanners voor bronbestanden worden ingesteld. Alleen
één QuickScan-scanner kan aan elk bronbestand en elke omgeving worden gekoppeld.

QuickScan wordt als volgt aangeroepen:

QuickScan CONSENV CODEREF, BESTANDSNAAM [, PATH]

De subroutine waarnaar CODEREF verwijst, zal naar verwachting een lijst met bestandsnamen retourneren
rechtstreeks via BESTAND. Deze bestandsnamen worden op hun beurt gescand. Het optionele PATH-argument
levert een opzoekpad voor het vinden van FILENAME en/of bestanden die door de gebruiker zijn geretourneerd
subroutine. Het PATH kan een verwijzing zijn naar een reeks namen van opzoekdirectory's, of a
reeks namen gescheiden door het scheidingsteken van het systeem (':' op UNIX-systemen, ';' op
WindowsNT).

De subroutine wordt één keer aangeroepen voor elke regel in het bestand, waarbij $_ is ingesteld op de huidige regel.
Als de subroutine naar extra regels moet kijken, of trouwens naar het hele bestand,
dan kan het ze zelf lezen, vanuit de filehandle SCAN. Het kan ook de lus beëindigen, als
het weet dat er geen verdere include-informatie beschikbaar is, door de filehandle te sluiten.

Ongeacht of er al dan niet een opzoekpad is opgegeven, QuickScan probeert eerst het bestand op te zoeken
relatief ten opzichte van de huidige map (voor het bestand op het hoogste niveau dat rechtstreeks aan QuickScan wordt geleverd),
of vanuit de map met het bestand dat naar het bestand verwijst. Dit is niet erg
algemeen, maar lijkt goed genoeg, vooral als je de luxe hebt om je eigen te schrijven
hulpprogramma's en kunnen het gebruik van het zoekpad op een standaard manier regelen. eindelijk, de
het zoekpad is momenteel gescheiden door dubbele punten. Dit maakt het NT-kamp misschien niet blij.

Hier is een echt voorbeeld, overgenomen uit a Bouwen bestand hier:

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

[Merk op dat de formulieren `$env->QuickScan...' en `$env->Command...' niet mogen zijn
noodzakelijk, maar om de een of andere reden is dit vereist voor deze specifieke aanroep. Dit verschijnt
een bug in Perl te zijn of een misverstand van mijn kant; deze aanroepstijl niet
lijkt altijd nodig te zijn.]

Hiermee worden alle namen van het formulier gevonden .smf in het bestand. Het zal de namen retourneren, zelfs als
ze zijn te vinden in de reacties, maar dat is geen probleem (het mechanisme is vergevingsgezind voor extra bestanden;
ze worden gewoon genegeerd in de veronderstelling dat het ontbrekende bestand zal worden opgemerkt wanneer het
programma, in dit voorbeeld smfgen, daadwerkelijk wordt aangeroepen).

Een scanner wordt alleen aangeroepen voor een bepaald bronbestand als dit nodig is voor een bepaald doel in het
boom. Het wordt slechts één keer aangeroepen voor een bepaald bronbestand.

Hier is een andere manier om dezelfde scanner te bouwen. Deze gebruikt een expliciete codereferentie,
en leest ook (in dit geval onnodig) het hele bestand zelf:

sub mijnscan {
mijn(@inclusief);
Doen {
push(@includes, /\b\S*?\.smf\b/g);
} terwijl ;
@inclusief
}

Merk op dat de volgorde van de lus is omgekeerd, met de lustest aan het einde. Dit is
omdat de eerste regel al voor u is gelezen. Deze scanner kan op een bron worden aangesloten
bestand door:

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

ONDERSTEUNING EN SUGGESTIES


Nadelen worden onderhouden door de gebruikersgemeenschap. Om u te abonneren, stuurt u een e-mail naar tegen-bespreek-
[e-mail beveiligd] met lichaam abonneren.

Meld eventuele suggesties via de [e-mail beveiligd] mailinglijst.

Gebruik nadelen online met behulp van onworks.net-services


Gratis servers en werkstations

Windows- en Linux-apps downloaden

  • 1
    Turkse devops
    Turkse devops
    TurkDevOps en kaynak yaz?l?m
    geli?tirici topluluklar? DevTurks-Team
    Tarafunda desteklenmektir..
    Kenmerken:https://github.com/turkdevopshttps://turkdevops.g...
    Turkdevops downloaden
  • 2
    asamdf
    asamdf
    *asammdf* is een snelle Python-parser en
    redacteur voor ASAM (Association for
    Standaardisatie van automatisering en
    Meetsystemen) MDF / MF4
    (Meetgegevensformaat...
    Asammdf downloaden
  • 3
    LAME (lame is geen mp3-encoder)
    LAME (lame is geen mp3-encoder)
    LAME is een educatief hulpmiddel om te gebruiken
    voor meer informatie over MP3-codering. De
    doel van het LAME-project is om te verbeteren
    de psycho-akoestiek, kwaliteit en snelheid
    van MP...
    LAME downloaden (Lame is geen MP3-encoder)
  • 4
    wxPython
    wxPython
    Een set Python-uitbreidingsmodules die
    verpak de platformonafhankelijke GUI-klassen van
    wxWidgets.. Publiek: Ontwikkelaars. Gebruiker
    interface: X Window-systeem (X11), Win32 ...
    WxPython downloaden
  • 5
    packfilemanager
    packfilemanager
    Dit is de bestandsbeheerder van het Total War-pakket
    project, vanaf versie 1.7. EEN
    korte introductie in Warscape
    modificatie: ...
    Packfilemanager downloaden
  • 6
    IPerf2
    IPerf2
    Een tool voor netwerkverkeer om te meten
    TCP- en UDP-prestaties met metrische gegevens
    rond zowel doorvoer als latentie. De
    doelen zijn onder meer het onderhouden van een actieve
    iperf kabeljauw...
    IPerf2 downloaden
  • Meer "

Linux-commando's

Ad