Как записать файлы automake в подкаталоги рекурсивной сборки? - PullRequest
0 голосов
/ 13 октября 2019

Мой рабочий каталог, как показано в следующем дереве:

./  
|--HelloWorld/  
|--|--main.cpp  
|--|--Dog/   
|--|--|--Dog.h  
|--|--|--Dog.cpp    
|--Pet/  
|--|--Pet.h  
|--|--Pet.cpp  
|--build/  

main.cpp включает dog.h и pet.h. Собака является унаследованным классом домашних животных, поэтому Dog.h также включает Pet.h. Я знаю, что это проводной способ организации кодов, но мне просто любопытно , как создавать файлы makefile.am для каждого подкаталога, чтобы autotool мог собрать проект в каталоге сборки.

Обратите внимание, что я хотел бы иметь некоторые дополнительные функции:

  1. Возможно ли, чтобы мы собрали файл hello.exe в каталоге build вместо каталога build/HelloWorld/? Чтобы сделать это, я должен поместить bin_PROGRAMS в ./Makefile.am
  2. Я не хочу собирать Pet как библиотеки, мне интересно, есть ли способ, которым я могу просто сказать automake найтиисходники в разных местах.
  3. Я знаю, что было бы проще использовать нерекурсивный make-файл. Но я просто хочу научиться создавать рекурсивные make-файлы для нескольких каталогов.

Я попробовал:

configure.ac

AC_PREREQ([2.69])
AC_INIT([Hello], [1.0], [qub@oregonstate.edu])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AC_CONFIG_SRCDIR([HelloWorld/main.cpp])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
#AC_PROG_CPP

AC_CONFIG_FILES([Makefile
                 HelloWorld/Makefile
                 Pet/Makefile
                 HelloWorld/Dog/Makefile])
AC_OUTPUT

Makefile.am

SUBDIRS = HelloWorld Pet

HelloWorld / Makefile.am

AM_CPPFLAGS=-I$(srcdir)/../Pet -I$(srcdir)/Dog 
SUBDIRS = Dog
bin_PROGRAMS=hello 
hello_SOURCES = main.cpp

Pet / Makefile.am

hello_SOURCES = Pet.h Pet.cpp

HelloWorld / Dog / Makefile.am

AM_CPPFLAGS=-I$(srcdir)/../../Pet

hello_SOURCES = Dog.h Dog.cpp 

Я только начал изучать автоматизированные вещи, и я знаю, что эти коды не работают навсе.

Может ли кто-нибудь помочь мне исправить их? Спасибо.

1 Ответ

0 голосов
/ 13 октября 2019

Вы говорите, что вас интересует

, как создавать файлы makefile.am для каждого подкаталога, чтобы autotool мог собрать проект в каталоге сборки

, но это не подходящая цель, как показывает этот пример. Редко полезно или уместно иметь Makefile.am, который не определяет какие-либо цели для построения. Вы указали, что не хотите собирать Pet как библиотеку, так какую цель определит Makefile.am в своем каталоге? Аналогичное относится к Dog, если вы хотите избежать создания библиотеки. В этой ситуации мало или нет смысла использовать рекурсивный make.

Однако отмечу, что в Automake есть концепция «вспомогательной библиотеки», которая является промежуточной целью, которая сама по себе никогда не устанавливается. , но содержит объектный код, который может быть связан с исполняемым файлом или большей библиотекой. Я продемонстрирую это позже, так как это наиболее разумный способ настроить структуру makefile-per-directory, которую вы запрашиваете в данном конкретном случае.

Кроме того, в отношении направления вывода в конкретный каталог висходное дерево: это можно сделать, но это, вероятно, пустая трата усилий. Автоинструменты уже предоставляют удобный метод для сборки вне источника, который легче выполняет задачу отделения результатов сборки от источника в случае, если человек, строящий проект, хочет сделать это.

NEVERTHELESS , Основы рекурсивных сборок с помощью Autotools довольно просты. Есть две основные вещи:

  • каждая Makefile.am, которая хочет выразить рекурсию в одну или несколько подкаталогов, делает это путем перечисления относительных путей к каждой из этих подкаталогов в переменной. SUBDIRS.

  • проект configure.ac должен указать Makefile s, которые будут построены с помощью макроса AC_CONFIG_FILES.

Это все, что вам нужно сделать, чтобы настроить рекурсию в целом, а подробности того, как установить конкретные цели и параметры, зависят от проекта.

  1. Возможно ли, что мы создаем привет.exe в каталоге build вместо build/HelloWorld/? Чтобы сделать это, нужно ли поставить bin_PROGRAMS на ./Makefile.am

Да, вы можете указать здание в build/hello вместо build/HelloWorld/hello. Вы не могли бы строго иметь для помещения соответствующего bin_PROGRAMS в верхний уровень Makefile.am, но вы определенно должны поместить его туда или в build/Makefile.am файл. Я призываю вас избегать попыток иметь какие-либо цели сборки make-файла вне дерева с корнем в каталоге, где находится этот конкретный make-файл.

Я не хочу собирать Pet как библиотеки, мне интересно, есть ли способ, которым я могу просто сказать automake найти исходные коды в разных местах.

Вы можете абсолютноукажите исходные файлы в каталоге, отличном от Makefile.am. Просто укажите соответствующий путь относительно каталога make-файла. Это имеет больше смысла для источников в том же дереве, что и make-файл, но использование источников, расположенных в другом месте, не такая большая проблема, как попытка создать цели в другом месте.

Я знаю, что было бы проще использовать нерекурсивный make-файл. Но я просто хочу научиться создавать рекурсивные make-файлы для нескольких каталогов.

Нерекурсивные make-файлы не обязательно проще, чем рекурсивные, но обычно они лучше потому что они выражают целое дерево / целевое дерево как единое целое, а не разбивают его на части. make может принимать лучшие решения при сборке, когда у него есть вся информация за один раз.

Я только начал изучать автоматизацию, и я знаю, что эти коды не работают вообще.

Мой ответ на ваш связанный вопрос предоставляет рекурсивное решение связанной проблемы. Он демонстрирует один из ключевых принципов, которые, по-видимому, вам не хватает: переменные, указывающие источники цели и другие свойства сборки, должны отображаться в том же файле Makefile.am, в котором определена сама цель. Каждый Makefile.am соответствует отдельному make-файлу. В первом приближении данные не делятся между make-файлами, поэтому вся информация, необходимая для построения заданной цели, должна отображаться в одной и той же.

Другая вещь, которая, кажется, отличает этот вопрос от вашего другого, заключается в том, чтоВы хотите (хотя и ошибочно) указать конкретный выходной каталог в вашем make-файле . Помните, что куда бы изначально ни создавались файлы, это промежуточная область - это не имеет большого значения, потому что они помещаются в конечный пункт назначения к make install. Тем не менее, вы можете указать цель, находящуюся в другом каталоге, указав правильный относительный путь к ней. Конечно, такое изменение имени цели должно быть отражено в именах переменных, полученных из имени цели .

Здесь, затем, рекурсивная установка Automake, которая должна создаватьваш пример проекта, использующий один make-файл для каждого исходного каталога:


Makefile.am

SUBDIRS = Pet HelloWorld

# Note: specifying output into a different directory
bin_PROGRAMS = build/hello

# Note the form of the following names:
build_hello_SOURCES = HelloWorld/main.cpp
build_hello_CPPFLAGS = -I$(srcdir)/Pet -I$(srcdir)/HelloWorld/Dog
# Note that library order matters
build_hello_LDADD = HelloWorld/Dog/libDog.a Pet/libPet.a

Pet / Makefile.am

noinst_LIBRARIES = libPet.a

libPet_a_SOURCES = \
    Pet.cpp        \
    Pet.h

HelloWorld / Makefile.am

SUBDIRS = Dog

# No own targets defined here, just the recursion into Dog.  This could have been
# skipped altogether, but I'm sticking to the letter of one Makefile.am per source
# directory.

HelloWorld / Dog / Makefile.am

noinst_LIBRARIES = libDog.a

libDog_a_SOURCES = \
  Dog.cpp          \
  Dog.h
libDog_a_CPPFLAGS = -I$(top_srcdir)/Pet

Ваш configure.ac должен работать с этим как есть.

Обратите внимание, что это не зависит от VPATH;он встраивает , в частности , в подкаталог build/ дерева сборки, в том числе при сборке непосредственно в дереве исходного кода.

...