Habbie
Habbie

Reputation: 2230

automake 1.12 changes bison/yacc output names, backwards incompatible change?

I have posted a repository at https://github.com/Habbie/autoyacc-problem to demonstrate my issue.

With automake 1.11 and below, using AC_PROG_YACC in configure.ac and AM_YFLAGS=-d in Makefile.am, parser.yy gets turned into parser.cc and parser.h. With automake 1.12, I get parser.cc and parser.hh. Because mybin.cc has include "parser.h", this means 1.12 breaks my build.

I have the feeling this is a backwards incompatible change, but I feel there should be a sane way to deal with this.

To demonstrate:

git clone https://github.com/Habbie/autoyacc-problem.git
cd autoyacc-problem/
autoreconf -i
./configure
make

Result with automake 1.11: mybin gets built. Result with automake 1.12:

mybin.cc:1:20: error: parser.h: No such file or directory

Help!

Note: there is no actual C++ code in this example but for my real issue I do need g++.

Upvotes: 5

Views: 1407

Answers (3)

nido
nido

Reputation: 531

I aint no expert; but given how you are depending on undocumented behaviour in the older versions of automake (see zhenech) you can either require a newer version of automake (so you can depend on defined behaviour); or make sure the expected file is generated by automake.

Given the default output extension is ".hh" you can make something that generates the .hh file out of the .h file (for the older versions of automake) with a simple make instruction:

.h.hh:
    cp $< $@

if you prefer to generate .h files out of .hh files you may want to turn around the definitions, and depending on specifics of lex/yacc processing of autotools i am infamilar with, you might want to add the generated file to BUILT_SOURCES

Upvotes: 2

JonnyJD
JonnyJD

Reputation: 2643

You can force a certain file name for the header with including

%defines "parser.h"

at the top of parser.yy. The -d option is the same as just %defines without a file name.

See the GNU Bison Docs.

Upvotes: 0

radekg1000
radekg1000

Reputation: 71

I use the following approach in projects which involve parsing using bison:

I have a file m4/AC_PROG_BISON.m4 which either appends (automake version 1.11 or lower) or doesn't append (version 1.12+) the following line to config.h file:

/* Use *.h extension for parser header file */
#define BISON_USE_PARSER_H_EXTENSION 1

Than in the file where the parser generated header needs to be included I add the following #ifdef statement:

#include "config.h"
#if defined(BISON_USE_PARSER_H_EXTENSION)
#   include "my_parser.h"
#else
#   include "my_parser.hh"
#endif

Additionally go get things work I append the following line to configure.ac

AC_PROG_BISON

Now depending on the automake version the relevant header will be included.

File contents: 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)
])

Upvotes: 0

Related Questions