Я разместил репозиторий на https://github.com/Habbie/autoyacc-problem продемонстрировать мою проблему.
С automake 1.11 и ниже, используя AC_PROG_YACC
в configure.ac и AM_YFLAGS=-d
в Makefile.am 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 ++.
Я не эксперт; но учитывая то, как вы зависите от недокументированного поведения в более старых версиях automake (см. Женек), вы можете либо потребовать более новую версию automake (так что вы можете зависеть от определенного поведения); или убедитесь, что ожидаемый файл генерируется automake.
Учитывая, что выходным расширением по умолчанию является «.hh», вы можете сделать что-то, что сгенерирует файл .hh из файла .h (для более старых версий automake) с помощью простой инструкции make
.h.hh
:
cp $< $@
если вы предпочитаете генерировать файлы .h из файлов .hh, возможно, вы захотите перевернуть определения, и в зависимости от особенностей обработки leo / yacc автоинструментов, с которыми я небезызвестен, вы можете добавить сгенерированный файл в BUILT_SOURCES.
Я использую следующий подход в проектах, которые включают разбор с использованием bison
:
У меня есть файл m4/AC_PROG_BISON.m4
который либо добавляет (автоматизировать версию 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)
])
Вы можете заставить определенное имя файла для заголовка с включением
%defines "parser.h"
на вершине parser.yy
, -d
вариант такой же как и просто %defines
без имени файла.
Увидеть GNU Bison Docs.