使用 automake/Makefile.am 生成 IDL 实体
-
26-09-2019 - |
题
对于那些不熟悉 IDL(接口描述语言)的人来说,它抽象了跨平台(java、c、c++ 等)使用的数据描述。我的项目具有从 Foo.idl 生成的依赖项 Foo.c、Foo.h、FooHelper.c 和 FooHelper.h。当 Foo.idl 更改时,如何运行任意命令,但在构建过程中仍包含 Foo.c、FooHelper.c?
我当前尝试向 Makefile.am 添加一条规则——希望将该规则复制到生成的 Makefile 中。
我努力了:
Foo.idl : Foo.idl
${the_generate_command}
然后将 Foo.idl 添加到 my_program_SOURCES 但在构建时不会运行 the_generate_command 。
我已经成功地从 IDL 生成了
Foo.c Foo.h FooHelper.h FooHelper.c : Foo.idl
${the_generate_command}
但它不会将 Foo.c、FooHelper.c 添加到编译过程中,因此它们永远不会被构建,只是由 the_generate_command 生成!
所有代码(包括 idl)都位于 $PROJECT_DIR/src 中。
解决方案
rq 的答案几乎是正确的,但忽略了一些微妙之处。尝试这个:
bin_PROGRAMS = myprogram
myprogram_SOURCES = Foo.c Foo.h FooHelper.h FooHelper.c $(OTHER_SOURCES)
BUILT_SOURCES = Foo.c Foo.h FooHelper.h FooHelper.c
EXTRA_DIST = Foo.idl
MAINTAINERCLEANFILES = Foo.c Foo.h FooHelper.h FooHelper.c
Foo.c: Foo.idl
$(THE_GENERATE_COMMAND)
Foo.h FooHelper.h FooHelper.c: Foo.c
@if test -f $@; then \
touch $@; \
else \
## Recover from the removal of $@
rm -rf $<; \
$(MAKE) $(AM_MAKEFLAGS) $<; \
fi
“生成”的附加规则 Foo.h
, FooHelper.h
和 FooHelper.c
从 Foo.c
确保并行构建不会尝试运行 $(THE_GENERATE_COMMAND)
两次。这是一个习语,详细介绍 Automake手册 这适用于并行构建。这里仍然有一点脆弱:如果用户删除(比如说) FooHelper.h
和 FooHelper.c
并启动并行 make,它可能会运行 $(MAKE) $(AM_MAKEFLAGS) $<
并行多次恢复规则的一部分。正如手册所说,只有当用户手动破坏构建树时,这种竞争才会发生,即使这样也没什么问题。 make clean; make
无法修复。
这 BUILT_SOURCES
线确保 Foo.c
, Foo.h
, FooHelper.h
和 FooHelper.c
在尝试构建之前构建 myprogram
(看 本节 Automake 手册,了解为什么只将它们添加到 myprog_SOURCES
是不够的)。这 EXTRA_DIST
变量确保 .idl
文件将被捕获 make dist
(参考).
MAINTAINERCLEANFILES
指定运行时要删除的附加文件 make maintainer-clean
;这是为了遵守 GNU Makefile 标准. 。另请参阅变量的描述 Automake手册.