Domanda

Come posso memorizzare un numero di versione in una libreria statica (file.a) e successivamente verificarne la versione in Linux?

P.S. Ho bisogno della possibilità di controllare la versione del file in qualsiasi momento senza alcun eseguibile speciale utilizzando solo dalle utility della shell.

È stato utile?

Soluzione

Forse potresti creare una stringa con la versione in questo modo:

char* library_version = { "Version: 1.3.6" };

e per poterlo controllare dalla shell basta usare:

strings library.a | grep Version | cut -d " " -f 2

Altri suggerimenti

Oltre a fornire una stringa statica come indicato da Puppe, è pratica comune fornire una macro per recuperare la verifica della versione per compatibilità. Ad esempio, potresti avere le seguenti macro (dichiarate in un file di intestazione da utilizzare con la tua libreria):

#define MYLIB_MAJOR_VERSION 1
#define MYLIB_MINOR_VERSION 2
#define MYLIB_REVISION 3
#define MYLIB_VERSION "1.2.3"
#define MYLIB_VERSION_CHECK(maj, min) ((maj==MYLIB_MAJOR_VERSION) && (min<=MYLIB_MINOR_VERSION))

Nota con la macro MYLIB_CHECK_VERSION , presumo che tu voglia un giro maggiore specifico e un giro minore maggiore o uguale alla versione desiderata. Modifica come richiesto per la tua applicazione.

Quindi usalo da un'applicazione chiamante, qualcosa del tipo:

if (! MYLIB_VERSION_CHECK(1, 2)) {
    fprintf(stderr, "ERROR: incompatible library version\n");
    exit(-1);
}

Questo approccio farà sì che le informazioni sulla versione provengano dal file di intestazione incluso. Inoltre, sarà ottimizzato in fase di compilazione per l'applicazione chiamante. Con un po 'più di lavoro, puoi estrarlo dalla libreria stessa. Continua a leggere ...

Puoi anche usare queste informazioni per creare una stringa statica memorizzata nella tua libreria, come menzionato da Puppe. Inserisci qualcosa del genere all'interno della tua libreria:

struct {
    const char* string;
    const unsigned major;
    const unsigned minor;
    const unsigned revision;
} mylib_version = {
    MYLIB_VERSION, MYLIB_MAJOR_VERSION, MYLIB_MINOR_VERSION, MYLIB_REVISION
};

Questo creerà una struttura chiamata mylib_version nella tua libreria. Puoi usarlo per fare ulteriori verifiche creando funzioni all'interno della tua libreria e accedendo a quelle da un'applicazione chiamante, ecc.

Creazione di una nuova risposta basata sulla modifica ... Solo per evitare confusione :)

Se stai cercando un modo senza codice per risolvere il problema, puoi provare questo. È (ancora una volta) un'alternativa all'approccio stringhe definito da Puppe.

Forse potresti semplicemente toccare un file chiamato versione_1.2.3 e aggiungerlo all'archivio. Quindi, è possibile determinare la versione cercando il file versione utilizzando il comando ar:

ar t libmylib.a | grep 'version_' | sed -e 's/^version_//'

Non sono sicuro che ti fornirà ciò di cui hai bisogno, ma non esiste un metodo standard per incorporare metadati come questo in un archivio. Forse troverai altre informazioni che desideri memorizzare in questo "metafile" per l'archivio.

Più volte è stato menzionato man 1 ident , quindi ecco i dettagli sull'uso di quel metodo.

ident è un comando fornito con RCS (Revision Control System), ma potrebbe anche essere disponibile se si utilizza CVS (Concurrent Versions System) o Subversion.

Lo useresti in questo modo (clonato dalla pagina man):

#include <stdio.h>
static char const rcsid[] =
    "$Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp 
ident f.c f.o
quot;; int main() { return printf("%s\n", rcsid) == EOF; }

e f.c sono compilati in f.o, quindi il comando

   f.c:
       $Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp $
   f.o:
       $Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp $

verrà emesso

#include <stdio.h>
#define VERSION_STR "5.4"
#define CONFIG "EXP"
#define AUTHOR "eggert"
static char const sccsid[] =
    "@(#) " CONFIG " v " VERSION_STR " " __DATE__ " " __TIME__ " " AUTHOR;
int main() { return printf("%s\n", sccsid) == EOF; }

Se il tuo f.o è stato aggiunto a una libreria statica f.a , ident f.a dovrebbe mostrare un output simile. Se hai molti [az] .o costruiti nello stesso modo nel tuo az.a , dovresti trovare tutte le loro stringhe nel file az.a .

CAVEAT: Solo perché si trovano nel file .a non significa che saranno inclusi nel file del programma. A meno che il programma non li faccia riferimento, il linker non vede la necessità di includerli. Quindi di solito devi avere un metodo in ogni modulo per restituire la stringa e l'app deve chiamare quel metodo. Esistono modi per convincere la maggior parte dei linker che si tratta di un simbolo richiesto senza effettivamente fare riferimento a esso, ma dipende dal linker e va oltre lo scopo di questa risposta.

Se invece hai familiarità con SCCS (Sistema di controllo del codice sorgente), dovresti invece usare man 1 what , e sembrerebbe così (fatto con le macro per mostrare la flessibilità disponibile):

what f.c f.o

e f.c sono compilati in f.o, quindi il comando

   f.c:
       @(#) EXP v 5.4 1993/11/09 17:40:15 eggert
   f.o:
       @(#) EXP v 5.4 1993/11/09 17:40:15 eggert

verrà emesso

<*>

PS: sia ident che what sono comandi forniti con specifici sistemi centralizzati di controllo del codice sorgente. Se si utilizza un sistema di controllo del codice sorgente distribuito (come git) l'intero concetto potrebbe non avere senso. Per alcune idee che usano git vedi questa discussione: Passaggio da CVS da git: $ Id: $ equivalente? sebbene l'hash non sia lo stesso di un numero di versione. :)

Se stai usando gcc, puoi usare la direttiva #ident

#ident "Foo Version 1.2.3.4"
void foo(void){ /* foo code here */ }

Per ottenere la versione basta usare una delle seguenti opzioni:

strings -a foo.o | grep "Foo Version"
strings -a foo.a | grep "Foo Version"
strings -a foo.so | grep "Foo Version"

Questo ti permetterà di compilare la versione nella libreria con la possibilità di rimuoverla in seguito usando strip -R .comment tuo_file o ometterla completamente passando -fno-ident (Questo ometterà anche i commenti sulla versione del compilatore dagli oggetti compilati)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top