如何在 autoconf/automake 中使用协议缓冲区?
Posted
技术标签:
【中文标题】如何在 autoconf/automake 中使用协议缓冲区?【英文标题】:How to use protocol-buffers with autoconf/automake? 【发布时间】:2012-12-18 19:16:09 【问题描述】:正在寻找用于构建使用协议缓冲区的项目的 autoconf 和 automake 规则的良好示例,以及将 protoc 添加到构建过程的最佳方式?
【问题讨论】:
【参考方案1】:configure.ac
就 protobuf 库而言,它使用 pkg-config
,因此最好使用 PKG_CHECK_MODULES
宏来引用它:
PKG_CHECK_MODULES(PROTOBUF, protobuf >= 2.4.0)
AC_SUBST(PROTOBUF_LIBS)
AC_SUBST(PROTOBUF_CFLAGS)
AC_SUBST(PROTOBUF_VERSION)
并检查路径中的protoc
命令。这是一个非常基本的检查它是否在路径中:
AC_CHECK_PROG([PROTOC], [protoc], [protoc])
AS_IF([test "x$PROTOC" == "x"],
[AC_MSG_ERROR([ProtoBuf compiler "protoc" not found.])])
或者,允许用户使用--with-protoc=/path/to/protoc
或使用环境变量PROTOC
指定不同的protoc
:
# ProtoBuf compiler.
# First, specify with --with-protoc=/path/of/protoc.
# Or, specify with env variable PROTOC.
# If neither of the above, find it in the path.
#AC_MSG_CHECKING([for ProtoBuf compiler protoc])
AC_ARG_WITH([protoc],
[AS_HELP_STRING([--with-protoc=/path/of/protoc],
[Location of the protocol buffers compiler protoc. Defaults to looking on path.])],
[PROTOC="$withval"],
[ AS_IF([test "x$PROTOC" == "x"],
[AC_PATH_PROG([PROTOC], [protoc], [no])])
]
)
#AC_MSG_RESULT([$PROTOC])
AS_IF([test "$PROTOC" == "no"], [AC_MSG_ERROR([ProtoBuf compiler "protoc" not found.])])
Makefile.am
添加规则以构建proto
文件:
%.pb.cc %.pb.h: %.proto
$(PROTOC) --proto_path=$(srcdir) --cpp_out=$(builddir) $^
用dist_noinst_DATA
指定protobuf 源文件。这对于确保将它们捆绑在使用 make dist
制作的源代码分发 .tar.gz
文件中是必要的。
dist_noinst_DATA = whatever.proto
(注意:对于较新版本的 autoconf/automake,可能需要使用@builddir@
而不是$(builddir)
。)
使用nodist_
前缀和$(builddir)
路径指定生成的文件:
nodist_myprog_SOURCES = $(builddir)/whatever.pb.cc $(builddir)/whatever.pb.h
然后用make clean
清理它们:
MOSTLYCLEANFILES = whatever.pb.cc whatever.pb.h
使用BUILT_SOURCES
处理构建头文件的依赖关系:
BUILT_SOURCES = whatever.pb.h
您的编译器标志可能需要参考构建目录来查找头文件(在 VPATH 构建中工作):
AM_CPPFLAGS += -I$(builddir)
【讨论】:
如果autoconf >= 0.24
如section 3.2 of Autotools myths 中所述,则不需要AC_SUBST(PROTOBUF_*)
非常好,谢谢! nodist_myprog_SOURCES
现在需要使用@builddir@/whatever.pb.cc
。【参考方案2】:
这似乎有效:
配置.ac:
AC_ARG_WITH([protobuf-libdir],
[AS_HELP_STRING([--with-protobuf-libdir=LIB_DIR],
[location of the protocol buffers libraries, defaults to /usr/lib])],
[PROTOBUF_LIBDIR="$withval"],
[PROTOBUF_LIBDIR='/usr/lib'])
AC_SUBST([PROTOBUF_LIBDIR])
LDFLAGS="$LDFLAGS -L$PROTOBUF_LIBDIR"
AC_CHECK_LIB([protobuf], [main], [], [AC_MSG_ERROR([cannot find protobuf library])])
AC_ARG_WITH([protoc],
[AS_HELP_STRING([--with-protoc=PATH],
[location of the protoc protocol buffer compiler binary, defaults to protoc])],
[PROTOC="$withval"],
[PROTOC='protoc'])
AC_SUBST([PROTOC])
Makefile.am:
%.pb.cc %.pb.h: %.proto
$(PROTOC) --proto_path=$(dir $^) --cpp_out=$(dir $^) $^
然后将 .pb.cc 文件添加到 SOURCES。
【讨论】:
Makefile.am
规则是否适用于 VPATH 构建(例如 mkdir build; cd build; ../configure; make
)?输出文件可能应该进入$builddir
而不是$srcdir
。
在Makefile.am
规则中使用$(dir $^)
,我收到错误Makefile.am:11: dir $^: non-POSIX variable name; Makefile.am:11: (probably a GNU make extension)
。以上是关于如何在 autoconf/automake 中使用协议缓冲区?的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 autoconf/automake 排除 boost 库/头文件包含问题?
可移植地在 autoconf/automake 中包含 GLib 标头
安装 Autoconf, Automake & Libtool
如何正确更新 m4、autoconf、automake 和 libtool? Mac OSX
autoconf/automake/libtool - 如何取消定义 PACKAGE_NAME、PACKAGE_TARNAME、PACKAGE_VERSION 等