在autotools中,源代码构建失败

时间:2018-05-28 03:53:26

标签: c autotools configure automake

这可能是一个愚蠢的问题,但我最近才开始使用autotools来简化我对事物的要求。也就是说,我喜欢最终用户真的不需要在本地系统上构建项目的想法。

为了使我的源目录保持干净,我将额外的配置文件保存在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的副本以及gnu.org上的Automake佳能。我不确定去哪里,这些来源都没有帮助我解决它。

从它看起来它正在src目录中寻找build并且自然它不存在。但是,我在源代码构建中查看的每个资源似乎都没有表明这个问题甚至可能发生。我做错了什么?

2 个答案:

答案 0 :(得分:1)

我找到了这个特殊问题的解决方案,但我不想给自己任何积分,因为我希望有更多经验丰富的人来解释它。

解决方案相当模糊:

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

答案 1 :(得分:1)

既然你邀请了更有经验的人的解释,我首先要重述我对你答案的评论:你需要告诉Autoconf configure脚本应该创建哪些文件,这就是AC_CONFIG_FILES宏。您没有告诉它您想要src/Makefile是源内和源外构建的错误。

但是你似乎想要了解更多关于幕后内容的解释,所以这里有。

项目的源代码树是以包含顶级configure脚本的目录为根的目录树。 构建树以工作目录为根,运行configure。当构建树与源树不同时,您正在执行源外构建configure将其所有输出发送到构建树,从其测试创建的临时文件到其日志文件,再到通过AC_CONFIG_FILES宏指定的输出文件。适当时,它还会为您的src创建为输出文件指定的所有子目录,例如src/Makefile。它不会复制源目录本身中的任何内容,也不会创建比放置其输出文件所需的目录更多的目录。

源外构建的魔力发生在make中。它依赖于某些make实现的“VPATH”功能,包括GNU Make,通过它可以为make提供构建规则的先决条件和目标的搜索路径。在咨询VPATH之前,Make始终首先查看这些相对于其(当时)工作目录的内容,但在新的源代码构建中,它最初可以找到的唯一内容是由configure创建的文件。 (随着构建的进行,它也可能会找到之前构建的文件。)

但VPATH与递归make正交,例如您正在利用Automake的SUBDIRS功能。事实上,递归make根本不是make的明确特征,而是普通make行为的特殊情况(尽管GNU make至少可以识别它并提供一些特殊的支持)。递归make只需将make命令放入常规make规则的配方中即可运行,但 VPATH没有(直接)与配方中的命令相关

特别是,如果make尝试递归到构建树中不存在的目录中,VPATH没有任何帮助。对于正确的Autotools构建系统而言,这不是问题,其中所有Makefile都是由configure生成的,因为make只会递归到(它预期会有)Makefile的目录,{{1}将创建这些目录以及其中的Makefile。然而,configure只知道Makefile本身,而不是它的起源。如果它试图递归到一个不存在的目录中,它只知道它试图执行的命令因此而失败。

这就是为什么你的案例中有一个不太有用的错误信息。但也因为在源代码构建已经在源代码中工作之后,源外构建是一种参与的能力。您可能会从源内构建中获得更有用的错误消息,而基于Automake的Makefile非常适合清理。 make和/或make clean和/或make distclean按宣传方式工作。

加成

  

现在想弄清楚如何将二进制文件放在bin中而不是src ...

为什么呢?说真的,有什么意义,特别是当你已经在进行源外构建时? make maintainer-clean知道在您准备好安装二进制文件时(或清理它们)的位置。当然,最初放置它们的地方make并不是它们的安装位置。

但是,是的,Automake可以做到这一点。你只需要告诉它做。使用您提供的布局,其主要部分将如下所示:

<强>的src / Makefile.am

make

您可能还需要诱导顶级Makefile以确保bin_PROGRAMS = ../bin/testprog ___bin_testprog_SOURCES = main.c 目录在它递归到bin/之前存在。如果确实需要,那么我认为你可以通过这种变化实现它:

<强> Makefile.am

src/

另见