Boost logo

Boost-Build :

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
^^^^^^^^^^^^^^
strike that
> signature:
>
> 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
^^^^^^^^^^
"applied 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
> examples:
>
> 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
^
"a"
> 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
my Jamfile!]

So, if I'm specifying a directory name, I can just write it using my
native path syntax, right?

c:\foo\bar

Oh, those backslashes have special meaning? Then certainly

c:\\foo\\bar

will work, right?
No?

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.
^------"a"-----^

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
^^^^^^^^^^^^^^ ^
"b" "a"
> Jamfile one level higher. Finally, the third target uses
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^---"c"
^^^^^^^^^^^^^^^^^^^^^^^^
"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
^^^ ^^^^^^
strike "must"
> 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 ;

...to here.

> 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
^^
strike
> 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
> <variant>release:<define>EXTRA_FAST
> ;
>
> In the example above, whenever network is built with <link>
> shared, <define>NEWORK_LIB_SHARED will be in its properties,
> too.
>
> 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
> rule:
>
> 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