记一次时间戳导致的编译失败

16 Aug 2018 | 编译, Bug | | ˚C

背景

最近接手一个老项目,项目结构大体示意如下:

project
    ├── packaging
    │   ├── Makefile
    │   └── project.spec
    └── src
        ├── knot-2.3.1
        │   ├── aclocal.m4
        │   ├── ar-lib
        │   ├── compile
        │   ├── config.guess
        │   ├── config.sub
        │   ├── configure
        │   ├── configure.ac
        │   ├── depcomp
        │   ├── install-sh
        │   ├── libtap
        │   ├── ltmain.sh
        │   ├── m4
        │   ├── Makefile.am
        │   ├── Makefile.in
        │   └── missing
        └── Makefile

项目目录中包含了第三方的项目knot-2.3.1(knot是什么不重要,重要的是它用了autotools)。src目录下的Makefile中,调用了knot的编译流程:

src/Makefile:

knot:
	cd ${KNOT_DIR}/..; \
	./configure; \
	make

位于packaging下的Makefile是用来生成rpm安装包的,部分内容如下:

packaging/Makefile:

all: rpm

rpm: $(TARBALL)
	@mkdir -p {BUILD,BUILDROOT,SRPMS,SPECS}
	@rpmbuild --define "_topdir ${PWD}" --define "_sourcedir ${PWD}"  \
	--define "buildroot ${PWD}/BUILDROOT" --define "_rpmdir ${PWD}" -ba ${SPECFILE}

$(TARBALL):
	@rm -rf $(PKG_NAME)-$(PKG_VERSION)
	cd ${PROJ_ROOT}/.. && git archive --format=tar --prefix=/ $(TAG) src | gzip >packaging/${TARBALL}
	@rm -rf $(PKG_NAME)-$(PKG_VERSION)

由于项目是通过git进行版本控制,这里通过git对项目的src目录进行打包,然后运行rpmbuild编译成rpm包。

按道理说,在packaging目录下编译和在src目录下编译,出了是否打包成rpm之外,都是完全一样的。然而,实际操作后发现,在packaging下可以正常编译,而在src目录下运行make会报一个错误:

/project/src/knotdb/knot-2.3.1/missing: line 81: aclocal-1.15: command not found
WARNING: 'aclocal-1.15' is missing on your system.
         You should only need it if you modified 'acinclude.m4' or
         'configure.ac' or m4 files included by 'configure.ac'.
         The 'aclocal' program is part of the GNU Automake package:
         <http://www.gnu.org/software/automake>
         It also requires GNU Autoconf, GNU m4 and Perl in order to run:
         <http://www.gnu.org/software/autoconf>
         <http://www.gnu.org/software/m4/>
         <http://www.perl.org/>

问题分析

只看错误提示,会以为这是一个aclocal版本不符的问题,于是会想到升级aclocal到1.15版本。但是这样做就掉坑里了,想想看为什么packaging里面能正常编译通过?明明是一模一样的项目文件,对不对?我甚至在packaging编译过程中提取tar包,与外面的src做diff,确实文件内容都是完全一致的。那么问题出在哪里?

其实这个网上也有人遇到过了,比如这个How to overcome “’aclocal-1.15’ is missing on your system” warning when compiling?。导致相同文件编译却一个成功一个报错的原因,是两份项目文件的时间戳不一致。

由于项目代码通过git管理,而git不保存文件的时间戳信息,导致autotools的某些脚本被认为过期,make的时候会重新生成;而由tar解压来的文件,时间戳都是最新的,不会重新生成,这就导致了编译行为差异。

解决方法

知道了原因,只要更新编译脚本的时间戳就可以了。

touch --date="`date`" aclocal.m4 Makefile.am configure Makefile.in

Older · View Archive (22)

记一个asio实现代理功能的设计思路

Newer

C++奇技淫巧之访问private变量