CodeShop

Bjam Custom Generator

August 21st, 2007

A project I work on uses lex&yacc (actually, flex and bison) to build a parser/code-generator. So how do I do that in jamfiles?

Actually, it’s quite simple: all you need to do is add the .l (lex) and .y (yacc) file to your project. Bjam knows how to handle the extensions:

1
2
3
4
5
6
lib xxgen
  : 
  grammar.y
  scanner.l
  my-source.cpp
  ;

But take care to add <include>. to your requirements section. Otherwise the generated source will not compile, if it includes anything from your source directory: the compiler will not use it as /I …

The code mentioned above is used to build a custom code generator, which is used in another project. So how would you do that? How would you call your own generator from your jamfiles …

Well, I took the bison.jam file and modified it a bit to use my commands. (You could also take a look at the generator example in the boost/tools/build/v2/example directory).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
## xxgen.jam
##
##

import generators ;
import feature ;
import type ;
import property ;

feature.feature xxgen.prefix : : free ;
type.register XX : xx ;
generators.register-standard xxgen.xxgen : XX : CPP HPP ;

rule init ( )
{
}

rule xxgen ( dst dst_header : src : properties * )
{
    local r = [ property.select xxgen.prefix : $(properties) ] ;
    if $(r)
    {
        PREFIX_OPT on $(<) = -p $(r:G=) ;
    }
}

actions xxgen
{
    xxgen $(PREFIX_OPT) -option+ $(>) $(<[1]) 
}

The new extension is called ‘xx’ – and when bjam encounters it, it will call my xxgen rule/action. You will need to import the new definition:

1
2
3
4
5
6
7
8
9
10
11
12
13
## other-project.jam
##
##

import xxgen ;

lib mylib
  :
  my-definition-1.xx
  my-definition-2.xx

  my-source.cpp
 ;

Bjam sees the .xx extension and calls the rule/action from xxgen.jam – this generates cpp code which subsequently is compiled …

That’s all folks :)