IngleseFranceseSpagnolo

Ad


Favicon di OnWorks

makepp_extending - Online nel cloud

Esegui makepp_extending nel provider di hosting gratuito OnWorks su Ubuntu Online, Fedora Online, emulatore online Windows o emulatore online MAC OS

Questo è il comando makepp_extending che può essere eseguito nel provider di hosting gratuito OnWorks utilizzando una delle nostre molteplici workstation online gratuite come Ubuntu Online, Fedora Online, emulatore online Windows o emulatore online MAC OS

PROGRAMMA:

NOME


makepp_extending -- Come estendere makepp usando Perl

DESCRIZIONE


Makepp internamente è abbastanza flessibile in modo che scrivendo un po' di codice Perl, puoi
aggiungere funzioni o eseguire una serie di altre operazioni.

Generale note on scrittura Perl codice a lavoro con makepp
Ogni makefile vive nel proprio pacchetto. Quindi le definizioni in un makefile non influiscono
definizioni in un altro makefile. Un insieme comune di funzioni che include tutti gli standard
le funzioni di manipolazione del testo vengono importate nel pacchetto al momento della creazione.

Le variabili Makefile sono memorizzate come scalari Perl in quel pacchetto. (Ci sono eccezioni a
questo: le variabili automatiche e il valore predefinito di variabili come CC sono in realtà
implementate come funzioni senza argomenti. Variabili specifiche di destinazione, variabili della riga di comando e
le variabili d'ambiente non sono viste in questo modo.) Quindi qualsiasi codice Perl che scrivi ha accesso a tutto
variabili makefile. Le variabili globali sono memorizzate nel pacchetto "Mpp::global". Vedere
Variabili Makefile per i dettagli.

Ciascuna delle istruzioni (ifperl / ifmakeperl, perl / makeperl, sub / makesub), il
funzioni (perl/makeperl, map/makemap) e l'azione della regola (perl/makeperl) per
la scrittura del codice Perl direttamente nel makefile è disponibile in due versioni. Il primo è assolutamente
Perl normale, il che significa che devi usare il prefisso "f_" come spiegato nella prossima sezione, se
vuoi chiamare le funzioni makepp. La seconda variante passa prima l'istruzione
Espansione variabile in stile make, il che significa che devi raddoppiare i "$" che vuoi che Perl veda.

La gestione della fine è speciale perché i dati enormi di makepp (a seconda del sistema di compilazione)
le strutture impiegherebbero diversi secondi per la raccolta dei rifiuti con un'uscita normale. Quindi facciamo un
uscita di forza bruta. Nel processo principale puoi ancora avere blocchi "END" ma se ne hai
gli handle di file globali potrebbero non essere cancellati. Ma dovresti usare il lessico moderno
filehandle, che vengono chiusi correttamente quando si esce dall'ambito.

Nel codice Perl eseguito direttamente come azione della regola o tramite un comando definito da te, è il
di fronte. I blocchi "END" non verranno eseguiti, ma i filehandle globali verranno svuotati per te. Il
"DISTRUZIONE" di oggetti globali non verrà mai eseguito.

Aggiunta nuovi testuale funzioni
Puoi aggiungere una nuova funzione al repertorio di makepp semplicemente definendo una subroutine Perl di
lo stesso nome ma con il prefisso "f_". Per esempio:

sub f_miafunzione {
mio $argomento = &arg; # Assegna un nome all'argomento.
my( undef, $mkfile, $mkfile_line ) = @_; # Assegna un nome agli argomenti.

... fai qualcosa qui

return $valore_ritorno;
}

XYZ := $(myfunc my func argomenti)

Se la tua funzione non accetta argomenti, non c'è niente da fare. Se la tua funzione ne accetta uno
argomento, come nell'esempio sopra, usa la semplice funzione di accesso &arg per ottenerlo. Se tu
aspettati più argomenti, hai bisogno della funzione di accesso più complessa "args" descritta di seguito.

Questi accessori elaborano gli stessi tre parametri che dovrebbero essere passati a qualsiasi "f_"
funzione, ovvero gli argomenti della funzione, l'oggetto makefile e un descrittore di riga per
messaggi. Quindi puoi usare la forma efficiente &arg nel primo caso.

La funzione di accesso &arg si occupa di quanto segue: Se gli argomenti erano già
espanso (es. per trovare il nome della funzione in "$(my$(function) arg)" l'argomento è
passato come stringa e appena restituito. Se l'argomento ha ancora bisogno di espansione, questo è il
caso normale, è invece un riferimento a una stringa. La funzione di accesso &arg lo espande per te,
per cui ha bisogno dell'oggetto makefile come secondo parametro.

Se ti aspetti più argomenti, possibilmente in numero variabile, il lavoro viene eseguito da "args".
Questa funzione di accesso accetta gli stessi 3 parametri di arg, più parametri aggiuntivi:

max: numero di argomenti (default 2): dare ~0 (maxint) per infinito
min: numero di argomenti (default 0 se max è ~0, altrimenti uguale a max)
only_comma: non mangiare spazio attorno alle virgole, usuale per non-nome file

Al massimo max, ma almeno min virgole presenti prima dell'espansione vengono utilizzate per dividere il
argomenti. Alcuni esempi dalle funzioni integrate di makepp:

my( $prefisso, $testo ) = argomenti $_[0], $_[1], $_[2], 2, 2, 1; # addprefix
per il mio $cond ( args $_[0], undef, $_[2], ~0 ) ... # e, o
my @args= args $_[0], $_[1], $_[2], ~0, 1, 1; # chiamata
my( $filtri, $parole ) = argomenti $_[0], $_[1], $_[2]; # filtro

La funzione dovrebbe restituire una stringa scalare (non un array) che viene poi inserita nel
testo a quel punto.

Se la tua funzione incontra un errore, dovrebbe morire usando la solita istruzione die Perl.
Questo verrà intrappolato da makepp e un messaggio di errore che mostra il nome del file e la linea
verrà stampato il numero dell'espressione che ha causato l'errore.

Non ci sono essenzialmente limiti a ciò che la funzione può fare; puoi accedere al file, eseguire
comandi della shell, ecc.

Al momento, le espressioni che appaiono nelle dipendenze e nelle azioni della regola sono espanse
una volta mentre le espressioni che appaiono nei target vengono espanse due volte, quindi fai attenzione se il tuo
ha effetti collaterali ed è presente in un'espressione per un target.

Si noti che l'ambiente (in particolare, il cwd) in cui la funzione valuta sarà
non necessariamente corrispondono all'ambiente in cui le regole del Makefile in cui il
funzione è stata valutata vengono eseguiti. Se questo è un problema per te, allora la tua funzione
probabilmente dovrebbe assomigliare a questo:

sub f_foo {
...
chdir $makefile->{CWD};

... eccetera.
}

Mettendo funzioni ai miglioramenti a Perl modulo
Se metti funzioni in un file di inclusione, avrai una copia per Makeppfile che
lo usa. Per evitare ciò, puoi scriverli come un normale modulo Perl con un "Esportatore"
interfaccia e usala. Questo si caricherà più velocemente e salverà la memoria:

perl { usa il mio modulo }
perla {
usa il mio::modulo; # put : su una nuova riga in modo che questo non venga analizzato come regola
}

Se hai bisogno di una delle funzioni normalmente disponibili in un Makefile (come "f_"
functions, "arg" o "args"), devi inserire questa riga nel tuo modulo:

usa Mpp::Sub;

Lo svantaggio è che il modulo sarebbe in un pacchetto diverso da una funzione direttamente
che appare in un makefile. Quindi devi passare tutto come parametri o costruire
nomi con la funzione "chiamante" di Perl.

chiamata esterno Perl script
Se chiami uno script Perl esterno tramite "sistema" o come azione di una regola, makepp eseguirà un fork a
nuovo processo (a meno che non sia l'ultima azione della regola) e attiva un nuovo interprete perl.
Non c'è niente di sbagliato in questo, tranne che c'è un modo più efficiente:

&command argomenti ...
Questa può essere un'azione della regola. Chiamerà una funzione command con un prefisso "c_", e
passagli il resto (opzionalmente citato in stile makepp -- non esattamente uguale a
Shell) argomenti. Se tale funzione non può essere trovata, passa tutte le stringhe a
"correre".

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

$(chiamata falsa cmd):
&mycmd 'arg con spazio' arg2 "arg3" # chiama c_mycmd

%.nella
&myscript -o $(output) $(input) # chiama myscript esterno

Puoi scrivere i tuoi comandi all'interno del framework dei builtin, permettendoti di usare
le stesse opzioni standard che hanno e la gestione degli I/O che danno.

L'operatore di blocco "Mpp::Cmds::frame" è seguito da un elenco di opzioni a lettera singola di
i builtin (al massimo "qw(fi I ​​o O rs)"). Anche se specifichi la tua opzione
sovrascrivendo uno di questi, si dà ancora la singola lettera dell'opzione standard.

Ogni propria opzione è specificata come "[qw(n nome), \$rif, argomento, sub]". I primi due
gli elementi sono nome breve e lungo, seguito dal riferimento variabile e facoltativamente da
un booleano per decidere se accettare un argomento. Senza un argomento, la variabile è
incrementato ogni volta che viene data l'opzione, altrimenti il ​​valore dell'opzione viene memorizzato in essa.

sub c_my_ocmd { # Tipico caso di output
locale @ARGV = @_;
Mpp::Cmds::frame {

... stampa qualcosa qui con @ARGV, con le opzioni già rimosse automaticamente

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

sub c_my_icmd { # Tipico caso di input con 2 opzioni
locale @ARGV = @_;
mio($corto, $lungo);
Mpp::Cmds::frame {

... fai qualcosa qui con <>

} qw(i I rs), # s specifica solo --separator, non -s
[qw(s short), \$short], # Nessuna opzione arg -> $short == 1
[qw(l long), \$long, 1, sub { warn "got arg $long"}];
}

Ecco un semplice comando che mette in maiuscolo solo il primo carattere di ogni input
record (equivalente a "&sed '$$_ = "\u\L$$_"'"):

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

All'interno del blocco gestito da frame, puoi avere blocchi nidificati per eseguire operazioni critiche
operazioni, come l'apertura di altri file.

Mpp::Cmds::esegui { ... } 'messaggio';

Questo produrrà un messaggio con "--verbose" (che ogni comando accetta) se il
comando è stato eseguito con successo. Ma se il blocco viene valutato come falso, muore con
messaggio negato.

eseguire il copione argomenti ...
Questa è una normale funzione Perl che puoi usare in qualsiasi contesto Perl all'interno del tuo makefile.
È simile alla forma multi-argomento del sistema, ma esegue lo script Perl all'interno
il processo in corso. Per le istruzioni makepp, la funzione perl o le tue funzioni
questo è il processo che esegue makepp. Ma per una regola che è il sottoprocesso in esecuzione
esso. Lo script viene analizzato tutte le volte che viene chiamato, ma puoi mettere il real
lavorare in una libreria, come fa pod2html. Questa libreria può quindi essere utilizzata al livello più alto, quindi
che è già presente:

perl { use mylib } # viene reindirizzato a tutte le regole che non devono essere analizzate

%.nella
makeperl { esegui qw'myscript -o $(output) $(input)' }

Se lo script chiama "exit", chiude i descrittori di file standard o si affida al sistema
per ripulire dopo di esso (file aperti, memoria...), questo può essere un problema con "run". Se
chiami "run" all'interno delle istruzioni o la funzione perl, makepp può essere disturbato o il
la pulizia avviene solo alla fine di makepp.

Se hai uno dei suddetti problemi, esegui lo script esternamente, ovvero come da
invece la riga di comando. All'interno di una regola la pulizia è meno problematica, soprattutto no
come ultima azione di una regola, poiché il sottoprocesso della regola uscirà comunque in seguito,
tranne su Windows.

scrittura il tuo proprio firma metodi
A volte vuoi che makepp calcoli un metodo di firma usando una tecnica diversa. Per
esempio, supponiamo di avere un binario che dipende da una libreria condivisa. Di solito, se tu
cambia la libreria condivisa, non devi ricollegare gli eseguibili che dipendono da essa perché
il collegamento viene eseguito in fase di esecuzione. (Tuttavia, è possibile che ricollegando l'eseguibile
potrebbe essere necessario, motivo per cui non l'ho impostato come predefinito.) Cosa vuoi makepp
da fare è avere la stessa firma per la libreria condivisa anche se cambia.

Questo può essere realizzato in diversi modi. Il modo più semplice è creare il tuo nuovo
metodo signature (chiamiamolo "shared_object"). Useresti questo metodo di firma
solo su regole che collegano i binari, come questo:

mioprogramma: *.o lib1/lib1.so lib2/lib2.so
: firma oggetto_condiviso
$(CC) $(input) -o $(output)

Ora dobbiamo creare il metodo della firma.

Tutti i metodi di firma devono essere la propria classe e la classe deve contenere alcuni speciali
elementi (vedi Mpp/Signature.pm nella distribuzione per i dettagli). Il nome della classe deve essere
preceduto da "Mpp::Signature::", quindi in questo caso dovrebbe essere chiamata la nostra classe
"Mpp::Firma::oggetto_condiviso". Dobbiamo creare un file chiamato oggetto_condiviso.pm e metti
in un file Mpp::Firma directory da qualche parte nel percorso include di Perl; il posto più facile
potrebbe essere nel Mpp/Firma directory nell'installazione di makepp (ad es.
/usr/local/share/makepp/Mpp/Signature o dove l'hai installato).

Per dettagli precisi su ciò che deve andare in questa classe, dovresti guardare attentamente
il file Mpp/Firma.pm e probabilmente anche Mpp/Firma/exact_match.pm nel trucco
distribuzione. Ma nel nostro caso, tutto ciò che vogliamo fare è apportare una piccolissima modifica a un
meccanismo di firma esistente; se il file è una libreria condivisa, vogliamo avere una costante
firma, mentre se il file è qualcos'altro, vogliamo fare affidamento sul normale di makepp
meccanismo di firma Il modo migliore per farlo è ereditare da
"Mpp::Signature::c_compilation_md5", che è il metodo di firma solitamente scelto
quando makepp riconosce un comando di collegamento.

Quindi il file Mpp/Firma/oggetto_condiviso.pm potrebbe contenere quanto segue:

usare rigorosamente;
pacchetto Mpp::Signature::shared_object;
usa Mpp::Firma::c_compilation_md5;
il nostro @ISA = qw(Mpp::Signature::c_compilation_md5); # Indica l'ereditarietà.
il nostro $oggetto_condiviso = benedici \@ISA; # Un pezzo di magia che aiuta makepp a trovare
# le subroutine per questo metodo. Tutto
# metodi di firma devono avere uno di questi.
# Il valore non viene utilizzato, solo un oggetto.
# Ora ecco il metodo che viene chiamato quando abbiamo bisogno della firma di
# qualsiasi destinazione o dipendenza per cui è attivo questo metodo di firma:
sottofirma {
my ($self, # Questo sarà lo stesso di $shared_object.
$info) = @_; # Una struttura speciale che contiene tutto
# makepp conosce questo file. Vedere
# Mpp/File.pm per i dettagli.

if ($finfo->{NAME} =~ /\.s[oa]$/) { # Il nome del file termina con .so o .sa?
return $finfo->file_exists ? 'esiste': '';
# Restituisci sempre la stessa firma se il file
# esiste. In questo caso la firma è il
# stringa "esiste".
}

Mpp::Firma::c_compilation_md5::firma;
# Se il file non termina con .so o .sa,
# delegato al solito metodo di firma di makepp.
}

Questo file è fornito come esempio nella distribuzione makepp, con alcune aggiunte
commenti.

Per inciso, perché non lo rendiamo predefinito? Bene, ci sono momenti in cui cambiare a
la libreria condivisa richiederà un ricollegamento del tuo programma. Se mai cambi o il
simboli che definisce una libreria condivisa, o i simboli che dipende da altre librerie
perché a volte può essere necessario un ricollegamento.

Supponiamo, ad esempio, che la libreria condivisa invochi alcune subroutine che il tuo programma
fornisce. Ad esempio, supponiamo di modificare la libreria condivisa in modo che ora chiami un esterno
sottoprogramma "xyz()". A meno che tu non usi l'opzione "-E" o "--export-dynamic" per il linker
(per GNU binutils; altri linker hanno nomi di opzioni diversi), il simbolo "xyz()" potrebbe non essere
essere accessibile al linker di runtime anche se esiste nel tuo programma.

Ancora peggio, supponi di aver definito "xyz()" in un'altra libreria (chiamala libxyz), come questo:

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

Poiché "libxyz" è a .a file e non a .così file, quindi "xyz()" potrebbe non essere inserito
correttamente da libxyz.a a meno che tu non ricollega il tuo binario.

I metodi Mpp::Signature controllano anche non solo la stringa utilizzata per determinare se a
file è cambiato, ma l'algoritmo utilizzato per confrontare le stringhe. Ad esempio, il
il metodo della firma "target_newer" nella distribuzione makepp richiede semplicemente che il
i target siano più recenti delle dipendenze, mentre il metodo della firma "exact_match" (e
tutto ciò che dipende da esso, come "md5" e "c_compilation_md5") richiede che il
file hanno la stessa firma dell'ultima build.

Ecco alcuni altri tipi di metodi di firma che potrebbero essere utili per aiutarti a realizzare
Le possibilità. Se lo scopo è abbastanza generico, alcuni di questi potrebbero alla fine essere
incorporato in makepp:

· Un metodo di firma per le librerie condivise che restituisce un checksum di tutti gli esportati
simboli, e anche tutti i simboli di cui ha bisogno da altre librerie. Questo risolve il
problema con l'esempio precedente e garantisce un collegamento corretto in tutte le circostanze.
È stato fatto un tentativo sperimentale per farlo nella distribuzione makepp (vedi
Mpp/Firma/oggetto_condiviso.pm), ma funzionerà solo con binutils GNU ed ELF
biblioteche in questo momento.

· Un metodo di firma che ignora un timbro data scritto in un file. Ad esempio, se tu
generare un .c file automaticamente utilizzando un programma che insiste nel mettere una stringa
in questo modo:

static char * date_stamp = "Generato automaticamente il 01 aprile 2004 da nessuno";

potresti scrivere un metodo di firma che ignori specificamente i cambiamenti nei timbri della data.
Pertanto, se il timbro della data è l'unica cosa che è cambiata, makepp non verrà ricostruito.

· Un metodo di firma che calcola le firme nel modo normale, ma ignora il
dipendenza dall'architettura quando si decide se ricostruire. Questo potrebbe essere utile per
file veramente indipendenti dall'architettura; attualmente se costruisci su un'architettura,
makepp insisterà nel ricostruire anche i file indipendenti dall'architettura quando si cambia
ad una diversa architettura.

· Un metodo di firma che sa ignorare i commenti nei file latex, in quanto
Il metodo "c_compilation_md5" sa come ignorare i commenti nei file C.

· Un metodo di firma per l'estrazione automatica della documentazione che esegue il checksum solo per il
commenta che un estrattore di documentazione ha bisogno e ignora altre modifiche alla fonte
file.

Incompiuto
Questo documento non è ancora finito. Dovrebbe spiegare come scrivere i propri scanner per
includere file e cose del genere.

Usa makepp_extending online usando i servizi onworks.net


Server e workstation gratuiti

Scarica app per Windows e Linux

Comandi Linux

Ad