From: David Abrahams (dave_at_[hidden])
Date: 2005-09-22 12:28:30
> Declaring targets
> A Main target is a user-defined named entity that can be built,
> for example an executable file. Declaring a main target is
> usually done
should be: "A main target is usually declared..."
> using one of the main target rules described in
> the section called âBuiltin target typesâ. The user can also
> declare custom main target rules as shown in the section called
> âMain target rulesâ.
I don't think this last sentence belongs here. I suggest you strike it.
> Most main target rules in Boost.Build have the same common
> rule rule-name (
> main-target-name :
> sources + :
> requirements * :
> default-build * :
> usage-requirements * )
> â main-target-name is the name used to request the target on
> command line and to use it from other main targets. A main
"and to refer to it in target references"
> target name may contain alphanumeric characters, dashes
> (â-â), and underscores (â_â).
> â sources is the list of source files and other main targets
> that must be combined.
^ "in order to build the target being declared"
> â requirements is the list of properties that must always be
> present when this main target is built.
> â default-build is the list of properties that will be used
> unless some other value of the same feature is already
> specified, e.g. on the command line or by propogation from
"because they are required by"
> a dependent target.
> â usage-requirements is the list of properties that will be
> propagated to all main targets that use this one, i.e. to
This last use of "propagated" is particularly bad because it goes in
the opposite direction from a propagated feature, which goes from
dependents to dependencies.
> all its dependents.
> Some main target rules have a shorter list of parameters;
> consult their documentation for details.
That's like saying "some english words have multiple meanings; look
them up in the dictionary for details." How am I going to find them?
I suggest you strike that sentence; you already said "most."
> The actual requirements for a target are obtained by refining
> requirements of the project where a target is declared with the
> explicitly specified requirements.
should be "with the requirements explicitly specified in its
declaration." But even so, I think this is terribly hard to
understand, and unless it can be clarified it should be dropped.
Nobody knows what "refining with" means. That's not normal usage.
> The same is true for usage-requirements. More details can be found
> in the section called âProperty refinementâ
In the spirit of many of Andrey's posts, I think it would be good to
avoid introducing a new technical term for this process, if possible.
> The list of sources specifies what should be processed to get
> the resulting targets. Most of the time, it's just a list of
> files. Sometimes, you'll want to automatically construct the
> list of source files rather than having to spell it out
> manually, in which case you can use the glob rule. Here are two
> exe a : a.cpp ; # a.cpp is the only source file
> exe b : [ glob *.cpp ] ; # all .cpp files in this directory are sources
> Unless you specify a file with an absolute path, the name is
> considered relative to the source directoryâwhich is typically
> the directory where the Jamfile is located, but can be changed
> as described in the section called âProjectsâ.
> The list of sources can also refer to other main targets.
", which become dependencies of the target being declared"^
> Targets in the same project can be referred to by name, while
> targets in other projects must be qualified with a directory or
> a symbolic project name. The directory/project name is
replace with " or "----------------^
> separated from the target name by double slash. There's no
> special syntax to distinguish directory name from project
> nameâthe part before double slash is first looked up as project
> name, and then as directory name.
[I still find that confusing. There's no way to know how a Jamfile
should be interpreted without knowing which project declarations have
already been seen. Also, the introduction of a new project id
declaration in a remote project I'm using will change the meaning of
So, if I'm specifying a directory name, I can just write it using my
native path syntax, right?
Oh, those backslashes have special meaning? Then certainly
will work, right?
Now you're going to have to tell people about that normalized path
syntax stuff, another thing I have big problems with, and I think
users will, too.
> For example:
> lib helper : helper.cpp ;
> exe a : a.cpp helper ;
> # Since all project ids start with slash, ".." is directory name.
Didn't you just say "there's no special syntax to distinguish...?"
This seems like you're contradicting yourself.
> exe b : b.cpp ..//utils ;
> exe c : c.cpp /boost/program_options//program_options ;
> The first exe uses the library defined in the same project.
"executable, a," "helper"
> The second one uses some target (most likely library) defined by
> Jamfile one level higher. Finally, the third target uses
"The Jamfile in the parent directory of this project."
> some C++ Boost library, referring to it by absolute symbolic name.
"the Boost Serialization library"
> More information about target references can be found in the section
> called âDependent Targetsâ and the section called âTarget
> identifiers and referencesâ.
All of these cross-references are getting distracting.
> Requirements are the properties that should always be present
> when building a target. Typically, they
> are includes and defines:
"consist of #include paths and preprocessor symbol definitions"
> exe hello : hello.cpp : <include>/opt/boost <define>MY_DEBUG ;
> There is a number of other feature, listed in the section
"are" "features" (no comma)
> called âBuiltin featuresâ.
Strike everything from here...
> For example if a library can only be
> built statically, or a file can't be compiled with optimization
> due to a compiler bug, one can use
> lib util : util.cpp : <link>static ;
> obj main : main.cpp : <optimization>off ;
> The default-build parameter is a set of properties to be used
> if the build request does not otherwise specify a value for
> features in the set. For example:
> exe hello : hello.cpp : : <threading>multi ;
> would build a multi-threaded target in unless the user
> explicitly requests a single-threaded version. The difference
> between requirements and default-build is that requirements
> cannot be overriden in any way.
Isn't the following nearly all copy/paste from some earlier section I
have just reviewed?? That shouldn't be!
> Sometimes, particular relationships need to be maintained among
> a target's build properties. This can be achieved with
> conditional requirement. For example, you might want to set
> specific #defines when a library is built as shared, or when a
> target's release variant is built in release mode.
> lib network : network.cpp
> : <link>shared:<define>NEWORK_LIB_SHARED
> In the example above, whenever network is built with <link>
> shared, <define>NEWORK_LIB_SHARED will be in its properties,
> The ways a target is built can be so different that describing
> them using conditional requirements would be hard. For example,
> imagine that a library actually uses different source files
> depending on the toolset used to build it. We can express this
> situation using target alternatives:
> lib demangler : dummy_demangler.cpp ; # alternative 1
> lib demangler : demangler_gcc.cpp : <toolset>gcc ; # alternative 2
> lib demangler : demangler_msvc.cpp : <toolset>msvc ; # alternative 3
> In the example above, when built with gcc or msvc, demangler
> will use a source file specific to the toolset. Otherwise, it
> will use a generic source file, dummy_demangler.cpp.
> It is possible to declare a target inline, i.e. the "sources"
> parameter may include calls to other main rules. For example:
> exe hello : hello.cpp
> [ obj helpers : helpers.cpp : <optimization>off ] ;
> Will cause "helpers.cpp" to be always compiled without
> optimization. When referring to an inline main target, its
> declared name must be prefixed by its parent target's name and
> two dots. In the example above, to build only helpers, one
> should run bjam hello..helpers.
> When no target is requested on the command line, all targets in
> the current project will be built. If a target should be built
> only by explicit request, this can be expressed by the explicit
> explicit install_programs ;
-- Dave Abrahams Boost Consulting www.boost-consulting.com
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