Сбой сборки из исходного кода в автоинструментах - PullRequest
0 голосов
/ 28 мая 2018

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

Для того, чтобы мой исходный каталог был чистым, у меня сохранены дополнительные файлы конфигурациив каталоге config, и я хочу mkdir каталог сборки, чтобы хранить мои файлы конфигурации для сборки в тайне.Вот мое текущее дерево проекта:

.
├── aclocal.m4
├── AUTHORS
├── autom4te.cache
│   ├── output.0
│   ├── output.1
│   ├── requests
│   ├── traces.0
│   └── traces.1
├── bin
├── build
├── Changelog
├── config
│   ├── compile
│   ├── install-sh
│   └── missing
├── config.h.in
├── configure
├── configure.ac
├── doc
├── lib
├── Makefile.am
├── Makefile.in
├── NEWS
├── README
├── README.html
├── README.md
├── src
│   ├── Makefile.am
│   ├── main.c
└── test

Makefile.am

SUBDIRS = src
dist_doc_data = README

src / Makefile.am

bin_PROGRAMS = testprog
testprog_SOURCES = main.c

configure.ac

AC_PREREQ(2.59)

AC_INIT([testprog], [1.0], [myemail@example.com])

AC_CONFIG_AUX_DIR([config])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

AC_CONFIG_HEADERS([config.h])

AC_PROG_CC

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

И, наконец, результат построения:

mkdir build
cd build
../configure
make

Настройка вывода

checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... /usr/bin/clang
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether /usr/bin/clang accepts -g... yes
checking for /usr/bin/clang option to accept ISO C89... none needed
checking whether /usr/bin/clang understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of /usr/bin/clang... none
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands

Сделать вывод

CDPATH="${ZSH_VERSION+.}:" && cd .. && /bin/sh /home/me/projects/testprog/config/missing aclocal-1.15 
 cd .. && /bin/sh /home/me/projects/testprog/config/missing automake-1.15 --foreign
CDPATH="${ZSH_VERSION+.}:" && cd .. && /bin/sh /home/me/projects/testprog/config/missing autoconf
/bin/sh ./config.status --recheck
running CONFIG_SHELL=/bin/sh /bin/sh ../configure CC=/usr/bin/clang --no-create --no-recursion
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... /usr/bin/clang
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether /usr/bin/clang accepts -g... yes
checking for /usr/bin/clang option to accept ISO C89... none needed
checking whether /usr/bin/clang understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of /usr/bin/clang... none
checking that generated files are newer than configure... done
configure: creating ./config.status
 /bin/sh ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing depfiles commands
(CDPATH="${ZSH_VERSION+.}:" && cd .. && /bin/sh /home/me/projects/testprog/config/missing autoheader)
rm -f stamp-h1
touch ../config.h.in
cd . && /bin/sh ./config.status config.h
config.status: creating config.h
config.status: config.h is unchanged
make  all-recursive
make[1]: Entering directory '/home/me/projects/testprog/build'
Making all in src
/bin/sh: line 20: cd: src: No such file or directory
make[1]: *** [Makefile:352: all-recursive] Error 1
make[1]: Leaving directory '/home/me/projects/testprog/build'
make: *** [Makefile:293: all] Error 2

Я купил копию Autotools , а также следовал канону Automake на GNU.орг.Я не уверен, куда идти, и ни один из этих источников не помог мне решить эту проблему.

Из того, что кажется, он ищет src внутри каталога build и, естественно, его не существует.Но каждый ресурс, на который я смотрю из исходных сборок, не указывает, что эта проблема может даже случиться.Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Поскольку вы приглашаете объяснение от кого-то более опытного, я начну с повторения моего комментария к вашему ответу: вам нужно указать 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

См. Также :

0 голосов
/ 28 мая 2018

Я нашел решение этой конкретной проблемы, но я не хочу присваивать себе какие-либо баллы, потому что хотел бы, чтобы кто-то более опытный пришел и объяснил это лучше.

Решение довольно неясное:

AC_PREREQ(2.59)

AC_INIT([testprog], [1.0], [myemail@example.com])

AC_CONFIG_AUX_DIR([config])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

AC_CONFIG_HEADERS([config.h])

AC_PROG_CC

AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT

src/Makefile отсутствует из AC_CONFIG_FILES.При этом он строит, а в каталоге сборки создает каталог src, который содержит двоичный файл.Теперь, чтобы выяснить, как заставить его поместить двоичный файл в bin вместо src ...

...