2010-02-16 11 views
12

Tengo un Makefile.am que será responsable de la construcción de una binaria aplicación final:¿Cómo especifico en una secuencia de comandos Makefile.am que solo quiero compilar archivos .o de objetos que pueden vincularse posteriormente?

proyecto/src/Makefile.am

también en el directorio src es un sub-directorio llamado ctrnn que contiene una mayor Makefile.am:

proyecto/src/ctrnn/Makefile.am

Ahora, ctrnn/Makefile.am sólo debe generar objeto .o archivos con la idea de que el nivel superior Makefile.am debe utilizar el archivos de objeto generados en el subdirectorio ctrnn para construir el binario.

Este es el ctrnn/Makefile.am

SOURCES = network.cpp\ 
    neuron.cpp 

AM_CPPFLAGS= @[email protected] 

Sobre la base de este archivo Makefile.am, quiero terminar con network.o y neuron.o. Estoy generando el Makefile según usando automake etc, pero cuando intento y luego ejecutar el archivo de marca, que no hace nada y se limita a decir:

hacer: nada que hacer para `todo'

I saber por qué es esto, necesito especificar el objetivo de compilación. Pero, ¿cómo hago esto en el script ctrnn/Makefile.am dado que no quiero construir un archivo binario que requiera bin_PROGRAMS sino archivos de objetos reales network.o y neuron.o?

(Tenga en cuenta que si especifico un nombre bin_PROGRAMS, con razón termina quejándose de una referencia indefinida a main).

¿Qué hago mal?

Gracias, Ben.

Respuesta

25

Automake no puede construir objetos sin un objetivo explícito (programa, biblioteca) que utilizará estos objetos. Una razón es que las opciones de compilación se especifican por objetivo. Si dos objetivos, p. dos binarios usan el mismo objeto pero tienen una opción de compilación diferente, el mismo objeto puede tener que compilarse dos veces.

Tiene tres formas de hacer lo que quiere, todas implican vincular sus archivos de origen a algún objetivo.

  1. No utilice una src/ctrnn/Makefile.am, acaba de hacer referencia a los archivos de origen subdirectorio de su src/Makefile.am:

     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp 
    
    Tenga en cuenta que este construirá network.o y neuron.o en el mismo directorio que main.o. Si desea objetos en subdirectorios, use AUTOMAKE_OPTIONS = subdir-objects.

  2. Utilice una biblioteca de conveniencia. En src/crtnn/Makefile.am hacer una biblioteca de sus dos objetos:

     
    noinst_LIBRARIES = libcrtnn.a 
    libcrtnn_a_SOURCES = network.cpp neuron.cpp 
    
    y en src/Makefile.am, enlazar el ejecutable a la biblioteca:
     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c 
    foo_LDADD = crtnn/libcrtnn.a 
    SUBDIRS = crtnn 
    
    Se llama "conveniencia" cuando no se va a instalar (se puede decir debido a la noinst_ prefijo): se solo se usa durante la compilación. Y esta es una biblioteca estática, por lo que el resultado es el mismo que si hubiera reemplazado crtnn/libcrtnn.a por crtnn/network.o y crtn/neuro.o al vincular foo.

  3. Utilice una biblioteca de conveniencia de Libtool. Esto requiere más configuración si no está usando Libtool ya. Debería agregar una llamada LT_INIT en configure.ac y ejecutar nuevamente autoreconf para instalar los archivos libtool. Luego puede actualizar src/crtnn/Makefile.am para hacer una biblioteca de sus dos objetos de la siguiente manera:

     
    noinst_LTLIBRARIES = libcrtnn.la 
    libcrtnn_la_SOURCES = network.cpp neuron.cpp 
    
    y src/Makefile.am de la siguiente manera:
     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c 
    foo_LDADD = crtnn/libcrtnn.la 
    SUBDIRS = crtnn 
    
    ¿Cuál es la diferencia? puedes preguntar, casi ninguno. Una ventaja del uso de las bibliotecas de conveniencia de Libtool es que se pueden anidar: una biblioteca Libtool puede incluir otra biblioteca Libtool (esto es conveniente cuando se tiene una jerarquía profunda de código fuente y se está creando una biblioteca en cada nivel). También las bibliotecas de conveniencia de Libtool se pueden usar para construir una biblioteca compartida si lo desea. Las bibliotecas estáticas de Automake no pueden.

+1

¡Gracias! Terminé usando el método libtool, funciona perfectamente :-) –

+2

Gracias por ayudarme esforzándome en el infierno autotools/libtool. Y haznos un favor a todos: vive mucho y prospera! – rockdaboot

+0

foo_LDADD? No se supone que es foo_LIBADD –

2

Usted simplemente puede especificar los archivos de origen en el proyecto/src/Makefile.am y no tener un Makefile.am en ctrnn:

 
maude_SOURCES = ctrnn/network.cpp ctrnn/neuron.cpp 

o puede utilizar una biblioteca libtool conveniencia. En ctrnn/Makefile.am, puso:

 
noinst_LTLIBRARIES = libctrnn.la 
libctrnn_la_SOURCES = network.cpp neuron.cpp 

y en src/Makefile.am, poner

 
LDADD = ctrnn/libmylib.la 

Si no está utilizando libtool, también tendrá que añadir a LT_INIT configure.ac.

0

Mejor aún, usted podría forzar una marca utilizando un origen destino, menos al hacer esto:

SUBDIRS = sub1 sub2 … 
lib_LTLIBRARIES = libtop.la 
libtop_la_SOURCES = 
# Dummy C++ source to cause C++ linking. 
nodist_EXTRA_libtop_la_SOURCES = dummy.cxx 
libtop_la_LIBADD = \ 
    sub1/libsub1.la \ 
    sub2/libsub2.la \ 
... 

La salsa secreta es nodist_EXTRA_xxxx_la_SOURCES.

Más detalles aquí: https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html

Cuestiones relacionadas