协议缓冲区文件的 Makefile 自动依赖关系问题
Posted
技术标签:
【中文标题】协议缓冲区文件的 Makefile 自动依赖关系问题【英文标题】:Makefile Automatic Dependencies Issues With Protocol Buffer Files 【发布时间】:2013-06-30 18:56:00 【问题描述】:我无法在我的 Makefile 中建立自动依赖关系。目标是从许多 Protocol Buffer 文件中创建一个 C++ 库,其中一些可能位于只读目录中。为了绕过写权限,我想在 Makefile 目录中生成 C++ 文件。实际的 Makefile 是从 Makefile.am 创建的。下面的简化脚本应该可以解决构建自动依赖关系的技巧,但它没有:
mypbfiles = /usr/share/project/my_file.proto
MY_PB_FILES = $(notdir $mypbfiles)
MY_SOURCE_FILES = $MY_PB_FILES:.proto=.pb.cc
lib_LTLIBRARIES = lib@PACKAGE_NAME@_protobuf.la
lib@PACKAGE_NAME@_protobuf_la_SOURCES = $MY_SOURCE_FILES
lib@PACKAGE_NAME@_protobuf_la_LDFLAGS = -version-info @MAJOR_VERSION@:@MINOR_VERSION@:0
$(MY_SOURCE_FILES): $(mypbfiles)
@for proto_file in $(mypbfiles); do \
gen_file=`echo $proto_file | perl -pe 's/\.proto/\.pb\.cc/; s|.*/||'`;\
echo "*** Building $gen_file from $$proto_file ***"; \
protoc -I$mypbdir --cpp_out=./ $$proto_file;\
done
LTLIBRARIES = $(lib_LTLIBRARIES)
all: Makefile $(LTLIBRARIES)
然后我决定在脚本中添加以下两行:
foo:
echo $MY_SOURCE_FILES
运行 'make foo' 显示以下输出:
echo my_file.pb.cc
my_file.pb.cc
所以 MY_SOURCE_FILES 确实包含正确的值,但没有建立依赖关系。但是,在脚本中进行以下更改可以解决问题:
lib@PACKAGE_NAME@_protobuf_la_SOURCES = my_file.pb.cc
您可能会问,为什么不做出改变并对此感到满意呢?问题是 Makefile.am 被提供给处理“lib@PACKAGE_NAME@_protobuf_xxx”的程序。所以我必须想办法让事情顺利进行!我怀疑使用 'notdir' 函数不会以我想要的方式扩展变量 'MY_PB_FILES'。
我对 GNU Makefile 不是很精通,因此非常感谢任何建议或帮助。
【问题讨论】:
在你的例子中你使用lib@PACKAGE_NAME@_protobuf_la_SOURCES
,在你的“固定”例子中你使用lib@PACKAGE_NAME@_protobuf_la_SOURCE
(没有S
)。这是问题中的错字吗?此外,您没有具体说明“未建立依赖关系”的确切含义......您希望发生什么但不会发生?
那是一个错字。我会编辑帖子。感谢您的关注。我想要发生的是看到以下声明: *** Building my_file.pb.cc from /usr/share/project/my_file.proto ***
对我来说这看起来像一个自动制作文件。我认为您需要与汽车制造商讨论它。我的怀疑是 automake 正在为您处理一些可以与my_file.pb.cc
等静态字符串一起正常工作的东西,但不会扩展像$MY_SOURCE_FILES
这样的变量,所以它不能那样工作。
我也想过这个问题,但不确定这是否是 automake 问题。如果您手动修改生成的 makefile 并将 my_file.pb.cc 静态分配给 $MY_SOURCE_FILES,则 make 按预期工作。
是的,这就是我上面所说的“automake 正在为你处理一些事情”。也就是说,automake 可能正在查看 makefile 并对源文件做一些特殊的事情。但是由于 automake 不是 make,它要求变量中的值是显式的,而不是变量中的值。我对 automake 了解不多,无法告诉你,所以我建议你问问 automake 的人。
【参考方案1】:
目标是从许多 Protocol Buffer 文件中创建一个 C++ 库,其中一些可能位于只读目录中。
你不能把它们复制到$(top_builddir)
来解决这个问题吗?
为了绕过写权限,我想在 Makefile 目录中生成 C++ 文件。
所以这些也将在$(top_builddir)
中。
您可能应该查看给出的答案here,它设置了协议缓冲区编译器,更重要的是设置了 Makefile.am 中的规则。您可能需要根据您的情况对其进行一些修改。
所以基本上是这样的:
my_file.proto : /usr/share/project/my_file.proto
cp $< $@
%.pb.cc %.pb.h: %.proto
$(PROTOC) --proto_path=$(dir $^) --cpp_out=$(dir $^) $^
lib_LTLIBRARIES = lib@PACKAGE_NAME@_protobuf.la
lib@PACKAGE_NAME@_protobuf_la_SOURCES = my_file.pb.cc
lib@PACKAGE_NAME@_protobuf_la_LDFLAGS = -version-info @MAJOR_VERSION@:@MINOR_VERSION@:0
我在这里看到的唯一棘手的事情是:当调用make dist
时,tarball 中的内容是什么?
你真的要分发my_file.pb.cc
吗?
【讨论】:
目标是避免手动包含 my_file.proto 和 my_file.pb.cc 的需要。 Makefile.am 可能包含许多 .proto 文件,或者文件在其生命周期中经历了多次修改。期望开发人员一直记住这种情况是不合理的。正如@MadScientist 正确指出的那样,问题与automake 无法扩展 MY_SOURCE_FILES 以建立依赖关系有关。我已经向汽车制造商提出了类似的问题,但还没有收到任何人的消息。以上是关于协议缓冲区文件的 Makefile 自动依赖关系问题的主要内容,如果未能解决你的问题,请参考以下文章