2013-11-27 17 views
8

Sto lavorando a un progetto C++ che utilizza autoconf & automake e non riesco a impostare correttamente i percorsi di inclusione in *CPPFLAGS. Ho letto circa 3 ore di documenti e non riesco ancora a capirlo. Non sto cercando un trucco, ma per il modo corretto di farlo. Ecco il mio enigma.come impostare i percorsi con gli autotools

come la vedo io, ci sono 3 fonti completamente diverse per percorsi di inclusione:

  1. librerie esterne che devono essere installati insieme con il mio pacchetto, che sono configurati per configure --with-XXX=<PATH>.
  2. All'interno del mio pacchetto, alcuni file di origine usano #include <file.h> anche quando file.h fa parte del pacchetto, quindi per compilarli, devo impostare correttamente il percorso di inclusione. (Nota, non è un'opzione per modificare tutti questi file.)
  3. Gli stravaganti standard (o non) specificano che l'utente deve essere autorizzato a specificare i propri percorsi di inclusione (extra). Cioè, non dovrei impostare CPPFLAGS affatto.

Nella mia configurazione attuale:

  • tipo 1 percorsi sono impostati all'interno configure.ac da AC_SUBST(CPPFLAGS, "$CPPFLAGS -I<path>").
  • I percorsi di tipo 2 sono impostati all'interno di Makefile.am entro il test_CPPFLAGS = -I<path>.
  • Il tipo 3 non può essere impostato. Più esattamente, se l'utente imposta CPPFLAGS prima di eseguire make, sostituisce le impostazioni di Tipo 1, causando il fallimento della compilazione. Ovviamente, l'utente potrebbe provare a utilizzare CXXFLAGS invece, ma quello ha un uso diverso (ricorda, sto chiedendo il modo corretto di farlo, non un trucco).

Ho provato a risolvere questo problema impostando i percorsi di tipo 1 utilizzando AM_CPPFLAGS all'interno di configure.ac. (Per riferimento: se si imposta CPPFLAGS invece di CPPFLAGS, ma è necessario eseguire alcuni controlli, ad esempio AC_CHECK_HEADERS, è necessario impostare temporaneamente CPPFLAGS e quindi ripristinarlo affinché gli assegni funzionino, questo è spiegato here.) Questo libera CPPFLAGS per i percorsi di tipo 3, ma sfortunatamente la compilazione fallisce perché il Makefile -s che viene prodotto da configure utilizza solo AM_CPPFLAGS se non esiste uno special <target>_CPPFLAGS specializzato. Quindi, se test_CPPFLAGS esiste con un percorso di tipo 2, la compilazione di test avrà esito negativo perché non ottiene il percorso di tipo 1.

Una correzione sarebbe specificare all'interno di Makefile.am per utilizzare sempre AM_CPPFLAGS. Ma è questo "dal libro"? Posso farlo in modo globale o devo modificare ogni singolo target_CPPFLAGS? Esiste un'altra soluzione "corretta"?

+0

Con "capriccioso", si include la documentazione ufficiale di autoconf che indica chiaramente che CPPFLAGS è una variabile utente non dovrebbe essere modificata dal manutentore? (Vedere la sezione 4.8.1 a http://www.gnu.org/software/autoconf/manual/autoconf.html) –

+0

Anche se un esempio meno ambiguo dalla documentazione di automake ufficiale può essere più chiaro, che afferma "Non si dovrebbe mai ridefinire un variabile utente come CPPFLAGS in Makefile.am. " nella sezione 27.6 di http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html#Flag-Variables-Ordering –

risposta

18

So che è difficile ottenere una risposta diretta dai manuali degli autotools. Ci sono un paio di buoni tutorial dall'inizio alla fine here e here.

Non esiste una variabile standard per il pacchetto specifico *CPPFLAGS in autoconf. configure può essere richiamato con CPPFLAGS=... e automake aggiungerà questo CPPFLAGS alle regole di makefile pertinenti: cercare CPPFLAGS in un file Makefile.in per gli esempi.Per questo motivo, ti suggerisco di non utilizzare questa variabile per nient'altro.

Aggiungere flag in Makefile.am alla variabile AM_CPPFLAGS (il valore predefinito per tutte le chiamate del preprocessore) o ignorare i singoli flag del preprocessore con target_CPPFLAGS. Nell'esempio di una libreria di terze parti, è meglio usare un nome come: FOO_CPPFLAGS per contenere le opzioni del preprocessore, per esempio,

FOO_CPPFLAGS="-I${FOO_DIR}/include -DFOO_BAR=1" 
... 
AC_SUBST(FOO_CPPFLAGS) 

e nel Makefile.am:

AM_CPPFLAGS = -I$(top_srcdir) $(FOO_CPPFLAGS) 
# or: 
target_CPPFLAGS = -I$(top_srcdir) $(FOO_CPPFLAGS) 

La variabile top_srcdir è definito da configure - Lo uso per illustrare il secondo caso. Supponiamo che tu abbia file.h in un'altra directory other, nella directory di livello superiore. -I$(top_srcdir) consente di includerlo come <other/file.h>. In alternativa, -I$(top_srcdir)/other consentirebbe di includerlo come <file.h>.

Un altro utile preset variable è srcdir - la directory corrente. -I$(srcdir) viene aggiunto a AM_CPPFLAGSper impostazione predefinita. Quindi se file.h si trova nella directory corrente, puoi includerlo con <file.h> o anche con "file.h". Se other era una directory "fratello", -I$(srcdir)/.. consentirebbe di includere <other/file.h> e -I$(srcdir)/../other consentirebbe <file.h>.


Vorrei anche aggiungere che alcuni pacchetti installare una pkg-config .pc file. Se l'installazione di pkg-config è impostata per cercare le directory corrette, è possibile che la macro PKG_CHECK_MODULES sia molto utile.

+2

Un altro è '$ (builddir)' o '$ (top_builddir) 'che apparentemente è pensato per essere utilizzato per tutti i file generati durante una compilazione. – CMCDragonkai

Problemi correlati