Como especificar em um script makefile.am que eu só quero compilar arquivos do objeto .o?

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

  •  20-09-2019
  •  | 
  •  

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?

Foi útil?

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.

  1. Não use um src/ctrnn/Makefile.am, basta fazer referência aos arquivos de origem do subdiretório do seu src/Makefile.am:

    bin_PROGRAMS = foo
    foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp
    
    Observe que isso vai construir network.o e neuron.o no mesmo diretório que main.o. Se você deseja objetos em subdiretos, use AUTOMAKE_OPTIONS = subdir-objects.

  2. 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 em src/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 do noinst_ prefixo): é usado apenas durante a construção. E esta é uma biblioteca estática, então o resultado é o mesmo que se você tivesse substituído crtnn/libcrtnn.a por crtnn/network.o e crtn/neuro.o Ao vincular foo.

  3. 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 dentro configure.ac e reencontrar autoreconf Para instalar os arquivos do libtool. Então você pode atualizar src/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
    
    e src/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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top