Boost logo

Boost-Build :

Subject: [Boost-build] stage.install problems
From: Johnny Stucklen (stuckj_at_[hidden])
Date: 2009-02-06 10:23:04


Hi,

I'm having a bit of problem using stage.install to stage binaries and
libraries in a project I'm working on. My basic problem is that I can't
reliably install all libraries dependencies for the binaries in the project
from the default build directory hierarchy (e.g.,
LIBNAME/gcc-default/debug/threading-multi ...). I realize there is an
<install-dependencies> feature on stage.install that handles just this
problem, but I'm running into the same problem I've seen posted previously
on this and other lists...enabling that for the binaries leads to bjam never
returning (I'm assuming it's due to the number of dependencies). The project
is somewhat large...~16 binaries with 50 or so libraries with many
dependencies between them. I know one potential answer to the problem is to
reduce our dependencies, but that's not really an option for us. The
dependencies are what they are. :-P

So, here's what I was trying as a work-around. I tried writing a rule to
register an install target for a given target. The idea was then to make a
rule that, given a target, would recursively lookup the installer for all
dependent targets (and the provided target) and add the resultant install
targets to a list. Then, generate an alias to all of the install targets
that could be called to install everything. The problem I ran into was how
to (in general) look up target sources / dependencies for a given target.
Here's what I have so far:

----------- SNIP -----------

rule register-install-target ( target : install-target )
{
    if $(target) in $(.targets)
    {
        errors.error "Install target already registered for $(target)." ;
    }
    else
    {
        .install-targets.$(target) = $(install-target) ;
    }
}

rule get-install-targets ( targets * )
{
    local install-targets ;

    for target in $(targets)
    {
        # Possibly empty...ok
        local install-target = $(.install-targets.$(target)) ;

        install-targets += $(install-target) ;
    }

    return $(install-targets) ;
}

rule generate-install-alias ( name : target : extra-requirements * ) ;
{
    local all-install-targets = [ generate-install-alias-helper $(target) ]
;
    [ sequence.unique $(all-install-targets) ] ;

    # Haven't gotten to handling requirements yet...trying to get deps
first...
    # TODO: Compare extra-requirements with usage requirements...should
probably delegate to some abstract target functionality...

    # TODO: Handle requirements, usage-requirements, ... Get the deps to
work first though.
    alias $(name) : $(all-install-targets) ;

    # TODO: Probably make it explicit in the calling module here too...
}

rule generate-install-alias-helper ( target ) ;
{
    local target-obj = [ targets.resolve-reference $(target) : [
project.current ] ] ;

    # Hmmm....where do I actually GET these from?
    local dep-refs = [ $(target-obj).dependencies ] ; # <-- doesn't work
since we're a main-target object...where to get sources / dependencies???

    for dep in $(dep-refs)
    {
        local dep-type ; # <-- not sure how to get this for a given target
object

        # Only care about library dependencies...
        if $(dep-type) in STATIC_LIB SHARED_LIB IMPORT_LIB
        {
            dep-refs += [ generate-install-alias-helper $(dep) ] ;
        }
    }

    dep-refs += $(target) ;

    return $(dep-refs) ;
}

----------- SNIP -----------

The above could be used as follows:

----------- SNIP -----------

exe hello-world
    : hello-world.cpp
      hello-world-lib
;

lib hello-world-lib
    : hello-world-lib.cpp
;

alias all
    : hello-world/<threading>multi
      hello-world/<threading>single
;

install hello-world-install
    : hello-world
    : <install-dependencies>off
      <install-type>EXE
;
explicit hellow-world-install ;

install hello-world-lib-install
    : hello-world-lib
    : <install-dependencies>off
      <install-type>LIB
;
explicit hellow-world-lib-install ;

register-install-target hello-world : hello-world-install ;
register-install-target hello-world-lib : hello-world-lib-install ;

generate-install-alias install-all : hello-world ;

----------- SNIP -----------

So, the two problems I ran into above are:
  - How to get the sources / dependencies from a main-target object
  - How to get the type for a target

And, more generally, does what I'm doing above even make sense. :)

NOTE: I don't claim to be a bjam expert. I only know what I've learned from
newsgroups and poking around boost-build. So, before I bang my head against
the wall anymore trying to do the above, I figured I'd try asking those who
are more knowledgable. :)

Thanks in advance,
-Johnny



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