Подтвердить что ты не робот

Как мне указать в скрипте Makefile.am, что я хочу компилировать только объектные .o файлы?

У меня есть Makefile.am который будет отвечать за создание окончательного двоичного файла приложения:

project/src/Makefile.am

Также в каталоге src есть подкаталог ctrnn который содержит дополнительный Makefile.am:

project/src/ctrnn/Makefile.am

Теперь ctrnn/Makefile.am должен генерировать только объектные файлы .o с идеей, что Makefile.am верхнего уровня должен использовать объектные файлы, сгенерированные в подкаталоге ctrnn для сборки двоичного ctrnn.

Это ctrnn/Makefile.am:

SOURCES = network.cpp\
    neuron.cpp

AM_CPPFLAGS=  @[email protected]

Основываясь на этом файле Makefile.am, я хочу получить network.o и neuron.o. Я создаю соответствующий Makefile с помощью Automake и т.д., Но когда я пытаюсь и затем выполняю make файл, он ничего не делает и просто говорит:

make: Nothing to be done for 'all'

Я знаю, почему это так, мне нужно указать цель сборки. Но как мне это сделать в ctrnn/Makefile.am учитывая, что я не хочу создавать двоичный файл, который потребовал бы bin_PROGRAMS а реальные объектные файлы network.o и neuron.o?

(Обратите внимание, что если я действительно укажу имя bin_PROGRAMS, оно справедливо закончится жалобой на неопределенную ссылку на main).

Что я делаю не так?

4b9b3361

Ответ 1

Automake не может создавать объекты без явной цели (программы, библиотеки), которые будут использовать эти объекты. Одна из причин заключается в том, что параметры компиляции указаны для каждой цели. Если две цели, например. два двоичных файла используют один и тот же объект, но имеют разные параметры компиляции, один и тот же объект может быть скомпилирован дважды.

У вас есть три способа сделать то, что вы хотите, все они связаны с привязкой исходных файлов к какой-либо цели.

  • Не используйте src/ctrnn/Makefile.am, просто укажите ссылку на исходные файлы подкаталога со своего src/Makefile.am:

    bin_PROGRAMS = foo
    foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp
    
    Обратите внимание, что это построит network.o и neuron.o в том же каталоге, что и main.o. Если вы хотите объекты в подкаталогах, используйте AUTOMAKE_OPTIONS = subdir-objects.
  • Используйте библиотеку удобства. В src/crtnn/Makefile.am создайте библиотеку двух ваших объектов:

    noinst_LIBRARIES = libcrtnn.a
    libcrtnn_a_SOURCES = network.cpp neuron.cpp
    
    и в src/Makefile.am свяжите свой исполняемый файл с библиотекой:
    bin_PROGRAMS = foo
    foo_SOURCES = main.c
    foo_LDADD = crtnn/libcrtnn.a
    SUBDIRS = crtnn
    
    Он называется "удобством", когда он не будет установлен (вы можете сказать из-за префикса noinst_): он используется только во время сборки. И это статическая библиотека, поэтому результат будет таким же, как если бы вы заменили crtnn/libcrtnn.a на crtnn/network.o и crtn/neuro.o при связывании foo.
  • Используйте библиотеку удобства Libtool. Это требует большей настройки, если вы уже не используете Libtool. Вы должны добавить вызов LT_INIT в configure.ac и перезапустить autoreconf, чтобы установить файлы libtool. Затем вы можете обновить src/crtnn/Makefile.am, чтобы сделать библиотеку двух ваших объектов следующим образом:

    noinst_LTLIBRARIES = libcrtnn.la
    libcrtnn_la_SOURCES = network.cpp neuron.cpp
    
    и src/Makefile.am следующим образом:
    bin_PROGRAMS = foo
    foo_SOURCES = main.c
    foo_LDADD = crtnn/libcrtnn.la
    SUBDIRS = crtnn
    
    В чем разница? вы можете спросить, почти нет. Одно из преимуществ использования библиотек-библиотек Libtool заключается в том, что они могут быть вложенными: библиотека Libtool может включать в себя еще одну библиотеку Libtool (это удобно, когда у вас есть глубокая иерархия исходного кода, и вы создаете библиотеку на каждом уровне). Кроме того, библиотеки удобства Libtool могут использоваться для создания общей библиотеки, если хотите. Невозможно создать статические библиотеки Automake.

Ответ 2

Вы можете просто указать исходные файлы в файле project/src/Makefile.am и не иметь Makefile.am в ctrnn:

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

или вы можете использовать библиотеку удобства libtool. В ctrnn/Makefile.am, поставьте:

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

и в src/Makefile.am, поставьте

LDADD = ctrnn/libmylib.la

Если вы еще не используете libtool, вам также нужно добавить LT_INIT для configure.ac.

Ответ 3

Еще лучше, вы могли бы FORCE сделать, используя цель без источника, сделав это:

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 \
...

Секретный соус nodist_EXTRA_xxxx_la_SOURCES.

Подробнее здесь: https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html