如何用Makefile为各子目录执行命令并避免重复编写任务?
如何避免重复编写Automake子目录中的
foo-local任务? 问题背景
目录结构
├── configure.ac ├── dir1 │ └── Makefile.am ├── dir2 │ └── Makefile.am ├── Makefile.am ...
各文件内容
configure.ac
AC_INIT([amhello], [1.0], [bug-report@address]) AM_INIT_AUTOMAKE([foreign -Wall -Werror]) AC_PROG_CC AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([ Makefile dir1/Makefile dir2/Makefile ]) # Libtool AM_PROG_AR LT_INIT AM_EXTRA_RECURSIVE_TARGETS([foo]) AC_OUTPUT
顶层Makefile.am
SUBDIRS = dir1 dir2 foo-start: @echo "executing foo!" make foo
dir1和dir2的Makefile.am(当前重复内容)
foo-local: echo "I'm here! $$(basename $(CURDIR))"
当前运行输出
execute foo! I'm here! dir1 I'm here! dir2
解决方案
有两种简洁的方式可以避免重复编写foo-local任务:
方法1:顶层定义通用规则,子目录自动继承
直接在顶层Makefile.am中定义foo-local的通用实现,子目录在执行递归目标时会自动使用这个规则,无需在子目录中重复编写:
修改后的顶层Makefile.am:
SUBDIRS = dir1 dir2 # 通用foo-local规则,所有子目录共享 foo-local: echo "I'm here! $$(basename $(CURDIR))" foo-start: @echo "executing foo!" make foo
之后删除dir1和dir2中Makefile.am里的foo-local规则即可。
方法2:创建通用片段文件,子目录包含引用
- 在项目根目录创建
common.mk文件,写入通用规则:
foo-local: echo "I'm here! $$(basename $(CURDIR))"
- 修改dir1和dir2的
Makefile.am,仅保留包含语句:
include $(top_srcdir)/common.mk
这种方式适合后续需要添加更多通用规则的场景,便于统一维护。
验证结果
两种方法执行make foo-start后,输出均与原场景一致:
execute foo! I'm here! dir1 I'm here! dir2
内容的提问来源于stack exchange,提问作者karobar
相关产品推荐
相关产品推荐

