5

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++.

Habbie
  • 2,150
  • 15
  • 17
  • Reading 1.11 docs, there is no mention of headers at all: The extension of a yacc source file is used to determine the extension of the resulting C or C++ file. Files with the extension .y will be turned into .c files; likewise, .yy will become .cc; .y++, c++; .yxx, .cxx; and .ypp, .cpp. Current docs (https://www.gnu.org/software/automake/manual/html_node/Yacc-and-Lex.html) do: Files with the extension .y will thus be turned into .c sources and .h headers; likewise, .yy will become .cc and .hh[...]. So you were using undocumented behaviour → not a bug ;) – zhenech Apr 19 '13 at 06:48
  • 1
    Not saying it's a bug - saying it's inconvenient. "not a bug" doesn't solve my issue, also :) – Habbie Apr 19 '13 at 07:15

3 Answers3

2

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

nido
  • 521
  • 3
  • 5
0

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)
])
radekg1000
  • 71
  • 7
0

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.

JonnyJD
  • 2,593
  • 1
  • 28
  • 44