1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Features</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.69.1">
<link rel="start" href="../../index.html" title="PartI.Boost.Build v2 User Manual">
<link rel="up" href="../extender.html" title="Chapter5.Extender Manual">
<link rel="prev" href="tools.html" title="Tools and generators">
<link rel="next" href="rules.html" title="Main target rules">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tools.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="rules.html"><img src="../../images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="bbv2.extending.features"></a>Features</h2></div></div></div>
<p>
Often, we need to control the options passed the invoked tools. This
is done with features. Consider an example:
</p>
<pre class="programlisting">
# Declare a new free feature
import feature : feature ;
feature verbatim-options : : free ;
# Cause the value of the 'verbatim-options' feature to be
# available as 'OPTIONS' variable inside verbatim.inline-file
import toolset : flags ;
flags verbatim.inline-file OPTIONS <verbatim-options> ;
# Use the "OPTIONS" variable
actions inline-file
{
"./inline-file.py" $(OPTIONS) $(<) $(>)
}
</pre>
<p>
We first define a new feature. Then, the <code class="computeroutput">flags</code> invocation
says that whenever verbatin.inline-file action is run, the value of
the <code class="computeroutput">verbatim-options</code> feature will be added to the
<code class="computeroutput">OPTIONS</code> variable, and can be used inside the action body.
You'd need to consult online help (--help) to find all the features of
the <code class="computeroutput">toolset.flags</code> rule.
</p>
<p>
Although you can define any set of features and interpret their values
in any way, Boost.Build suggests the following coding standard for
designing features.
</p>
<p>Most features should have a fixed set of values that is portable
(tool neutral) across the class of tools they are designed to work
with. The user does not have to adjust the values for a exact tool. For
example, <code class="computeroutput"><optimization>speed</code> has the same meaning for
all C++ compilers and the user does not have to worry about the exact
options passed to the compiler's command line.
</p>
<p>
Besides such portable features there are special 'raw' features that
allow the user to pass any value to the command line parameters for a
particular tool, if so desired. For example, the
<code class="computeroutput"><cxxflags></code> feature allows you to pass any command line
options to a C++ compiler. The <code class="computeroutput"><include></code> feature
allows you to pass any string preceded by <code class="computeroutput">-I</code> and the interpretation
is tool-specific. (See <a href="../faq/external.html" title="Can I get output of external program as a variable in a Jamfile?
">the section called “Can I get output of external program as a variable in a Jamfile?
”</a> for an example of very smart usage of that
feature). Of course one should always strive to use portable
features, but these are still be provided as a backdoor just to make
sure Boost.Build does not take away any control from the user.
</p>
<p>
Using portable features is a good idea because:
</p>
<div class="itemizedlist"><ul type="disc">
<li><p>When a portable feature is given a fixed set of
values, you can build your project with two different
settings of the feature and Boost.Build will automatically
use two different directories for generated files.
Boost.Build does not try to separate targets built with
different raw options.
</p></li>
<li><p>Unlike with “raw” features, you don't need to use
specific command-line flags in your Jamfile, and it will be
more likely to work with other tools.
</p></li>
</ul></div>
<p>
</p>
<h3>
<a name="id2577355"></a>Steps for adding a feauture</h3>
<p>Adding a feature requires three steps:
</p>
<div class="orderedlist"><ol type="1">
<li>
<p>Declaring a feature. For that, the "feature.feature"
rule is used. You have to decide on the set of <a href="../reference/definitions.html#bbv2.reference.features.attributes" title="Feature Attributes">feature
attributes</a>:
</p>
<div class="itemizedlist"><ul type="disc">
<li><p>if a feature has several values and
significantly affects the build, make it “propagated,” so that the
whole project is built with the same value by
default</p></li>
<li><p>if a feature does not have a fixed
list of values, it must be “free.” For example, the
<code class="computeroutput">include</code> feature is a free
feature.</p></li>
<li><p>if a feature is used to refer to a
path relative to the Jamfile, it must be a “path”
feature. <code class="computeroutput">include</code> is also a path
feature.</p></li>
<li><p>if feature is used to refer to some target, it
must be a “dependency” feature. </p></li>
</ul></div>
<p>
</p>
</li>
<li><p>Representing the feature value in a
target-specific variable. Build actions are command
templates modified by Boost.Jam variable expansions. The
<code class="computeroutput">toolset.flags</code> rule sets a target-specific
variable to the value of a feature.</p></li>
<li><p>Using the variable. The variable set in step 2 can
be used in a build action to form command parameters or
files.</p></li>
</ol></div>
<p>
</p>
<h3>
<a name="id2577462"></a>Another example</h3>
<p>Here's another example.
Let's see how we can make a feature that refers to a target. For example,
when linking dynamic libraries on windows, one sometimes needs to specify
"DEF file", telling what functions should be exported. It would be nice to
use this file like this:
</p>
<pre class="programlisting">
lib a : a.cpp : <def-file>a.def ;
</pre>
<p>
Actually, this feature is already supported, but anyway...
</p>
<div class="orderedlist"><ol type="1">
<li>
<p>Since the feature refers to a target, it must be "dependency".
</p>
<pre class="programlisting">
feature def-file : : free dependency ;
</pre>
<p>
</p>
</li>
<li>
<p>One of the toolsets that cares about
DEF files is msvc. The following line should be added to it.
</p>
<pre class="programlisting">
flags msvc.link DEF_FILE <def-file> ;
</pre>
<p>
</p>
</li>
<li>
<p>Since the DEF_FILE variable is not used by the
msvc.link action,
we need to modify it to be:
</p>
<pre class="programlisting">
actions link bind DEF_FILE
{
$(.LD) .... /DEF:$(DEF_FILE) ....
}
</pre>
<p>
</p>
<p> Note the <code class="computeroutput">bind DEF_FILE</code> part. It tells
bjam to translate the internal target name in
<code class="varname">DEF_FILE</code> to a corresponding filename in
the <code class="computeroutput">link</code> action. Without it the expansion of
<code class="computeroutput">$(DEF_FILE)</code> would be a strange symbol that is
not likely to make sense for the linker.
</p>
<p>
We are almost done, but we should stop for a small workaround. Add the following
code to msvc.jam
</p>
<pre class="programlisting">
rule link
{
DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
}
</pre>
<p>
This is needed to accomodate some bug in bjam, which hopefully
will be fixed one day.
</p>
</li>
</ol></div>
<h3>
<a name="id2577576"></a>Variants and composite features.</h3>
<p>Sometimes you want to create a shortcut for some set of
features. For example, <code class="computeroutput">release</code> is a value of
<code class="computeroutput"><variant></code> and is a shortcut for a set of features.
</p>
<p>It is possible to define your own build variants. For example:
</p>
<pre class="programlisting">
variant crazy : <optimization>speed <inlining>off
<debug-symbols>on <profiling>on ;
</pre>
<p>
will define a new variant with the specified set of properties. You
can also extend an existing variant:
</p>
<pre class="programlisting">
variant super_release : release : <define>USE_ASM ;
</pre>
<p>
In this case, <code class="computeroutput">super_release</code> will expand to all properties
specified by <code class="computeroutput">release</code>, and the additional one you've specified.
</p>
<p>You are not restricted to using the <code class="computeroutput">variant</code> feature
only.
Here's example that defines a brand new feature:
</p>
<pre class="programlisting">
feature parallelism : mpi fake none : composite link-incompatible ;
feature.compose <parallelism>mpi : <library>/mpi//mpi/<parallelism>none ;
feature.compose <parallelism>fake : <library>/mpi//fake/<parallelism>none ;
</pre>
<p>
This will allow you to specify the value of feature
<code class="computeroutput">parallelism</code>, which will expand to link to the necessary
library.
</p>
</div>
<table width="100%"><tr>
<td align="left"></td>
<td align="right"><small></small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tools.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="rules.html"><img src="../../images/next.png" alt="Next"></a>
</div>
</body>
</html>
|