Come evitare di ridefinire VERSIONE, PACCHETTO, ecc
Domanda
Non ho visto nessuna domanda relativa alle build GNU autoconf/automake, ma spero che almeno alcuni di voi là fuori lo conoscano.Ecco qui:
Ho un progetto (lo chiamerò il mio progetto) che include un altro progetto (fornitore).Il progetto del fornitore è un progetto autonomo gestito da qualcun altro.Includere un progetto come questo è giusto semplice, ma in questo caso c'è un piccolo intoppo:ogni progetto genera il proprio config.h
file, ognuno dei quali definisce macro standard come PACKAGE, VERSION, ecc.Ciò significa che, durante la compilazione, quando viene creato il fornitore, ricevo molti errori come questo:
... warning: "VERSION" redefined
... warning: this is the location of the previous definition
... warning: "PACKAGE" redefined
... warning: this is the location of the previous definition
Questi sono solo avvertimenti, almeno per il momento, ma vorrei sbarazzarmene.L'unica informazione rilevante che sono riuscito a trovare con una ricerca su Google è Questo thread sulla mailing list di automake, il che non è di grande aiuto.Qualcun altro ha qualche idea migliore?
Soluzione
Alcune note:
- non hai detto come
config.h
è stato incluso - tra virgolette o parentesi angolari.Vedere quest'altra domanda per ulteriori informazioni sulla differenza.In breve,config.h
è tipicamente incluso tra virgolette, non tra parentesi angolari, e questo dovrebbe far sì che il preprocessore preferisca il fileconfig.h
dalla directory del progetto (che di solito è ciò che desideri) - Dici che un sottoprogetto dovrebbe includere quello del progetto allegato
config.h
Normalmente questo non è affatto quello che vuoi.Il sottoprogetto è autonomo e il suo PACKAGE e VERSION dovrebbero essere quelli di quel sottoprogetto, non i tuoi.Se includi libxml nel tuo progetto xmlreader, ad esempio, vorresti comunque che il codice libxml fosse compilato con PACKAGE libxml e VERSION (qualunque sia la versione libxml). - Di solito è un grosso errore avere
config.h
essere incluso dalle intestazioni pubbliche.config.h
è sempre privato per il tuo progetto o sottoprogetto e deve essere incluso solo da file .c.Pertanto, se la documentazione del tuo fornitore dice di includere il loro "vendor.h" e l'intestazione pubblica includeconfig.h
in qualche modo, allora è un no-no.Allo stesso modo, se il tuo progetto è una libreria, non includerloconfig.h
ovunque dalle intestazioni installate pubblicamente.
Altri suggerimenti
È sicuramente un hack, ma ho post-elaborato l'autogen config.h
file:
sed -e 's/.*PACKAGE_.*//' < config.h > config.h.sed && mv config.h.sed config.h
Questo è tollerabile nel nostro ambiente di costruzione, ma sarei interessato a un modo più pulito.
Si scopre che nel mio caso c'era una soluzione molto semplice.Il progetto del fornitore raccoglie diversi file di intestazione in un file di intestazione monolitico, che è quindi #include
d dalle fonti del fornitore.Ma la regola make che crea l'intestazione monolitica includeva accidentalmente il file generato config.h
.La presenza del PACCHETTO, DELLA VERSIONE, ecc.Le variabili di configurazione nell'intestazione monolitica sono ciò che causava gli avvisi di ridefinizione.Si scopre che quello del venditore config.h
era irrilevante, perché "config.h" si risolveva sempre in $(top_builddir)/config.h
.
Credo che questo sia il modo in cui dovrebbe funzionare.Per impostazione predefinita, un sottoprogetto dovrebbe includere il progetto che lo racchiude config.h
invece del proprio, a meno che il sottoprogetto non includa esplicitamente il proprio, o manipoli il percorso INCLUDE in modo che la propria directory venga prima $(top_builddir)
, o manipola in altro modo i file di intestazione come nel mio caso.