Boost logo

Boost-Build :

Subject: Re: [Boost-build] boost build - user module configuration
From: Phillip Seaver (phil_at_[hidden])
Date: 2015-01-23 08:40:57


On 1/22/15 8:13 AM, Stefan Pflueger wrote:
>
> Hello,
>
> I'm currently working on a c++ project that uses bjam (boost build) as
> a builder. For now I was quite happy with this build system and
> everything works nicely, however with one exception which I could not
> find an easy solution for:
>
> I would like to have a build configuration of this project, in which
> the user is able to switch on or off certain modules and its
> dependencies (also automatic checks if software is not found ->
> disable module..). With dependencies I mean for example applications
> that require this module to work. So these applications should also
> not be built when the module is disabled.
>
> Since I found nothing out there that could do this job for me, I
> created some variables in the jamroot (top level jamfile) that
> resemble the module structure of the project, and I use these
> variables in if statements within the appropriate jamfiles to switch
> on and off things. See below for an example:
>
> Jamroot excerpt:
>
> |constant build_DataReader : 1 ;
> constant build_RootReader : 1 ;
> constant build_AsciiReader : 1 ;
>
> if $(build_DataReader) {
> build-project DataReader ;
> }|
>
> Jamfile for DataReader Module:
>
> |sources = [ glob *.cpp ] ;
> if $(build_RootReader)
> {
> build-project RootReader ;
> sources = $(sources) $(DATAREADER)/RootReader//RootReader ;
> }
> if $(build_AsciiReader)
> {
> build-project AsciiReader ;
> sources = $(sources) $(DATAREADER)/AsciiReader//AsciiReader ;
> }
>
> # Build libDataReader.so
> lib DataReader :
> $(sources)
> ;
>
> install dist : DataReader : <location>$(TOP)/lib ;|
>
> However this is not a very elegant solution, as I would constantly
> have to update these hardcoded if statements when dependencies change
> etc.. In addition it is annoying to have to construct this tree
> structure of the modules in the project myself, as boost build is
> constructing the same thing internally by itself. Is there some kind
> of option in boost build to make the building of applications optional
> in case some requirements are not built in the current build process?
>
> The only solution I see at the moment would be to construct a complete
> new config tool that would create the jamfiles for me like I want them
> (preprocessor). However this is work I do not want to start, and I
> don't really believe that there is nothing out there that is able to
> do what seems to me like pretty common stuff. But probably I missed
> something completely...
>
> Hope I explained it in an understandable way, thanks in advance!
>
> Steve
>

I was going to adapt what I have, but I didn't feel like debugging it,
so here's what I use to automatically create projects in my Jamroot:

JAMFILE = [ modules.peek : JAMFILE ] ;

local dbg_auto ;
if --debug-auto-load in [ modules.peek : ARGV ] {
    dbg_auto = 1 ;
    ECHO "JAMFILE =" $(JAMFILE) ;
}

use-project /boost : misc/boostlibs ;

local plat_dirs = mac win ;
local sub_dirs = [ set.difference [ sequence.unique [ glob */* ] ] :
$(plat_dirs) ] ;
local search_dirs = [ MATCH (.*/.*)/.* : [ glob $(sub_dirs)/$(JAMFILE) ] ] ;
for local d in $(search_dirs) {
    local p = [ MATCH (.*)/(.*) : $(d) ] ;
    if ! ( $(p[1]) in $(plat_dirs) ) {
        if $(dbg_auto) {
            ECHO "using " $(d) "as project" /$(p[2]) ;
        }
    }
    use-project /$(p[2]) : $(d) ;
}

In our root directory, we have "libs" for libraries, "progs" for
programs, "win" for Windows code, and "mac" for OS X code. Under the
"libs" and "progs" directories, there are directories for each project,
which have a build.jam in them ("win" and "mac" have their own "libs"
and "progs", but I left out the code that deals with that).

So, e.g., I have libs/filters, which has a build.jam file in it. That
code will do "use-project /filters : libs/filters ;" so I can just use
"/filters" anywhere I need it. That also means that I can bulid any of
the automatically created projects from anywhere in the tree, e.g., "b2
/filters"

For your case, you could add "constant build_$(p[2]) : 1 ;" and change
the "use-project" to "build-project". You'd also have to remove one
level of directory from the glob and MATCH calls and change the "p" usage.

If you wanted to disable a module from the command line, you could do
something like "if --no-build-$(p[2]) in [ modules.peek : ARGV ]" and
pass "--no-build-AsciiReader", e.g., on the command line.

I used lots of "ECHO" statements while creating this code and "EXIT ;"
to stop b2 after that code was parsed and run but before the build
actually occurred.

Hope that helps!

Phillip


Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk