¿Cómo se especifica en un script Makefile.am que sólo quiero compilar objeto .o archivos?

StackOverflow https://stackoverflow.com/questions/2272697

  •  20-09-2019
  •  | 
  •  

Pregunta

Tengo un Makefile.am que será responsable de la construcción de una binaria aplicación final:

project/src/Makefile.am

También en el directorio src es un sub-directorio llamado ctrnn que contiene un Makefile.am adicional:

project/src/ctrnn/Makefile.am

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

Este es el ctrnn/Makefile.am:

SOURCES = network.cpp\
    neuron.cpp

AM_CPPFLAGS=  @CXXFLAGS@

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

make: Nothing to be done for `all'

Yo sé por qué esto es, que necesito para especificar el tipo de generación. Pero, ¿cómo puedo hacer esto en el guión ctrnn/Makefile.am dado que yo no quiero construir un binario que requeriría bin_PROGRAMS pero los archivos de objetos reales y network.o neuron.o?

(Nota si hago especificar un nombre bin_PROGRAMS, que con razón termina quejándose de una referencia indefinida a principal).

¿Qué soy yo mal?

¿Fue útil?

Solución

Automake no puede construir objetos sin un objetivo explícito (programa, biblioteca) que va a utilizar estos objetos. Una de las razones es que las opciones de compilación son especificados por la diana. Si dos objetivos, por ejemplo, dos binarios utilizar el mismo objeto pero tienen opción de compilación diferente, el mismo objeto puede tener que ser compilado dos veces.

Hay tres maneras de hacer lo que quiere, todos ellos implican atar los archivos de origen a algún objetivo.

  1. No utilice un 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 esto va a construir network.o y neuron.o en el mismo directorio que main.o. Si desea que los objetos en subdirectorios, 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 por el prefijo noinst_): sólo se utiliza durante la construcción. Y esto es una biblioteca estática, por lo que el resultado es el mismo que si se hubiera reemplazado por crtnn/libcrtnn.a crtnn/network.o y crtn/neuro.o al vincular foo.

  3. Utilice una biblioteca de conveniencia Libtool. Esto requiere más configuración si no está utilizando ya Libtool. Debe añadir una llamada en LT_INIT configure.ac y autoreconf vuelva a ejecutar para instalar los archivos libtool. A continuación, 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 como sigue:
    bin_PROGRAMS = foo
    foo_SOURCES = main.c
    foo_LDADD = crtnn/libcrtnn.la
    SUBDIRS = crtnn
    
    ¿Cuál es la diferencia? usted puede pedir, casi ninguno. Una de las ventajas de utilizar las bibliotecas de conveniencia Libtool es que pueden ser anidadas: una biblioteca Libtool puede incluir otra biblioteca Libtool (esto es conveniente cuando se tiene una profunda jerarquía de código fuente y se está construyendo una biblioteca en cada nivel). También las bibliotecas de conveniencia Libtool se pueden utilizar para construir una biblioteca compartida si lo desea. bibliotecas estáticas de automake no puede.

Otros consejos

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, poner:

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

y en src / Makefile.am, puesto

LDADD = ctrnn/libmylib.la

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

Mejor aún, 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 en aquí: https: // www .gnu.org / software / automake / manual / html_node / Libtool-Conveniencia-libraries.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top