Boost logo

Boost-Build :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2004-12-28 11:18:17


Hi Dave,
here are my comments on your doc edits.

diff -u -U10000 -r1.7 -r1.8
--- tutorial.xml 30 Oct 2004 09:32:04 -0000 1.7
+++ tutorial.xml 28 Dec 2004 03:39:09 -0000 1.8

<chapter id="bbv2.tutorial" status="draft">
<title>Tutorial</title>

+<!-- You can't launch into this stuff without describing how to configure -->
+<!-- Boost.Build... unless of course you think it's likely to work with -->
+<!-- no configuration. But even if you do you have to tell people how to -->
+<!-- configure their installation in case it doesn't work. -->
+

Sure, the "how to use this document" suggest that whenever the user decides to really try
V2, he look at installation docs. Do you think a link is in order here, too?

things. First of all, just invoking <command>bjam</command> will
- build the debug variant of the <command>hello</command>
+ build the debug variant of the <filename>hello</filename>>

Edit noted.

recompilation. Let's extend the example by adding another line
to our project's <filename>Jamfile</filename>:

<programlisting>
exe hello2 : hello.cpp ;
</programlisting>

Now we can build both the debug and release variants of our
project:

+<!-- The phrasing above misleadingly makes it seem as though adding -->
+<!-- this line makes it possible to build two variants, whereas -->
+<!-- they're totally unrelated. -->
+

Understood. Maybe "Now let us build both the debug and release variants of our project again"?
Of course, you probably have better wording anyway.

It's also possible to build or clean specific targets. The
following two commands, respectively, build or clean only the
- debug version of <command>hello2</command>.
+ debug version of <filename>hello2</filename>.
+
+<!-- You can't say that without first telling people that the debug
+variant is the default one, or you just sow confusion. -->

A bit earler -- after defining the "hello" target, we talk about "debug" variant. Maybe, the fact
that debug is default should be mentioned there?

<para>There are many built-in features that can be combined to
produce arbitrary build configurations. The following command
- builds the project's &quot;release&quot; variant with inlining
+ builds the project's <code>release</code> variant with inlining
disabled and debug symbols enabled:

Ok, so we'll be using <code> for all references to properties. What will be use when talking
about main targets -- quotation marks or <code>?

- <para>The "release" and "debug" that we've seen
+ <para>The <option>release</option> and <option>debug</option> that we've seen
in <command>bjam</command> invocations are just a shorthand way to
- specify values of the "variant" feature. For example, the command
+ specify values of the <varname>variant</varname> feature. For example, the command
above could also have been written this way:

Must have misunderstood something. Is <varname> for features and <code> for values?

<para>
- A complete description of features can be found
- <link linkend="bbv2.reference.features">here</link>.
+ A complete description of features can be found in <xref linkend="bbv2.reference.features"/>.
+<!-- <link linkend="bbv2.reference.features">here</link>. -->
+<!-- You can't use "here" style links because they don't work in printed documentation. -->

Noted.

<para>
The set of properties specified in the command line constitute a
- <firstterm>build request</firstterm> &#x2014; a description of
+ <firstterm>build request</firstterm>&#x2014;a description of

Why spaces are gone? At least in LyX/TeX, I always surround em-dashes with spaces.

<programlisting>
exe hello
: hello.cpp
: &lt;include&gt;/home/ghost/Work/boost &lt;threading&gt;multi
;
</programlisting>

+<!-- Can those requirements be written as
+ "include=/home/ghost/Work/boost threading=multi"? If so, we
+ should do everything in the manual, or at the very least in the
+ tutorial, that way. If not, why not? -->

We can't, because it's not implemented. I sure would like this syntax.

requirements specified above will normally always be present.
If the build request given on the <command>bjam</command>
command-line explictly contradicts a target's requirements,
the command-line usually overrides (or, in the case of
- &quot;free&quot; feautures like <code>&lt;include&gt;</code>
- <footnote>See <xref
- linkend="bbv2.reference.features.attributes"/></footnote>,
- augments) the target requirements.
+ &ldquo;free&rdquo; features like <varname>&lt;include&gt;</varname>,

What's ldquo and why it's better than quot?

+ <footnote>
+<para>
+See <xref linkend="bbv2.reference.features.attributes"/>
+ augments) the target requirements.

Are there unmatched parenthesis?

<!--
However, when a
contradiction of a target's requrements involves certain
<firstterm>link-incompatible</firstterm> features, the target
will be skipped. See <xref linkend=
"bbv2.reference.variants.compat"/> for more information.
-->
+
+<!-- Don't leave flotsam in the document/code. If the above is wrong, take -->
+<!-- it out. That's what source control is for. -->

Ok.

<para>So far we've only considered examples with one project
(i.e. with one <filename>Jamfile</filename>). A typical large
- software project would be composed of sub-projects organized
+ codebase would be composed of many projects organized
into a tree. The top of the tree is called the
<firstterm>project root</firstterm>. Besides a
<filename>Jamfile</filename>, the project root directory
contains a file called <filename>project-root.jam</filename>. Every other
<filename>Jamfile</filename> in the project has a single parent
project, rooted in the nearest parent directory containing a
<filename>Jamfile</filename>. For example, in the following
directory layout:

+<!-- Shouldn't we be introducing Jamroot here instead of -->
+<!-- project-root.jam? It certainly is simpler. -->
+

We definitely should.

<section id="bbv2.tutorial.libs">
<title>Libraries and Dependent Targets</title>

- <comment>TODO: need to make this
- section consistent with "examples-v2/libraries".</comment>
+ <remark>TODO: need to make this
+ section consistent with "examples-v2/libraries".</remark>
+
+<!--
+ What does that mean? Either make that change (much preferred),
+ or leave a comment that someone else can understand and use to
+ fix this section (only an option for the lazy ;->).
+-->

I meant that it might be good to have and example for each section of tutorial, so that user can experiment.
The examples/libraries is not equal to what's described here.

<para>
- Targets that are "needed" by other targets are called
+ Targets that are &#x201C;needed&#x201D; by other targets are called

What are those numeric entities?

<code>bar</code> will be built and linked in. What do we mean by
- "appropriate"? For example, suppose we build "app" with:
+ &#x201C;appropriate&#x201D;? For example, suppose we build <filename>app</filename> with:

And here?

<screen>
bjam app optimization=full cxxflags=-w-8080
</screen>

+<!-- I think it's a bad idea to expose nonportable features like
+ cxxflags this early in the documentation. It will tend to
+ encourage people who aren't familiar with Boost.Build to use them
+ when it could be avoided. I suggest using a portable feature like
+ <include> or <define> -->

I agree.

- includes, but then this work will be repeated for all programs
- which use "foo". A better solution is to modify
- util/foo/Jamfilie in this way:
+ <varname>&lt;optimization&gt;</varname> feature is propagated, so both <filename>app</filename> and
+ <filename>foo</filename> will be compiled with full optimization. But
+ <varname>&lt;cxxflags&gt;</varname> is not propagated: its value will be
+ added as-is to the compiler flags for <filename>a.cpp</filename>, but won't affect
+ <filename>foo</filename>. There are still a couple of problems. First, the library
+ probably has some headers that must be used when compiling
+ <filename>app.cpp</filename>. We could manually add the neccessary
+ <code>#include</code> paths to <filename>app</filename>'s
+ requirements as values of the
+ <varname>&lt;include&gt;</varname> feature, but then this work will be repeated for all programs
+ that use <filename>foo</filename>. A better solution is to modify
+ <filename>util/foo/Jamfile</filename> in this way:
+
+ <!-- Look up the rules for using "that" vs. "which." It's "Janfile,"
+ not "Jamfilie." Take care to avoid silly typos. -->

Found:

http://www.press.uchicago.edu/Misc/Chicago/cmosfaq/cmosfaq.WhichvsThat.html

which discusses "that" vs. "which" quite clearly. OTOH, at the end it says that using "which" in
restrictive clauses is "more or less okay (and popular among writers of British English)", so I have an excuse ;-)
(After all, my spellchecker uses British dictionary)

lib foo : foo.cpp ;
</programlisting>

- Usage requirements are requirements which are applied to
- dependents. In this case, &lt;include&gt; will be applied to all
- targets which use "foo" &#x2014; i.e. targets which have "foo"
- either in sources or in dependency properties. You'd need to
- specify usage requirements only once, and programs which use "foo"
- don't have to care about include paths any longer. Or course, the
- path will be interpreted relatively to "util/foo" and will be
- adjusted according to the <command>bjam</command>s invocation
- directory. For
- example, if building from project root, the final compiler's
+ Usage requirements are applied not to the target being declared
+ but to its
+ dependents. In this case, <literal>&lt;include&gt;.</literal> will be applied to all
+ targets that use <filename>foo</filename>&#x2014;i.e. targets that have <filename>foo</filename>
+ either in their sources or in their dependency properties.
+ <!-- You can't use the term "dependency properties" without first
+ defining it! This sort of thing happens over and over. I
+ suggest just saying "all targets that directly depend on foo." -->

I agree to this.

+ You'd need to
+ specify usage requirements only once, and programs that use <filename>foo</filename>
+ don't have to care about include paths any longer.
+ <!-- Point of good writing: programs are inanimate and don't
+ "care" about include paths.

Noted.

I suggest striking the previous
+ sentence anyway as it's redundant. -->

Agreed.

+ Of course, the
+ path will be interpreted relatively to <filename>util/foo</filename> and will be
+ adjusted according to the <command>bjam</command> invocation
+ directory.
+ <!-- You need to explain this path adjustment in the first place
+ you introduce #include paths, probably with a "Tip"
+ element.

Agreed.

It applies to all relative paths in
+ Boost.Build, some of which you've covered. -->

What do you mean?

- <para>The second problem is that we hardcode the path to library's
- Jamfile. Imagine it's hardcoded in 20 different places and we
- change the directory layout. The solution is to use project ids
- &#x2014; symbolic names, not tied to directory layout. First, we
- assign a project id to Jamfile in util/foo:</para>
+ <para>
+ The second problem <!-- by this point I've completely forgotten
+ that there was a first problem. I suggest starting the a new
+ paragraph for the first one, and describing these as improvements
+ we can make, rather than problems. -->

Agreed.

<programlisting>
exe app : app.cpp /foo//bar ;
</programlisting>

- The "/foo//bar" syntax is used to refer to target "foo" in
- project with global id "/foo" (the slash is used to specify global
- id). This way, users of "foo" do not depend on its location, only
- on id, which is supposedly stable. The only thing left, it to make
- sure that src/Jamfile knows the project id that it uses. We add to
- top/Jamfile the following line:
+<!-- It is counterintuitive and confusing to assign a top-level
+ absolute project ID to this subproject. It should be something
+ like /myproject/foo.
+
+ In fact I'm beginning to
+ wonder what the point of labelling the project root with
+ project-root.jam or Jamroot is. See my jamboost post. -DWA
+-->
+
+ The <filename>/foo//bar</filename> syntax is used to refer to the target <filename>bar</filename> in
+ <!-- I assume I was right to change foo into bar here. Please
+ take care not to make errors like this one; it leaves the
+ reader mightily confused about what's really going on if he
+ assumes the documentation is correct. -->
+ the project with global id <filename>/foo</filename> (the slash
+ is used to specify global id).
+ <!-- as opposed to what? There's no such thing as a "local" id
+ is there? This parenthetical remark is more confusing than
+ enlightening. It gives the impression that we could leave
+ the slash off and still have a project id, but a path
+ without a preceding slash always specifies a file path
+ (right?) -->
+ This way, users of <filename>foo</filename> do not depend on its location, only
+ on id, which is supposedly stable. The only thing left is to make
+ sure that <filename>src/Jamfile</filename> knows the project id that it uses. We add to
+ <filename>top/Jamfile</filename> the following line:

<programlisting>
use-project /foo : util/foo ;
</programlisting>

QUERTY

<section id="bbv2.tutorial.depends">
<title>Library dependencies</title>

- <para>The previous example was simple. Often, there are long chains
- of dependencies between libraries. The main application is a thin
- wrapper on top of library with core logic, which uses library of
- utility functions, which uses boost filesystem library.
+ <para>The previous example was simple, but there are often long chains
+ of dependencies between libraries. For example, the main application might be a thin
+ wrapper on top of library with core logic, which uses another library of
+ utility functions, which in turn uses the boost filesystem library.
Expressing these dependencies is straightforward:</para>

<programlisting>
lib utils : utils.cpp /boost/filesystem//fs ;
lib core : core.cpp utils ;
exe app : app.cpp core ;
</programlisting>

+ <!-- Point of style: the "ask a question and then answer it" style
+ you frequently use just complication. Use fewer words;
+ just come out and say what you mean.

I'll try.

+
+ Also, you can't have a "First,..." without a "Second,..." or
+ a "Next,...." Don't underestimate how much confusion that can
+ add for the reader.

Noted.

+
+ Also, "built just as written, and everything will work" is
+ vague and confusing.

Agreed.

+
+ This information might be too low-level for the main flow of
+ the tutorial. It also might turn out to be specific to some
+ particular platforms. It would be much better to handle it
+ in a callout box if you feel compelled to mention it here.
+
+ If you want to keep the info here, the whole paragraph needs
+ to be rewritten. You could say all this (including the
+ one-sentence paragraph that follows) in one or two sentences.
+
+ "When core is built as a dynamic library, it is linked
+ directly into utils. Static libraries can't link to other
+ libraries, so when core is built as a static library, its
+ dependency on utils is passed along to core's dependents,
+ causing app to be linked with both core and utils."

I think this wording is fine.

+ The material here probably doesn't warrant a whole section of
+ the document. "Libraries and Dependent Targets" isn't easy
+ to distinguish from "Library Dependencies" anyway. Merge the
+ two.

Agreed.

+
+ You *definitely* can't talk about "returning back" library
+ targets. That assumes the reader has a mental model of the
+ Boost.Build internals!

Noted.

<para>While the
previous section explained how to create and use libraries, it
- omitted one important detail. Libraries can be either
+ omitted one important detail.
+ <!-- The foregoing sentence adds nothing -->

Agreed.

and must be available at run time. Boost.Build can work with both
- types. By default, all libraries are shared. This is much more
+ types.
+ <!-- This section seems to be introducing the idea of static and
+ shared libraries, but you just spent a couple of paragraphs
+ talking about them in the previous section! Clearly that is
+ not "one important detail that was omitted." Please take care
+ that terms are defined and concepts introduced before they're
+ used. -->

This suggests that maybe, "Library Dependencies" section should be merged into "Static and shared libaries",
maybe even as tip at the end.

+ By default, all libraries are shared. This is much more
efficient in build time and space. But the need to install all
- libraries to some location is not always convenient, especially
- for debug builds. Also, if the installed shared library changes,
- all application which use it might start to behave differently.
+ libraries to some location
+ <!-- If I'm a reader who doesn't know about shared linking as
+ this section seems to assume, I have absolutely no context
+ for "the need to install all libraries to some location."
+ It has no obvious relationship to anything we're discussing
+ here. -->

Oh, that paragraph is really confusing!

+ is not always convenient, especially
+ for debug builds.
+ <!-- An incongruous assumption about the reader's knowledge.
+ The relationship of debug builds to all this is
+ non-obvious. -->

Agreed.

<para>Static libraries do not suffer from these problems, but
- considerably increase the size of application. Before describing
- static libraries, it's reasonable to give another, quite simple
+ can considerably increase the size of an application. Before describing
+ how to use static libraries, it's reasonable to give another, quite simple
approach. If your project is built with
- &lt;hardcode-dll-paths&gt;true property, then the application
- will include the full paths for all shared libraries, eliminating
- the above problems. Unfortunately, you no longer can move shared
+ <code>&lt;hardcode-dll-paths&gt;true</code> property, the application
+ will include the full paths to all shared libraries, eliminating
+ the above problems.
+ <!-- Not the last one. So it solves just one of two problems
+ mentioned above. -->
+ Unfortunately, once that's done, you can no longer move that shared
library to a different location, which makes this option suitable
only for debug builds. Further, only gcc compiler supports this
- option.</para>
+ option.
+ <!-- Now you tell me?! You should put all this information in a
+ <tip> box that begins "If you're a GCC user..." -->
+ </para>

I think this section should actually start with "Libraries can be either shared or static, and which one is best
depends on your situation". Then it will say about <link>static and <link>shared, say that putting a library
in sources of other library works no matter what kind of linking is used, and then mention
(in <tip>) the hardcode-dll-paths feature.

- <orderedlist>
- <listitem>
- <para>
- Suppose your library can be only build statically. This is
- easily achieved using requirements:
+ <para>
+ We can also use the <varname>&lt;link&gt;</varname> property
+ to express linking requirements on a per-target basis.
+ <!-- <orderedlist> The use of an orderedlist is inappropriate here. -->

Why? I'm trying to list several situation which are possible for shared/static linking combinations.

+ For example, if a particular executable can be correctly built
+ only with the static version of a library, we can qualify the
+ executable's <link
+ linkend="bbv2.reference.targets.references">target
+ reference</link> to the library as follows:
+
+<!-- There has been no earlier indication that target references can
+ contain properties. You can't assume that the reader will
+ recognize that strange incantation as a target reference, or that
+ she'll know what it means. You also can't assume that hyperlinks
+ will help the reader, because she may be working from a printout,
+ as I was. -->

Does it mean that properties in target references need to be explained here. Also, if hyperlinks
are useless in printed docs, doesn't it mean all information have to duplicated in the parts where its used?

+ <!-- Take note of the difference between "build" and
+ "built." This error is repeated throughout. -->

Will try to be more attentive.

<programlisting>

- Note that the <link linkend="bbv2.builtins.alias">alias</link>
- rule is specifically used for rename a reference to a target and possibly
+ The <link linkend="bbv2.builtins.alias"><functionname>alias</functionname></link>
+ rule is specifically used to rename a reference to a target and possibly
change the properties.
+
+ <!-- You should introduce the alias rule in an earlier
+ section, before describing how it applies to this
+ specific use-case, and the foregoing sentence should
+ go there. -->

Do you think "alias" deserves a separate section?

<section id="bbv2.tutorial.conditions">
<title>Conditions and alternatives</title>

- <para>As we've just figured out, properties can significally affect the
- way targets are built. The processing of the &lt;link&gt; feature is
- built in the build system, and is quite complex. But there is a couple
- of mechanisms which allow ordinary users to do different things
- depending on properties.
- </para>
+ <!-- We haven't "just figured out" anything. You didn't lead the
+ reader through a deductive process. -->
- <para>The first mechanism is called <firstterm>conditinal
- requirement</firstterm>. For example, you might want to set specific
- defines when the library is build as shared, or you have your own define
- to be used in release mode. Here's a piece of Jamfile.
+ <para>As we've just seen, properties can significally affect the
+ way targets are built.
+ <!-- What is the point in saying that? Affecting the way
+ targets are built is the whole point of properties. The
+ previous sentence makes it sound like affecting the way
+ targets are built is just an incidental characteristic. -->

Noted, the sentence is indeed bad.

+ The processing of the <varname>&lt;link&gt;</varname> feature is
+ built in, and is quite complex, but
+ <!-- These two points don't make an appropriate "A but B"
+ clause, because <link> doesn't allow the system to "do
+ different things depending on properties. -->
+ there are a couple
+ of mechanisms that allow ordinary users to do different things
+ depending on properties.
+ <!-- They don't _allow users_ to do different things; it's the
+ build system that does different things. And "different
+ things" is too vague. -->
+ </para>
+
+ <!-- You could replace the foregoing paragraph with:
+
+ "Sometimes, particular relationships need to be maintained
+ among a target's build properties. In this section we'll
+ discuss two mechanisms for expressing those relationships."
+
+ It took me about five minutes to figure out how to say that,
+ and it still isn't perfect. But at least it says what we're
+ about to talk about with _some_ precision. Saying what you
+ mean is hard and requires an investment of effort and
+ attention.
+ -->

I think your suggestions is fine. The only problems is that alternatives are not exactly
"relationships among properties", but I can't think of a better wording yet.

<programlisting>
lib network : network.cpp
- : &lt;link&gt;shared:&lt;define&gt;NEWORK_LIB_SHARED
- &lt;variant&gt;release:&lt;define&gt;EXTRA_FAST
+ : <strong>&lt;link&gt;shared:&lt;define&gt;NEWORK_LIB_SHARED</strong>
+ <strong>&lt;variant&gt;release:&lt;define&gt;EXTRA_FAST</strong>

Why <strong>? To mark up the interesting part of the example?
;

<para>
- Sometimes different variant of a target are so different, that
- describing them using conditional requirements would be hard. Imagine
- that a library has different sources on two supported toolsets, and
- dummy implementation for all the other toolset. We can express this
- situation using <firstterm>target alternatives</firstterm>:
-<programlisting>
-lib demangler : dummy_demangler.cpp ;
-lib demangler : demangler_gcc.cpp : &lt;toolset&gt;gcc ;
-lib demangler : demangler_msvc.cpp : &lt;toolset&gt;msvc ;
-</programlisting>
- The proper alternative will be automatically selected.
+ Sometimes the ways a target is built are 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 <firstterm>target
+ alternatives</firstterm>:
+<programlisting>
+lib demangler : dummy_demangler.cpp ; # alternative 1
+lib demangler : demangler_gcc.cpp : &lt;toolset&gt;gcc ; # alternative 2
+lib demangler : demangler_msvc.cpp : &lt;toolset&gt;msvc ; # alternative 3
+</programlisting>
+ In the example above, when built with <literal>gcc</literal>
+ or <literal>msvc</literal>, <filename>demangler</filename>
+ will use a source file specific to the toolset. Otherwise, it
+ will use a generic source file,
+ <filename>dummy_demangler.cpp</filename>.
+ <!-- You can't say "The proper alternative will be automatically
+ selected" because it presumes the user understands what's
+ proper. You haven't even said what an alternative is! -->

Noted.

<para>
- We've just learned how to use libraries which are created by
- Boost.Build. But some libraries are not. At the same time, those
+ We've just learned how to use libraries that are created by
+ Boost.Build. But some libraries are not.
+ <!-- You can't start a sentence with "But" -->

A style issue or hard grammar rule?

+ At the same time, those
libraries can have different versions (release and debug, for
example), that we
should select depending on build properties. Prebuilt targets
- provide a mechanism for that. Jamfile in util/lib2 can contain:
+ provide a mechanism for that. The Jamfile in util/lib2 can contain:
+
+ <!-- You should replace the above with:

+ To link to libraries whose build instructions
+ aren't given in a Jamfile, you just need to
+ create targets with an appropriate <file>
+ property. Target alternatives can be used to
+ associate multiple library files with a single
+ conceptual target.
+ -->

That's pretty conscise! Agreed.

- This defines two alternatives for target "lib2", and for each
- one names a prebuilt file. Naturally, there are no sources.
- Instead, the &lt;file&gt; feature is used to specify the file name.
- Which alternative is selected depends on properties of dependents.
- If "app" binary should use "lib2", we can write:
+ This <!-- you can't say "this defines" without an antecedent for
+ "this", e.g. "this example defines..." --> code

Noted.

- <para>More advanced use of prebuilt target is described in <link
- linkend="bbv2.recipies.site-config">a FAQ entry</link>.</para>
+ <para>A more advanced use of prebuilt targets is described in <xref
+ linkend="bbv2.recipies.site-config"/>.
+
+ <!-- "xxx is described in a FAQ entry" is confusing for the person
+ who is working with a printed manual. -->

Do you consider xref generally better than link? Like in TeX, where most references do not
include text?

<!--
Local Variables:
- mode: xml
+ mode: nxml

Hmm... now I need to reconfigure Emacs. Maybe it's good, as PSGML decided it won't auto-complete
element names for me anymore :-(

Now, what shall we do next? I can go ahead and apply edits which you did not apply, if that won't cause any conflicts
with what you're doing.

- 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