Search code examples
flex-lexerlexautoconfrhel6

AM_PROG_LEX and undefined yywrap


My program uses the documented autoconf macro AM_PROG_LEX. It builds fine on RHEL 6.5 and other distros, but fails on RHEL 6.6 and later.

The configure script cannot compile its tests. When it tries gcc with -ll, -lfl, linking fails with:

/usr/bin/ld: cannot find -lfl

When it tries gcc without extra libraries, linking fails with:

undefined reference to `yywrap'

libfl.a or libfl.so is missing from official repos of those systems. On RHEL 6.5 it's part of flex package.

RHEL 6.5
configure:5334: checking whether yytext is a pointer
configure:5351: gcc -o conftest -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -O0   conftest.c -lfl  >&5
configure:5351: $? = 0
configure:5359: result: yes


RHEL 6.8
configure:5196: checking whether yytext is a pointer
configure:5217: gcc -o conftest -g -O2   conftest.c   >&5
/tmp/ccNJtVgv.o: In function `input':
/home/git/rpmbuild/BUILD/snacc-1.3.1_16_g23ba7a6/lex.yy.c:1168: undefined reference to `yywrap'
/tmp/ccNJtVgv.o: In function `yylex':
/home/git/rpmbuild/BUILD/snacc-1.3.1_16_g23ba7a6/lex.yy.c:867: undefined reference to `yywrap'
/tmp/ccNJtVgv.o: In function `main':
/home/git/rpmbuild/BUILD/snacc-1.3.1_16_g23ba7a6/conftest.l:17: undefined reference to `yywrap'
collect2: ld returned 1 exit status
configure:5224: $? = 1
configure: failed program was:
...
configure:5246: result: no

Solution

  • libfl contains two and only two functions, both of which are normally unnecessary in production use of flex:

    int main() { extern int yylex(void); while (yylex()) ; return 0; }
    int yywrap(void) { return 1; }
    

    The yywrap implementation (which essentially disables the yywrap functionality) is not necessary if you use the option

    %option noyywrap
    

    in your flex definition, or if you pass the command-line option --noyywrap to flex.

    For quick-and-dirty flex scanners, or for debugging, it is sometimes handy to be able to use libfl to fill in the above functions. But it also can create problems on systems which provide both 32- and 64-bit environments. For this reason, libfl was removed from the RHEL flex rpm in 2014. See this RedHat bug fix advisory for details.

    So you could install the appropriate flex-devel rpm in order to have libfl available. Or you could compile it yourself using the above code (which is not precisely the source code you'll find in the flex source bundle, but should produce precisely the same library).

    Or you could try to fix autoconf so that it doesn't depend on libfl. It didn't used to have any such dependency; if it couldn't find libfl, it would just assume that it wasn't required for the program being compiled.