我有一个项目,我想用automake构建。 该项目由不同的组件或模块组成,并且存在模块间依赖性,这需要以特定顺序构建项目。


project dir/ module1 (core C shared lib) module2 (C++ shared lib wrapper around module 1) module3 (C++ application with dependency on module2) module4 (C library with dependency on module1) module5 (C application with dependency on module4) 


我想有一个’主’项目文件(如果可能的话),它指定项目模块的构建顺序,运行unit testing,如果有的话,整个构建过程都失败:

  • 其中一个模块无法构建
  • 其中一个模块未通过unit testing


如果您使用的是autotools,那么您也可以使用automake。 顶级Makefile.am可以提供按顺序下降的子目录列表,例如:

 SUBDIRS = module1 module2 module3 module4 module5 

子目录Makefile.am可以添加测试目标,使用’make check’调用,如果需要,将强制构建:

 check_PROGRAMS = t_module1 t_module1_SOURCES = t_module1.c t_module1_LDADD = ./ 



info automake提供了参考文档 – 但它提供了一个糟糕的教程。 我在这里可以找到最好的指南之一。

我遇到了同样的问题 ,发现纯autotools解决方案很难运行,因为例如module4的configure脚本取决于module1的安装。

这种情况的手动Makefile和配置脚本相当容易生成。 我已经粘贴在rapidSTORM项目Makefile下面。 它用于树外构建(源目录和构建目录)。

 TARGETS=any_iterator libb64 readsif cs_units dStorm-doc simparm andorcamd rapidSTORM plugin-andorsif fitter master all: # Project dependencies: Any project whose configure run depends upon other projects has a line here andorcamd.prerequisites-installed : $(addsuffix .installed-stamp,libb64 simparm cs_units) rapidSTORM.prerequisites-installed : $(addsuffix .installed-stamp,simparm cs_units libb64 any_iterator) plugin-andorsif.prerequisites-installed : $(addsuffix .installed-stamp,rapidSTORM readsif) master.prerequisites-installed fitter.prerequisites-installed : $(addsuffix .installed-stamp,rapidSTORM) # [Autoconf substitutions snipped here] # The .options files control configuration of subdirectories. They are used in %.configured-stamp vpath %.options $(srcdir)/options:$(builddir) RULES = all check install installcheck dist distcheck # All standard rules have a simple template: Execute them for each # subdirectory after configuring it and installing all prerequisite # packages, and re-execute them whenever # the source files changed. install and distcheck are special and # treated further below. define recursive_rule_template $(1) : $(foreach target,$(TARGETS),$(target).$(1)ed-stamp) endef define standard_rule_template %.$(1)ed-stamp : %.source-change-stamp %.configured-stamp %.prerequisites-installed make -j 4 -C $$* $(1) && touch $$@ endef $(foreach rule,$(RULES),$(eval $(call recursive_rule_template,$(rule)))) $(foreach rule,$(filter-out install distcheck,$(RULES)),$(eval $(call standard_rule_template,$(rule)))) %.installed-stamp : %.alled-stamp make -C $* install && touch $@ # This rule is probably the most complex. It collects option files named after a # number of options and generates configure flags from them; this rule could be # shortened considerably when you don't need project-specific configure/CFLAGS # configuration. %.configured-stamp : $(foreach i, all $(host_config) $(tag) $(host_config)-$(tag), global-$i.options) \ $(foreach i, all $(host_config) $(tag) $(host_config)-$(tag),%-$i.options) | %.prerequisites-installed prefix="$(prefix)"; abs_builddir=$(abs_builddir); \ for i in $(filter %.options,$^); do . ./$$i; done; \ mkdir -p $* && cd $* \ && echo "Configuring with $$OPTIONS CPPFLAGS=$$CPPFLAGS CFLAGS=$$CFLAGS CXXFLAGS=$$CXXFLAGS LDFLAGS=$$LDFLAGS PKG_CONFIG_PATH=$$PKG_CONFIG_PATH" INSTALL="$(INSTALL)" \ && /bin/sh ../$(srcdir)/$*/configure --build=$(build_alias) --host=$(host_alias) --target=$(target_alias) --config-cache $$OPTIONS \ CPPFLAGS="$$CPPFLAGS" CFLAGS="$$CFLAGS" CXXFLAGS="$$CXXFLAGS" PKG_CONFIG_PATH="$$PKG_CONFIG_PATH" \ LDFLAGS="$$LDFLAGS" $(if $(CC),CC=$(CC),) $(if $(CXX),CXX=$(CXX),) \ INSTALL="$(INSTALL)" touch $@ # The source change stamp is updated whenever a file in the source directory changes. # It is used to prevent non-necessary sub-make invocations. %.source-change-stamp : always-renew { test -e $@ && find $(srcdir)/$* -newer $@ -and -not -ipath '*/.svn*' -and -not -path '*/.libs*' | wc -l | grep -q '^0$$'; } \ || touch $@ %.prerequisites-installed : @true %.distchecked-stamp : %.source-change-stamp %.configured-stamp %.prerequisites-installed DISTCHECK_CONFIGURE_FLAGS=`./$*/config.status --config | sed -e "s/'--prefix=[^']*' //"` \ $(MAKE) -j 4 -C $* distcheck && touch $@ Makefile : $(srcdir)/ config.status ./config.status $@ installcheck : dejagnu-tests-ran-stamp dejagnu-tests-ran-stamp : $(foreach target,$(TARGETS),$(target).installed-stamp) testsuite.configured-stamp make -C testsuite check touch $@ always-renew : @true clean : rm -rf *-stamp $(foreach target,$(TARGETS),$(target)/*.la $(target)/config.cache) deploy realclean : clean rm -rf $(TARGETS) %.options : touch $@ world : $(foreach target,$(TARGETS),$(foreach rule,$(RULES),$(target).$(rule)ed-stamp)) .PHONY : always-renew .SECONDARY : .DELETE_ON_ERROR :