Boost logo

Boost-Build :

From: elesende (elesende_at_[hidden])
Date: 2004-06-18 11:46:10


Thanks for you response. I'm not sure that I understand how
Boost.Build works internally. But by examining the --debug-
generators output I can see that the generator is spawned only once
and from there on its get cloned for each target. The thing is that
generated-targets is only called when it is spawned. Am I wrong?

Check the following output (look the for ECHO java-generated-
targets, its an ECHO inside the generated-targets rule of the java-
compiler generator)
--------------------- OUTPUT ---------------------
*** construct JAR_LIB
from { com/pack1/pack2/Vector.JAVA }
from { com/pack1/pack2/Vector2.JAVA }
properties: <debug-symbols>on <exception-handling>on
<hardcode-dll-paths>false <inlining>off <link-runtime>shared
<link>shared <main-target-type>LIB <optimization>off <os>NT
<profiling>off <rtti>on <runtime-debugging>on <stdlib>native
<symlink-location>project-relative <threading>single <toolset>jdk
<traverse-dependencies>off <user-interface>console <variant>debug
find-viable-generators target-type= JAR_LIB property-set=
jdk/debug
trying type *
trying generator prebuilt-file-generator ( -> * )
trying type JAR_LIB
trying generator jdk.archive ( CLASS -> JAR_LIB )
matched with rank 0
*** 1 viable generators
generator jdk.archive
multiple:
composing: true
*** construct CLASS (may return multiple targets)
from { com/pack1/pack2/Vector.JAVA }
properties: <debug-symbols>on <exception-handling>on
<hardcode-dll-paths>false <inlining>off <link-runtime>shared
<link>shared <main-target-type>LIB <optimization>off <os>NT
<profiling>off <rtti>on <runtime-debugging>on <stdlib>native
<symlink-location>project-relative <threading>single <toolset>jdk
<traverse-dependencies>off <user-interface>console <variant>debug
*** construct CLASS (may return multiple targets)
from { %.JAVA }
properties: <debug-symbols>on <exception-
handling>on <hardcode-dll-paths>false <inlining>off <link-
runtime>shared <link>shared <main-target-type>LIB <optimization>off
<os>NT <profiling>off <rtti>on <runtime-debugging>on <stdlib>native
<symlink-location>project-relative <threading>single <toolset>jdk
<traverse-dependencies>off <user-interface>console <variant>debug
find-viable-generators target-type= CLASS property-set=
jdk/debug
trying type *
trying generator prebuilt-file-generator ( -> * )
trying type CLASS
trying generator jdk.compile ( JAVA -> CLASS )
matched with rank 0
*** 1 viable generators
generator jdk.compile
multiple:
composing:
alt1
java-generated-targets
sources %
SUCCESS: { jdk%jdk.compile-%.CLASS { %.JAVA } }

generator jdk.compile spawned
{ jdk%jdk.compile-%.CLASS { %.JAVA } } --
*** putting to cache?
*** cloning { jdk%jdk.compile-%.CLASS { %.JAVA } }
*** cloned { jdk%jdk.compile-Vector.CLASS {
com/pack1/pack2/Vector.JAVA } } --- { jdk%jdk.compile-Vector.CLASS {
com/pack1/pack2/Vector.JAVA } }
*** construct CLASS (may return multiple targets)
from { com/pack1/pack2/Vector2.JAVA }
properties: <debug-symbols>on <exception-handling>on
<hardcode-dll-paths>false <inlining>off <link-runtime>shared
<link>shared <main-target-type>LIB <optimization>off <os>NT
<profiling>off <rtti>on <runtime-debugging>on <stdlib>native
<symlink-location>project-relative <threading>single <toolset>jdk
<traverse-dependencies>off <user-interface>console <variant>debug
*** putting to cache?
*** cloning { jdk%jdk.compile-%.CLASS { %.JAVA } }
*** cloned { jdk%jdk.compile-Vector2.CLASS {
com/pack1/pack2/Vector2.JAVA } } --- { jdk%jdk.compile-Vector2.CLASS
{ com/pack1/pack2/Vector2.JAVA } }
alt2 : consumed is { jdk%jdk.compile-Vector.CLASS {
com/pack1/pack2/Vector.JAVA } } { jdk%jdk.compile-Vector2.CLASS {
com/pack1/pack2/Vector2.JAVA } }
SUCCESS: { jdk%jdk.archive-emi.JAR_LIB { jdk%jdk.compile-
Vector.CLASS { com/pack1/pack2/Vector.JAVA } } { jdk%jdk.compile-
Vector2.CLASS { com/pack1/pack2/Vector2.JAVA } } }

generator jdk.archive spawned
{ jdk%jdk.archive-emi.JAR_LIB { jdk%jdk.compile-Vector.CLASS
{ com/pack1/pack2/Vector.JAVA } } { jdk%jdk.compile-Vector2.CLASS {
com/pack1/pack2/Vector2.JAVA } } } --
make -- all
make -- all
time -- all: unbound
--------------------- OUTPUT ---------------------

BTW: You can compile file by file in Java, if you compile them in
the right order. If you do not, then the java compiler will
automatically compile any dependency.

Any insight you might provide is greatly appreciated.
Regards,
Emiliano

--- In jamboost_at_[hidden], Vladimir Prus <ghost_at_c...> wrote:
> Hi Emiliano,
>
> > Hello! I've been trying to extend Boost.Build v2 system so it
will
> > be able to compile java files and generate jars. Ive created a
base
> > system mainly from builtin.jam called java.jam that added a few
type-
> > declarations and basic-targets and rules. I also added a
register-
> > java-compiler.
>
> That's great. You know, it's one of the nicest things in open-
source when you
> sit buried in some hacking at work, and suddenly a user sends some
new
> functionality!
>
> > So currently I get X.java compiled into com/yyy/X.class. But the
> > system is expecting something <build-dir>\bin\jdk\debug\X.class.
Is
> > there anyway to override this into "<build-
> > dir>\bin\jdk\debug\com/yyy/X.class"? (I'm willing to regex source
> > file for package definition).
>
> I think I'd have to first ask how do you plan to use it? There are
two
> approaches:
>
> 1. You drop all .java files in the same directory and they are
compiled in
> the 'right' directories.
> 2. You arrange source files according to package name.
>
> I'm not Java programmer, but it seems that a number of projects
(e.g. all of
> http://jakarta.apache.org) use the second convention.
>
> In this case you need not parse source files for package name, but
just need
> to make sure V2 does not strip paths from names of sources.
However, we
> traditionally allowed relative paths in sources, like:
>
> sources = a b c ;
> exe a : ../src/$(sources) ;
>
> so maybe this 'don't strip path to source' behaviour should be
java-specific.
> See below for a possible approach.
>
> Also, another question from a Java niebie: it's it always
necessary to compile
> all sources in one invocation, or one can compile them one-by-one?
>
> > type.register JAR_LIB : jar : : main ;
> > type.register JAVA : java ;
> > type.register CLASS : class ;
> >
> > class jar-target-class : basic-target
> > {
> > import generators : construct : generators.construct ;
> > import type ;
> > import path ;
> >
> > rule __init__ ( name : project
> >
> > : sources * : requirements * : default-build * : usage-
> >
> > requirements * )
> > {
> > basic-target.__init__ $(name) : $(project)
> >
> > : $(sources) : $(requirements) : $(default-build) :
> >
> > $(usage-requirements) ;
> > }
> >
> > rule construct ( source-targets * : property-set )
> > {
> > local properties = [ $(property-set).raw ] ;
> > # Determine the needed target type
> > local actual-type ;
> > actual-type = JAR_LIB ;
> > property-set = [ $(property-set).add-raw <main-target-
> > type>LIB ] ;
> > # Construct the target.
> > return [ generators.construct $(self.project)
$(self.name) :
> > $(actual-type)
> >
> > : $(property-set) : $(source-targets) :
> >
> > LIB ] ;
> > }
> > }
>
> It looks like the only thing this class does is pass JAR_LIB as
type to
> generators.construct. In that case you probably can drop this
class
> completely, and ....
>
> > rule jar ( name : sources * : requirements * : default-build *
> >
> > : usage-requirements * )
> >
> > {
> > local project = [ CALLER_MODULE ] ;
> >
> > # This is a circular module dependency, so it must be
imported
> > here
> > import targets ;
> > targets.main-target-alternative
> > [ new jar-target-class $(name) : $(project)
>
> ... create typed-target here, passing JAR_LIB as type. BTW, are
you working
> with m9.1 or with CVS. If with CVS, then you better use [
project.current ]
> instead of [ CALLER_MODULE ] . With CALLER_MODULE the 'jar' rule
can be only
> invoked in Jamfile, and with project.current it can be called from
everywhere
> -- for example, your project-root.jam can define a helper rule
which calls
> 'jar'.
>
>
> > class java-compile-action : action
> > {
> > import sequence ;
> >
> > rule __init__ ( targets + : sources * : action-name :
properties
> > * )
> > {
> > action.__init__ $(targets) : $(sources) : $(action-
name) :
> > $(properties) ;
> > }
> >
> > # For all virtual targets for the same dependency graph as
self,
> > # i.e. which belong to the same main target, add their
> > directories
> > # to include path.
> > rule adjust-properties ( properties * )
> > {
> > local s = [ $(self.targets[1]).creating-subvariant ] ;
> > return $(properties) [ $(s).implicit-
includes "include" ] ;
> > }
> > }
>
> I'm not sure this rule (adjust-properties) is necessary. For C, it
makes sure
> that every .h header which is created in the same main target is
in include
> path. For example:
>
> exe a : a.cpp parser.y ;
>
> here parser.h is created from parser.y and is put in bin/debug...
but will
> should be found by #include "parser.h" in a.cpp. In Java, we have
import, and
> I guess that this functionality is not needed.
>
> I think that you can handle the names issue by redefining the
> 'generated-targets' rule in this generators. For each Java source,
you can
> get its path with:
>
> local p = [ $(s).project ] ;
> local location = [ path.root [ $(s).name ]
> [ $(p).get source-location ] ] ;
>
> after that you can compute relative path from source location with
> path.relative. After that, you can adjust the name of generated
targets.
> The result would be that com/something/X.java can be compiled to
> bin/debug/com/something/X.class.
>
> I did not try to implement this myself, so there might be problems
along there
> way. In that case, don't hesitate to ask.
>
> > # Declare generators
> > generators.register-composing jdk.archive : CLASS : JAR_LIB :
> > <toolset>jdk ;
> > generators.register-java-compiler jdk.compile : JAVA : CLASS :
> > <toolset>jdk ;
> >
> > # Declare flags and action for compilation
> > actions compile
> > {
> > $(NAME:E=javac) $(OPTIONS) "$(>)"
> > }
> >
> > # Declare action for creating static libraries
> > actions piecemeal archive
> > {
> > jar -cf "$(<)" "$(>)"
> > }
>
> I guess you'll add support for the "classpath" feature later?
>
> - Volodya

 


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