Поскольку вы приглашаете объяснение от кого-то более опытного, я начну с повторения моего комментария к вашему ответу: вам нужно указать Autoconf, какие файлы должен создавать сценарий configure
, и это функция AC_CONFIG_FILES
макрос.Вы не смогли сказать, что хотели, чтобы src/Makefile
было ошибкой как для внутреннего, так и для внешнего источника.
Но вам, кажется, нужно больше объяснения того, что происходит под прикрытием,Итак, пошли.
Дерево проекта * * * * * * * * * * - это дерево каталогов с корнем в каталоге, содержащем скрипт configure
верхнего уровня. дерево сборки имеет корень в рабочем каталоге, из которого вы запускаете configure
.Если дерево сборки отличается от дерева исходного кода, вы выполняете сборку вне источника .configure
отправляет весь свой вывод в дерево сборки, от временных файлов, созданных его тестами, до его файлов журнала в выходные файлы, обозначенные макросами AC_CONFIG_FILES
.При необходимости он также создает любые подкаталоги, указанные для выходных файлов, например src
для вашего src/Makefile
.Он не копирует ничего из исходного каталога per se и не создает больше каталогов, чем необходимо для размещения выходных файлов.
Волшебство сборок вне исходного кода происходит вmake
.Он опирается на функцию «VPATH» некоторых реализаций make
, включая GNU Make, с помощью которой make
может быть задан путь поиска для предварительных условий и целей правил сборки.Make всегда сначала ищет их относительно своего (затем) рабочего каталога, прежде чем обращаться к VPATH, но в свежей сборке вне источника единственные вещи, которые он может первоначально найти, это файлы, созданные configure
.(По ходу сборки он может также найти файлы, которые он ранее построил.)
Но VPATH ортогонален рекурсивному make
, например, вы используете функцию SUBDIRS
в Automake.Фактически, рекурсивный make
- это вовсе не явная особенность make
, а скорее особый случай обычного поведения make
(хотя GNU make
, по крайней мере, распознает его и предоставляет немного особенногослужба поддержки).Рекурсивный make
работает просто, помещая команду make
в рецепт обычного правила make
, но VPATH не имеет (напрямую) никакого отношения к командам в рецептах .
В частности, VPATH не поможет, если, скажем, make
попытается перейти в каталог, который не существует в дереве сборки.Это не проблема для правильной системы сборки Autotools, в которой все Makefile сгенерированы configure
, потому что make
будет записываться только в каталоги, которые (как ожидается) будут иметь Makefiles, и configure
создаст эти каталогивместе с Makefiles в них.make
, однако, знает только о самом Makefile, а не о его происхождении.Если он пытается перейти в каталог, который не существует, все, что он знает, это то, что команда, которую он пытался выполнить, по этой причине не удалась.
Вот почему вы получили менее полезное сообщение об ошибке в вашем случае,Но также потому, что сборка вне исходного кода - это возможность подключиться после того, как ваша сборка уже работает в исходном коде.Вы бы получили несколько более полезное сообщение об ошибке из сборки из исходного кода, и основанные на Automake файлы Makefile очень хорошо справляются с очисткой.make clean
и / или make distclean
и / или make maintainer-clean
работают так, как заявлено.
Бонус
Теперь, чтобы выяснить, как сделать так, чтобы бинарный файл помещался в корзину вместоsrc ...
Почему?Серьезно, какой смысл, особенно если вы уже выполняете сборку из исходного кода?make
знает, где найти двоичные файлы, когда вы будете готовы их установить (или очистить).И, конечно же, место, в которое make
изначально помещает их, не предназначено для места их установки.
Но да, Automake может сделать это.Вам просто нужно сказать это сделать.С представленным макетом основная часть будет выглядеть так:
src / Makefile.am
bin_PROGRAMS = ../bin/testprog
___bin_testprog_SOURCES = main.c
Вам также может понадобиться запустить Make-файл верхнего уровня, чтобы обеспечить наличие каталога bin/
, прежде чем он вернется в src/
.Если это действительно необходимо, то я думаю, что вы можете добиться этого с помощью этого варианта:
Makefile.am
SUBDIRS = . src
dist_doc_data = README
all-local:
mkdir -p bin
clean-local:
-rm -rf bin
См. Также :