2009-05-27 22 views
5

Ho un progetto gestito da autoconf C++ che sto adattando per compilare su host FreeBSD. Il sistema originale era Linux, quindi ho creato un AM_CONDITIONAL per distinguere l'host che sto costruendo e separare il codice in file specifici del sistema.Automake e file con lo stesso nome

configure.ac

 

AC_CANONICAL_HOST 
AM_CONDITIONAL([IS_FREEBSD],false) 
case $host in 
     *free*)  
      AC_DEFINE([IS_FREEBSD],[1],[FreeBSD Host]) 
      AM_CONDITIONAL([IS_FREEBSD],true) 
      BP_ADD_LDFLAG([-L/usr/local/lib]) 
       ;; 
esac 

Makefile.am

 

lib_LTLIBRARIES=mylib.la 
mylib_la_SOURCES=a.cpp \ 
       b.cpp 

if IS_FREEBSD 
    mylib_la_SOURCES+=freebsd/c.cpp 
else 
    mylib_la_SOURCES+=linux/c.cpp 
endif 

Quando eseguo automake, non riesce con questo tipo di messaggio:

 
Makefile.am: object `c.lo' created by `linux/c.cpp' and `freebsd/c.cpp' 

Tutte le idee su come configurare automake rispettare questo condizionale anche nel Makefile.in processo di costruzione?

Questo funziona se i file hanno nomi diversi, ma è codice C++ e sto cercando di mantenere il nome del file uguale al nome della classe.

Grazie in anticipo!

+1

C'è un errore di battitura nel Makefile.am: "IS_FREEBSD" dovrebbe leggere "se IS_FREEBSD". – adl

+0

Grazie adl, modificato –

risposta

11

Si potrebbe chiedere per gli oggetti da costruire nei rispettivi sottodirectory con

AUTOMAKE_OPTIONS = subdir-objects 
+1

Risposta perfetta, basta dire che questa è un'opzione Makefile.am! Grazie !!! –

+5

È anche possibile configurare questa opzione di automake in 'AM_INIT_AUTOMAKE ([... subdir-objects ...])' in 'configure.ac'. – ndim

+0

Perché automake crea file oggetto per il codice che non viene detto di compilare? Poiché si sta compilando su una condizione, dovrebbe prendere solo un file alla volta anche se è nello stesso nome. Ho ragione? –

7

Un'altra opzione, oltre subdir-oggetti, è quello di dare ad ogni sotto-progetto un po 'su misura per ogni singolo progetto costruire bandiere. Quando lo fai, automake cambia le sue regole di denominazione * .o per anteporre il nome del target al nome del modulo. Ad esempio, questo:

mylib_la_CXXFLAGS=$(AM_CXXFLAGS) 
mylib_la_SOURCES=a.cpp b.cpp 

si tradurrà nei file di output mylib_la-A. Ó e mylib_la-b.o, piuttosto che A. Ó e b.o. In questo modo è possibile avere due progetti diversi con la stessa directory di output, ognuno dei quali ha, ad esempio, un file b.cpp e non ha conflitti di output.

Si noti che l'ho fatto impostando il CXXFLAGS specifico del progetto sui valori che già l'automake avrebbe utilizzato, AM_CXXFLAGS. Automake non è abbastanza intelligente per rilevare questo trucco e utilizzare i nomi * .o più brevi. Se succede che hai bisogno di opzioni di costruzione per progetto, puoi farlo al posto di questo trucco.

C'è un whole list di variabili automake che, se impostato su base per-eseguibile, danno lo stesso effetto. Così, per esempio, forse un sub-progetto ha bisogno di bandiere di collegamento speciali già, quindi si dà qualcosa di simile:

mylib_la_LDFLAGS=-lfoo 

Questo vi darà i * .o file prefissati così come il trucco AM_CXXFLAGS ha fatto, solo ora si è "legittimamente" utilizzando questa funzione, invece di ingannare automake nel farlo.

A proposito, è un cattivo stile di autoconf per modificare il modo in cui il programma si basa esclusivamente sul sistema operativo per cui è stato creato. Il buon stile di autoconf è quello di controllare solo per specifiche funzionalità della piattaforma, non intere piattaforme, perché le piattaforme cambiano. FreeBSD potrebbe essere un certo modo oggi, ma forse nella prossima versione copierà una funzionalità di Linux che cancellerebbe la necessità per te di costruire il tuo programma in due modi diversi. Oppure, forse la funzionalità che stai usando oggi è deprecata e verrà eliminata nella prossima versione.

Ci sono quaranta anni di saggezza di programmazione portatile Unix negli autotools, grasshopper.I "maybes" che ho dato sopra hanno avuto il in passato e lo faranno di nuovo. Testare le singole funzionalità è il modo più agile per far fronte a piattaforme in costante cambiamento.

È possibile ottenere bonus inaspettati anche da questo approccio. Ad esempio, forse il tuo programma ha bisogno di due funzioni non portatili per fare il suo lavoro. Dì che su FreeBSD, queste sono le funzioni A e B, e su Linux, sono le caratteristiche X e Y; A e X sono meccanismi simili ma con interfacce diverse, e lo stesso per B e Y. Potrebbe essere che la caratteristica A provenga dai BSD originali, ed è in Solaris perché ha radici BSD da SunOS negli anni 80 e Solaris ha anche caratteristica Y dalla sua riprogettazione basata su System V nei primi anni '90. Provando per queste funzionalità, il tuo programma potrebbe essere eseguito anche su Solaris, perché ha le funzionalità di cui ha bisogno il tuo programma, ma non nella stessa combinazione di FreeBSD e Linux.

+4

+1 per "verifica funzionalità, non piattaforme". –

Problemi correlati