标准项目布局为
$(src_topdir)/include
$(src_topdir)/src
$(src_topdir)/tests
除了在
$(src_topdir)/tests
中运行任何已配置的测试之外,我还想在 $(src_topdir)/src
中输入“make check”时运行 $(src_topdir)/src
中的所有测试。
Automake 提供了一个扩展,可以通过添加(在 Makefile.am 中)我可以定义的目标
check
来向 local-check
Makefile 目标添加其他目标
local-check:
cd ../tests && $(MAKE) $(AM_MAKEFLAGS) check
虽然这使我能够满意地在
make check
目录中进行 $(src_topdir)/src
,但不幸的是,它中断了从 make check
目录对 $(src_topdir)
的调用。这是因为从 $(src_topdir)
调用会递归地进入 $(src_topdir)/src
和 $(src_topdir)/tests
,从而触发 $(src_topdir)/tests
中的测试两次。
是否有一种方法可以更改
Makefile.am
中的 $(src_topdir)/src
,以便本地 make check
调用触发所需的额外测试,而来自其余工具的 make check
调用不受影响?
在 Automake 中没有办法做到这一点。
一种解决方法是简单地更改目标的名称。也就是说,不要输入
make check
,而是输入 make mycheck
(或您喜欢的任何内容)。那么mycheck
规则就很容易写了。
另一个想法是简单地省去子目录 Makefiles。如今,整棵树使用一个
Makefile
通常会更好。然后这个问题就消失了——或者,如果你真的想要,你可以写一个只有单个 src/Makefile
目标的小 check
。
实现此目的的方法是在子目录中使用小 Makefile,链接到项目根目录中的 Automake 管理的 Makefile。
我已经通过使用以下 Makefile 获得了几乎所有我想要的东西
all:
@make -C .. $@
%:
@make -C .. $@
基本上,
%:
规则匹配所有内容,在其上方的一个目录中调用make。然而,这使得 make 没有默认规则(因为 %:
是一个规则模式)。为了纠正这个问题,我还添加了一个相同的规则all:
,它不需要规则模式匹配。
在这两种情况下,他们都会调用
@make -C .. $@
来调用 make,但是 -C ..
表示在评估任何内容之前将目录更改为 ..
。最后,$@
将所有参数传递给上面一个目录的 make 调用。
为了使其正常工作,这意味着所有构建都将位于根目录中
$(src_topdir)
。这意味着需要修改(在 automake 系统中)bin_PROGRAMS
和 {PROGRAM}_SOURCES
位于顶层 Makefile.am,就像这样
bin_PROGRAMS = src/main
src_main_SOURCES = src/main.c src/module.c
现在这会将您的
*.o
文件放置在顶级目录中,这是不可取的。要解决该问题,请将 subdir-objects
配置参数添加到 configure.ac
文件中,如下所示:
AM_INIT_AUTOMAKE([subdir-objects ... ])
注意上面的
...
不是字面意思,而是代表 AM_INIT_AUTOMAKE
的所有其他选项。
这样,您还必须将 automake 测试构建/配置移至顶层
Makefile.am
但您获得了能够从 make check
目录中键入 $(src_topdir)/src
的优势,从而允许您验证您不这样做在执行重构和其他代码修改时不要破坏单元测试。