Como especificar em um script makefile.am que eu só quero compilar arquivos do objeto .o?
Pergunta
eu tenho um Makefile.am
que será responsável por construir um aplicativo final binário:
project/src/Makefile.am
Também no diretório SRC está um subdiretório chamado ctrnn
que contém um adicional Makefile.am
:
project/src/ctrnn/Makefile.am
Agora, ctrnn/Makefile.am
só deve gerar objeto .o
arquivos com a ideia é que o nível superior Makefile.am
deve usar os arquivos de objeto gerados no subdiretório ctrnn
Para construir o binário.
Isto é o ctrnn/Makefile.am
:
SOURCES = network.cpp\
neuron.cpp
AM_CPPFLAGS= @CXXFLAGS@
Com base nisso Makefile.am
Arquivo, eu quero acabar com o Network.O e o Neuron.O. Estou gerando o acordo Makefile
Usando o Autorake etc, mas quando tento e executo o arquivo make, ele não faz nada e apenas diz:
make: Nothing to be done for `all'
Eu sei por que isso é, preciso especificar o destino de construção. Mas como faço isso no ctrnn/Makefile.am
script, pois não quero construir um binário que exigiria bin_PROGRAMS
Mas arquivos de objeto reais network.o
e neuron.o
?
(Observe que, se eu especificar um nome de bin_programa, ele corretamente acaba reclamando de uma referência indefinida ao principal).
O que eu vou fazer de errado?
Solução
O Autorake não pode criar objetos sem um destino explícito (programa, biblioteca) que usará esses objetos. Uma razão é que as opções de compilação são especificadas por alvo. Se dois alvos, por exemplo, dois binários usarem o mesmo objeto, mas têm opção de compilação diferente, o mesmo objeto pode ter que ser compilado duas vezes.
Você tem três maneiras de fazer o que deseja, todos envolvem amarrar seus arquivos de origem a algum destino.
Não use um
src/ctrnn/Makefile.am
, basta fazer referência aos arquivos de origem do subdiretório do seusrc/Makefile.am
:bin_PROGRAMS = foo foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp
Observe que isso vai construirnetwork.o
eneuron.o
no mesmo diretório quemain.o
. Se você deseja objetos em subdiretos, useAUTOMAKE_OPTIONS = subdir-objects
.Use uma biblioteca de conveniência. Dentro
src/crtnn/Makefile.am
Faça uma biblioteca de seus dois objetos:noinst_LIBRARIES = libcrtnn.a libcrtnn_a_SOURCES = network.cpp neuron.cpp
e emsrc/Makefile.am
, vincule seu executável à biblioteca:bin_PROGRAMS = foo foo_SOURCES = main.c foo_LDADD = crtnn/libcrtnn.a SUBDIRS = crtnn
É chamado de "conveniência" quando não será instalado (você pode dizer por causa donoinst_
prefixo): é usado apenas durante a construção. E esta é uma biblioteca estática, então o resultado é o mesmo que se você tivesse substituídocrtnn/libcrtnn.a
porcrtnn/network.o
ecrtn/neuro.o
Ao vincularfoo
.Use uma biblioteca de conveniência do Libtool. Isso requer mais configuração se você ainda não estiver usando o LBtool. Você deve adicionar uma chamada
LT_INIT
dentroconfigure.ac
e reencontrarautoreconf
Para instalar os arquivos do libtool. Então você pode atualizarsrc/crtnn/Makefile.am
Para fazer uma biblioteca de seus dois objetos da seguinte forma:noinst_LTLIBRARIES = libcrtnn.la libcrtnn_la_SOURCES = network.cpp neuron.cpp
esrc/Makefile.am
do seguinte modo:bin_PROGRAMS = foo foo_SOURCES = main.c foo_LDADD = crtnn/libcrtnn.la SUBDIRS = crtnn
Qual é a diferença? Você pode perguntar, quase nenhum. Uma vantagem de usar as bibliotecas de conveniência do LBTOOL é que elas podem ser aninhadas: uma biblioteca Libtool pode incluir outra biblioteca Libtool (isso é conveniente quando você tem uma profunda hierarquia de código -fonte e está construindo uma biblioteca em cada nível). Além disso, as bibliotecas de conveniência do LBtool podem ser usadas para criar uma biblioteca compartilhada, se você quiser. As bibliotecas estáticas do Autorake não podem.
Outras dicas
Você pode simplesmente especificar arquivos de origem no Project/src/makefile.am e não ter um makefile.am em ctrnn:
maude_SOURCES = ctrnn/network.cpp ctrnn/neuron.cpp
Ou você pode usar uma biblioteca de conveniência do Libtool. Em ctrnn/makefile.am, put:
noinst_LTLIBRARIES = libctrnn.la libctrnn_la_SOURCES = network.cpp neuron.cpp
e em src/makefile.am, coloque
LDADD = ctrnn/libmylib.la
Se você ainda não está usando o LBtool, também precisará adicionar lt_init para configurar.ac.
Melhor ainda, você pode forçar uma marca usando um alvo sem fonte, fazendo isso:
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 \
...
O molho secreto é nodist_EXTRA_xxxx_la_SOURCES
.
Mais detalhes aqui: https://www.gnu.org/software/automake/manual/html_node/libtool-convenience-libraries.html