automake 1.12 更改 bison/yacc 输出名称,向后不兼容的更改?
Posted
技术标签:
【中文标题】automake 1.12 更改 bison/yacc 输出名称,向后不兼容的更改?【英文标题】:automake 1.12 changes bison/yacc output names, backwards incompatible change? 【发布时间】:2013-04-19 06:24:49 【问题描述】:我已经在https://github.com/Habbie/autoyacc-problem 发布了一个存储库来演示我的问题。
在 automake 1.11 及以下版本中,使用 configure.ac 中的 AC_PROG_YACC
和 Makefile.am 中的 AM_YFLAGS=-d
,parser.yy 会变成 parser.cc 和 parser.h。使用 automake 1.12,我得到 parser.cc 和 parser.hh。因为 mybin.cc 有 include "parser.h"
,这意味着 1.12 破坏了我的构建。
我觉得这是一个向后不兼容的变化,但我觉得应该有一种理智的方式来处理这个问题。
演示:
git clone https://github.com/Habbie/autoyacc-problem.git
cd autoyacc-problem/
autoreconf -i
./configure
make
automake 1.11 的结果:构建了 mybin。 automake 1.12 的结果:
mybin.cc:1:20: error: parser.h: No such file or directory
救命!
注意:此示例中没有实际的 C++ 代码,但对于我的实际问题,我确实需要 g++。
【问题讨论】:
阅读 1.11 文档,根本没有提到标题:yacc 源文件的扩展名用于确定生成的 C 或 C++ 文件的扩展名。扩展名为 .y 的文件将转换为 .c 文件;同样,.yy 将变为 .cc; .y++,C++; .yxx,.cxx;和.ypp、.cpp。当前文档 (gnu.org/software/automake/manual/html_node/Yacc-and-Lex.html) 这样做:扩展名为 .y 的文件将因此转换为 .c 源和 .h 标头;同样,.yy 将变为 .cc 和 .hh[...]。因此,您使用的是未记录的行为→不是错误;) 不是说这是一个错误 - 说它不方便。 “不是错误”也不能解决我的问题:) 【参考方案1】:我不是专家;但是考虑到您如何依赖旧版本的 automake 中未记录的行为(请参阅 zhenech),您可以要求更新版本的 automake(因此您可以依赖已定义的行为);或者确保预期的文件是由 automake 生成的。
假设默认输出扩展名为“.hh”,您可以使用简单的 make 指令从 .h 文件(对于旧版本的 automake)生成 .hh 文件:
.h.hh:
cp $< $@
如果您更喜欢从 .hh 文件中生成 .h 文件,您可能需要翻转定义,并且根据我不熟悉的 autotools 的 lex/yacc 处理的具体情况,您可能需要将生成的文件添加到BUILT_SOURCES
【讨论】:
使用了这个的变体(需要 .hh.h,而不是 .h.hh)。这一切都解决了。谢谢!【参考方案2】:我在涉及使用bison
解析的项目中使用以下方法:
我有一个文件m4/AC_PROG_BISON.m4
附加(automake 版本 1.11 或更低版本)或不附加(版本 1.12+)以下行到 config.h 文件:
/* Use *.h extension for parser header file */
#define BISON_USE_PARSER_H_EXTENSION 1
在需要包含解析器生成的标头的文件中,我添加了以下#ifdef 语句:
#include "config.h"
#if defined(BISON_USE_PARSER_H_EXTENSION)
# include "my_parser.h"
#else
# include "my_parser.hh"
#endif
另外,让事情工作我将以下行附加到configure.ac
AC_PROG_BISON
现在根据 automake 版本,将包含相关的标头。
文件内容:m4/AC_PROG_BISON.m4
dnl
dnl Check for bison
dnl AC_PROG_BISON([MIN_VERSION=2.0])
dnl
AC_DEFUN([AC_PROG_BISON], [
if test "x$1" = "x" ; then
bison_required_version="2.6"
else
bison_required_version="$1"
fi
AC_CHECK_PROG(have_prog_bison, [bison], [yes],[no])
AC_DEFINE_UNQUOTED([BISON_VERSION], [0.0],
[Defines bison version if bison is not present])
#Do not use *.h extension for parser header file but *.hh
bison_use_parser_h_extension=false
if test "$have_prog_bison" = "yes" ; then
AC_MSG_CHECKING([for bison version >= $bison_required_version])
bison_version=`bison --version | head -n 1 | cut '-d ' -f 4`
AC_DEFINE_UNQUOTED([BISON_VERSION], [$bison_version],
[Defines bison version])
if test "$bison_version" \< "$bison_required_version" ; then
BISON=:
AC_MSG_RESULT([no])
AC_MSG_ERROR([Bison version 2.6 or higher must be installed on the system!])
else
AC_MSG_RESULT([yes])
BISON=bison
AC_SUBST(BISON)
#Verify automake version
#Upto version 1.11 parser headers for yy files are with h extension, from 1.12 it is hh
automake_version=`automake --version | head -n 1 | cut '-d ' -f 4`
AC_DEFINE_UNQUOTED([AUTOMAKE_VERSION], [$automake_version],
[Defines automake version])
if test "$automake_version" \< "1.12" ; then
#Use *.h extension for parser header file
bison_use_parser_h_extension=true
echo "Automake version < 1.12"
AC_DEFINE([BISON_USE_PARSER_H_EXTENSION], [1],
[Use *.h extension for parser header file])
fi
fi
else
BISON=:
AC_MSG_RESULT([NO])
fi
AM_CONDITIONAL([BISON_USE_PARSER_H_EXTENSION], [test x$bison_use_parser_h_extension = xtrue])
AC_SUBST(BISON)
])
【讨论】:
【参考方案3】:您可以强制包含包含的标题的某个文件名
%defines "parser.h"
在parser.yy
的顶部。 -d
选项与没有文件名的 %defines
相同。
请参阅GNU Bison Docs。
【讨论】:
以上是关于automake 1.12 更改 bison/yacc 输出名称,向后不兼容的更改?的主要内容,如果未能解决你的问题,请参考以下文章