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

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

project/src/Makefile.am

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

project/src/ctrnn/Makefile.am

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

Это ctrnn/Makefile.am:

SOURCES = network.cpp\
    neuron.cpp

AM_CPPFLAGS=  @CXXFLAGS@

Основываясь на этом 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).

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

Ответы [ 3 ]

27 голосов
/ 21 февраля 2010

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

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

  1. Не используйте 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.
  2. Использовать вспомогательную библиотеку. В 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.
  3. Используйте удобную библиотеку 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 голосов
/ 16 февраля 2010

Вы можете просто указать исходные файлы в проекте / 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.

0 голосов
/ 12 октября 2016

Еще лучше, вы можете сделать ФОРМУ используя цель без исходного кода, выполнив это:

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

...