2012-11-28 9 views
7

Ho un progetto di autotools che si compila bene sul Mac, ma sotto Linux (Ubuntu 12.04.1 LTS) le righe di comando passate a gcc hanno le librerie fuori uso rispetto all'oggetto File. Ad esempio, autotools genera il seguente comando per compilare il mio codice, un singolo file denominato test.c in un binario chiamato test:Correggere l'ordinamento della riga di comando GCC utilizzando Automake

gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -O2 -lglib-2.0 -o test test-test.o 

Questa riga di comando viene a mancare con:

/home/user/glib-test/test.c:4: undefined reference to `g_malloc` 
/home/user/glib-test/test.c:5: undefined reference to `g_free` 

Tuttavia, se compilo da la riga di comando e passare in su in modo che il riferimento alla libreria viene dopo i file di oggetto funziona bene:

gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -O2 -o test test-test.o -lglib-2.0 

l'i sfida s che non riesco a capire come forzare Autotools per generare la riga di comando nel giusto ordine. Per motivi di chiarezza, ho riprodotto qui il semplice caso di test. Il primo è configure.ac:

dnl Process this file with autoconf to produce a configure script. 

AC_PREREQ(2.59) 
AC_INIT(glib-test, 1.0) 

AC_CANONICAL_SYSTEM 
AM_INIT_AUTOMAKE() 

AC_PROG_CC 
AM_PROG_CC_C_O 
PKG_CHECK_MODULES(GLIB, glib-2.0 > 2.0) 
AC_CONFIG_FILES(Makefile) 
AC_OUTPUT 

successivo è il semplice Makefile.am:

CFLAGS=-Wall 
bin_PROGRAMS=test 
test_CFLAGS=$(GLIB_CFLAGS) 
test_LDFLAGS=$(GLIB_LIBS) 
test_SOURCES=test.c 

Infine, il codice sorgente per questo test minimale, test.c:

#include <glib.h> 

int main(int argc, char **argv) { 
    gchar *foo = g_malloc(100); 
    g_free(foo); 
    return 0; 
} 

compilazione viene quindi ottenuta utilizzando la seguente serie di comandi:

touch NEWS README AUTHORS ChangeLog 
aclocal 
autoconf 
automake --add-missing 
./configure 
make 

Dovrei essere chiaro, capisco perché il mio codice non verrà compilato, mi sto solo chiedendo come ottenere automake per mettere le librerie alla fine della riga di comando in modo che gcc venga eseguito e collegato correttamente. Va notato che gcc su Mac OS X Lion non sembra presentare questo problema.

+1

"gcc su Mac OS X Lion non sembra avere questo problema." - no, perché Apple utilizza un fork di GCC 4.2, mentre questo comportamento è stato introdotto in una versione più recente di GCC (IIRC in GCC 4.5). –

risposta

10

La soluzione è risultata essere la differenza tra LDFLAGS e LDADD. In breve, LDFLAGS viene aggiunto prima dei file oggetto sulla riga di comando e in seguito viene aggiunto LDADD. Così, cambiando Makefile.am al seguente risolto il problema:

CFLAGS=-Wall 
bin_PROGRAMS=test 
test_CFLAGS=$(GLIB_CFLAGS) 
test_LDADD=$(GLIB_LIBS) 
test_SOURCES=test.c 

ci sono voluti solo rintracciare uno sviluppatore GCC al lavoro per risolvere. Inoltre, questo esempio che ho fornito è piuttosto scadente perché test ha un significato definito in alcuni contesti di autotools.

+2

Si noti che la documentazione di automake indica chiaramente che LDADD è il posto sbagliato per i flag '-l'. Sebbene funzioni, non ha un buon odore. –

+3

@William: Il documento Automake dice che "PROG_LDADD" non è appropriato per passare flag di linker specifici del programma (** tranne ** per '-l',' -L', '-dlopen' e' -dlpreopen'). " – adl

+0

@adl L'eccezione nella documentazione non appare nella documentazione per 1.11.1 (sezione 8.1.2). Sai perché questa eccezione è stata accettata? O era sempre ok, solo non documentato? –

0

Ho risolto un problema simile. Lo script ./configure in questione non è stato in grado di completare un controllo per la presenza di una funzione a causa di un simbolo mancante. Se ho aggiunto la libreria corretta a $LDFLAGS o simile, è stata aggiunta prima del file .c e la libreria è stata ignorata.

I nomi delle funzioni per controllare vengono dapprima aggiunti ac_func_list e poi c'è un ciclo nel corpo del ./configure che per ognuno di essi chiamate ac_fn_c_check_func() e che a sua volta richiama ac_fn_c_try_link()

la funzione di controllo ac_fn_c_try_link() utilizza un comando di questo modello:

ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS \ 
     $LDFLAGS conftest.$ac_ext $LIBS >&5' 

$LDADD viene completamente ignorata qui. Pertanto l'unica soluzione qui è aggiungere i flag -l alla variabile $LIBS.

Problemi correlati