I am running this example from "Lex & Yacc" (John R. Levine, Tony Mason & Doug Brown):
$ cat ch2-04.l
%{
unsigned verbose;
char *prog_name;
%}
%%
-h |
"-?" |
-help {
printf("usage is: %s [ -help | -h | -? ] [ -verbose | -v ] [ (-file | -f) filename ]\n", prog_name);
}
-v |
-verbose {
printf("verbose mode is on\n"); verbose=1;
}
%%
int main(int argc, char **argv) {
prog_name = *argv;
yylex();
return 0;
}
I try to compile it using:
$ lex ch2-04.l; cc -ll -o ch2-04 lex.yy.c
ld: error: duplicate symbol: main
>>> defined at libmain.c:29 (/usr/src/contrib/flex/src/libmain.c:29)
>>> libmain.o:(main) in archive /usr/lib/libl.a
>>> defined at lex.yy.c
>>> /tmp/lex-f8aca4.o:(.text+0x1D80)
cc: error: linker command failed with exit code 1 (use -v to see invocation)
Why main is being reported as already defined? The book is mentioning AT&T lex version and using K&R C, so I do understand that maybe there are differences in implementations of lex and that the book might be refering to an old lex implementation.
I am currently used the supplied lex version in FreeBSD.
Don't use -ll
as the lex library includes a main()
function implementation, or put it after a main()
routine has already been provided (as you provide it in lex.yy.c
) so the main module from the lex library is not include in the linking. The best is to put libraries at the end, so only the modules with undefined references to solve are linked into the program.
The -ll
just provides default implementations of yywrap()
and main()
, that cause yylex()
to return the first time end of file condition occurs, and a simple main()
implementation that just calls yylex();
once.
Change
lex ch2-04.l; cc -ll -o ch2-04 lex.yy.c
into
lex ch2-04.l; cc -o ch2-04 lex.yy.c -ll
and every will go fine.
Explanation: Whe the linker sees the -ll
function, it has already an unsolved reference to main()
that comes from the C runtime environment that is normally specified first to the compiler. So it includes the main()
function provided by the Lex library. When you link the file lex.yy.c
, a second version of main()
is provided (this time the one you provide in your lex source) conflicting with the already linked before.
Note: The main()
redefinition of the linker error is about your definition, and not the one in the lex library. The repeated definition is the one in your lex.yy.c
which is the one coming after the one in lex libary has already been included. The difference comes because the definition in a library is not included in the executable if the references to main()
had already been solved.