On Sun, Oct 3, 2010 at 4:14 AM, Vladimir Prus <ghost@cs.msu.su> wrote:
On Friday, October 01, 2010 00:45:15 Trevor wrote:
> How do I let Boost.Build know about dependencies on generated header files?
>
> I have a simple Jamfile that runs flex and bison, builds a library with the
> output, and builds an executable with the library and a source file:
>
> using bison ;
> using lex ;
> lib sql_parser : sql_lexer.ll sql_parser.yy : <link>static ;
> exe sql_parser_test : main.cpp sql_parser ;

try adding <implicit-dependency>sql_parser as requirement to your 'exe'
target. See documentation section on generated headers for more details.

Thanks, I tried that, and it seems to ensure that main.cpp is not built until after flex and bison are run. However, the dependency of sql_lexer.obj on sql_parser.hpp and of sql_parser.obj on sql_lexer.hpp is still not generated (according to the output of bjam -d+12), so compilation of the generated source is still being attempted before both flex and bison finish running. BTW, this dependency is due to the following directive in sql_parser.yy (and vice versa in sql_lexer.ll):

%code {
#include "sql_lex.hpp"
}

One thing that might be an issue is that lex.jam doesn't specify that it generates a header file. I've updated lex.jam to do so. Here are the relevant parts; please let me know if they look okay:

generators.register-standard lex.lex : LEX : C H ;
generators.register-standard lex.lex : LEX++ : CPP HPP ;

rule lex ( dst dst_header : src : properties * )
{
    local r = [ property.select flex.prefix : $(properties) ] ;
    if $(r)
    {
        PREFIX on $(<) = $(r:G=) ;
    }

    # simulate binding of source file
    local bound_src = [ on $(src) GLOB $(LOCATE) $(SEARCH) : $(src:G=) ] ;
    if $(bound_src)
    {
        # generate the header alongside the source file
        LOCATE on $(dst_header) = $(bound_src:D) ;
    }
}

actions lex
{
    flex -P$(PREFIX) --header-file=$(<[2]) -o$(<[1]) $(>)
}

(I also made similar updates to bison.jam so that the header file goes alongside the source. This allows source files in other projects to include the header file. Let me know if you think there's a better way to achieve this.)

I then tried using <implicit-dependency> on the individual obj targets (after renaming sql_parser.yy to sql_grammar.yy to avoid a name conflict with lib sql_parser):

obj sql_lex : sql_lex.ll : <link>static <implicit-dependency>sql_grammar ;
obj sql_grammar : sql_grammar.yy : <link>static <implicit-dependency>sql_lex ;
lib sql_parser : sql_lex sql_grammar : <link>static ;
exe sql_parser_test : main.cpp sql_parser <implicit-dependency>sql_parser ;

However, this gives me an error:

error: Recursion in main target references
error: the following target are being built currently:
error: ./sql_lex ./sql_grammar ./sql_lex

Is there some way to specify the (inter)dependency between these components that doesn't make Boost.Build think it's circular?

Thanks,
Trevor