¿Cómo se especifica en un script Makefile.am que sólo quiero compilar objeto .o archivos?
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?
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.
-
No utilice un
src/ctrnn/Makefile.am
, acaba de hacer referencia a los archivos de origen subdirectorio de susrc/Makefile.am
:bin_PROGRAMS = foo foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp
Tenga en cuenta que esto va a construirnetwork.o
yneuron.o
en el mismo directorio quemain.o
. Si desea que los objetos en subdirectorios,AUTOMAKE_OPTIONS = subdir-objects
. -
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 ensrc/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 prefijonoinst_
): 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 porcrtnn/libcrtnn.a
crtnn/network.o
ycrtn/neuro.o
al vincularfoo
. -
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
yautoreconf
vuelva a ejecutar para instalar los archivos libtool. A continuación, puede actualizarsrc/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
ysrc/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