mirror of
https://github.com/boostorg/build.git
synced 2026-02-11 11:42:14 +00:00
402 lines
15 KiB
XML
402 lines
15 KiB
XML
<?xml version="1.0" standalone="yes"?>
|
|
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
|
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
|
|
|
<chapter id="bbv2.faq">
|
|
<title>Frequently Asked Questions</title>
|
|
|
|
<section>
|
|
<title>
|
|
How do I get the current value of feature in Jamfile?
|
|
</title>
|
|
|
|
<para>
|
|
This is not possible, since Jamfile does not have "current" value of any
|
|
feature, be it toolset, build variant or anything else. For a single invocation of
|
|
<filename>bjam</filename>, any given main target can be built with several property sets.
|
|
For example, user can request two build variants on the command line. Or one library
|
|
is built as shared when used from one application, and as static when used from another.
|
|
Obviously, Jamfile is read only once, so generally, there's no single value of a feature
|
|
you can access in Jamfile.
|
|
</para>
|
|
|
|
<para>A feature has a specific value only when building a target, and there are two ways how you
|
|
can use that value:</para>
|
|
<itemizedlist>
|
|
<listitem><simpara>Use conditional requirements or indirect conditional requirements. See
|
|
<xref linkend="bbv2.advanced.targets.requirements.conditional"/>.</simpara>
|
|
</listitem>
|
|
<listitem>Define a custom generator and a custom main target type. The custom generator can do arbitrary processing
|
|
or properties. See the <xref linkend="bbv2.extender">extender manual</xref>.
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<title>
|
|
I'm getting "Duplicate name of actual target" error. What
|
|
does it mean?
|
|
</title>
|
|
|
|
<para>
|
|
The most likely case is that you're trying to
|
|
compile the same file twice, with almost the same,
|
|
but differing properties. For example:
|
|
|
|
<programlisting>
|
|
exe a : a.cpp : <include>/usr/local/include ;
|
|
exe b : a.cpp ;
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
The above snippet requires two different compilations
|
|
of 'a.cpp', which differ only in 'include' property.
|
|
Since the 'include' property is free, Boost.Build
|
|
can't generate two objects files into different directories.
|
|
On the other hand, it's dangerous to compile the file only
|
|
once -- maybe you really want to compile with different
|
|
includes.
|
|
</para>
|
|
|
|
<para>
|
|
To solve this issue, you need to decide if file should
|
|
be compiled once or twice.</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>Two compile file only once, make sure that properties
|
|
are the same:
|
|
|
|
<programlisting>
|
|
exe a : a.cpp : <include>/usr/local/include ;
|
|
exe b : a.cpp : <include>/usr/local/include ;
|
|
</programlisting></para></listitem>
|
|
|
|
<listitem><para>
|
|
If changing the properties is not desirable, for example
|
|
if 'a' and 'b' target have other sources which need
|
|
specific properties, separate 'a.cpp' into it's own target:
|
|
|
|
<programlisting>
|
|
obj a_obj : a.cpp : <include>/usr/local/include ;
|
|
exe a : a_obj ;
|
|
</programlisting></para></listitem>
|
|
|
|
<listitem><para>
|
|
To compile file twice, you can make the object file local
|
|
to the main target:
|
|
|
|
<programlisting>
|
|
exe a : [ obj a_obj : a.cpp ] : <include>/usr/local/include ;
|
|
exe b : [ obj a_obj : a.cpp ] ;
|
|
</programlisting></para></listitem>
|
|
|
|
</orderedlist>
|
|
|
|
<para>
|
|
A good question is why Boost.Build can't use some of the above
|
|
approaches automatically. The problem is that such magic would
|
|
require additional implementation complexities and would only
|
|
help in half of the cases, while in other half we'd be silently
|
|
doing the wrong thing. It's simpler and safe to ask user to
|
|
clarify his intention in such cases.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section id="bbv2.faq.envar">
|
|
<title>
|
|
Accessing environment variables
|
|
</title>
|
|
|
|
<para>
|
|
Many users would like to use environment variables in Jamfiles, for
|
|
example, to control location of external libraries. In many cases you
|
|
better declare those external libraries in the site-config.jam file, as
|
|
documented in the <link linkend="bbv2.recipies.site-config">recipes
|
|
section</link>. However, if the users already have the environment variables set
|
|
up, it's not convenient to ask them to set up site-config.jam files as
|
|
well, and using environment variables might be reasonable.
|
|
</para>
|
|
|
|
<para>In Boost.Build V2, each Jamfile is a separate namespace, and the
|
|
variables defined in environment is imported into the global
|
|
namespace. Therefore, to access environment variable from Jamfile, you'd
|
|
need the following code:
|
|
<programlisting>
|
|
import os ;
|
|
local SOME_LIBRARY_PATH = [ os.environ SOME_LIBRARY_PATH ] ;
|
|
exe a : a.cpp : <include>$(SOME_LIBRARY_PATH) ;
|
|
</programlisting>
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>
|
|
How to control properties order?
|
|
</title>
|
|
|
|
<para>For internal reasons, Boost.Build sorts all the properties
|
|
alphabetically. This means that if you write:
|
|
<programlisting>
|
|
exe a : a.cpp : <include>b <include>a ;
|
|
</programlisting>
|
|
then the command line with first mention the "a" include directory, and
|
|
then "b", even though they are specified in the opposite order. In most
|
|
cases, the user doesn't care. But sometimes the order of includes, or
|
|
other properties, is important. For example, if one uses both the C++
|
|
Boost library and the "boost-sandbox" (libraries in development), then
|
|
include path for boost-sandbox must come first, because some headers may
|
|
override ones in C++ Boost. For such cases, a special syntax is
|
|
provided:
|
|
<programlisting>
|
|
exe a : a.cpp : <include>a&&b ;
|
|
</programlisting>
|
|
</para>
|
|
|
|
<para>The <code>&&</code> symbols separate values of an
|
|
property, and specify that the order of the values should be preserved. You
|
|
are advised to use this feature only when the order of properties really
|
|
matters, and not as a convenient shortcut. Using it everywhere might
|
|
negatively affect performance.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<title>
|
|
How to control the library order on Unix?
|
|
</title>
|
|
|
|
<para>On the Unix-like operating systems, the order in which static
|
|
libraries are specified when invoking the linker is important, because by
|
|
default, the linker uses one pass though the libraries list. Passing the
|
|
libraries in the incorrect order will lead to a link error. Further, this
|
|
behaviour is often used to make one library override symbols from
|
|
another. So, sometimes it's necessary to force specific order of
|
|
libraries.
|
|
</para>
|
|
|
|
<para>Boost.Build tries to automatically compute the right order. The
|
|
primary rule is that if library a "uses" library b, then library a will
|
|
appear on the command line before library b. Library a is considered to
|
|
use b is b is present either in the sources of a or in its
|
|
requirements. To explicitly specify the use relationship one can use the
|
|
<use> feature. For example, both of the following lines will cause
|
|
a to appear before b on the command line:
|
|
<programlisting>
|
|
lib a : a.cpp b ;
|
|
lib a : a.cpp : <use>b ;
|
|
</programlisting>
|
|
</para>
|
|
|
|
<para>
|
|
The same approach works for searched libraries, too:
|
|
<programlisting>
|
|
lib z ;
|
|
lib png : : <use>z ;
|
|
exe viewer : viewer png z ;
|
|
</programlisting>
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section id="bbv2.faq.external">
|
|
<title>Can I get output of external program as a variable in a Jamfile?
|
|
</title>
|
|
|
|
<para>The <code>SHELL</code> builtin can be used for the purpose:
|
|
<programlisting>
|
|
local gtk_includes = [ SHELL "gtk-config --cflags" ] ;
|
|
</programlisting>
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>How to get the project-root location?
|
|
</title>
|
|
|
|
<para>You might want to use the location of the project-root in your
|
|
Jamfiles. To do it, you'd need to declare path constant in your
|
|
project-root.jam:
|
|
<programlisting>
|
|
path-constant TOP : . ;
|
|
</programlisting>
|
|
After that, the <code>TOP</code> variable can be used in every Jamfile.
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>How to change compilation flags for one file?
|
|
</title>
|
|
|
|
<para>If one file must be compiled with special options, you need to
|
|
explicitly declare an <code>obj</code> target for that file and then use
|
|
that target in your <code>exe</code> or <code>lib</code> target:
|
|
<programlisting>
|
|
exe a : a.cpp b ;
|
|
obj b : b.cpp : <optimization>off ;
|
|
</programlisting>
|
|
Of course you can use other properties, for example to specify specific
|
|
compiler options:
|
|
<programlisting>
|
|
exe a : a.cpp b ;
|
|
obj b : b.cpp : <cflags>-g ;
|
|
</programlisting>
|
|
You can also use <link linkend="bbv2.tutorial.conditions">conditional
|
|
properties</link> for finer control:
|
|
<programlisting>
|
|
exe a : a.cpp b ;
|
|
obj b : b.cpp : <variant>release:<optimization>off ;
|
|
</programlisting>
|
|
|
|
</para>
|
|
</section>
|
|
|
|
<section id="bbv2.faq.dll-path">
|
|
<title>Why are the <code>dll-path</code> and
|
|
<code>hardcode-dll-paths</code> properties useful?
|
|
</title>
|
|
|
|
<para>(This entry is specific to Unix system.)Before answering the
|
|
questions, let's recall a few points about shared libraries. Shared
|
|
libraries can be used by several applications, or other libraries,
|
|
without phisycally including the library in the application. This can
|
|
greatly decrease the total size of applications. It's also possible to
|
|
upgrade a shared library when the application is already
|
|
installed. Finally, shared linking can be faster.
|
|
</para>
|
|
|
|
<para>However, the shared library must be found when the application is
|
|
started. The dynamic linker will search in a system-defined list of
|
|
paths, load the library and resolve the symbols. Which means that you
|
|
should either change the system-defined list, given by the
|
|
<envar>LD_LIBRARY_PATH</envar> environment variable, or install the
|
|
libraries to a system location. This can be inconvenient when
|
|
developing, since the libraries are not yet ready to be installed, and
|
|
cluttering system paths is undesirable. Luckily, on Unix there's another
|
|
way.
|
|
</para>
|
|
|
|
<para>An executable can include a list of additional library paths, which
|
|
will be searched before system paths. This is excellent for development,
|
|
because the build system knows the paths to all libraries and can include
|
|
them in executables. That's done when the <code>hardcode-dll-paths</code>
|
|
feature has the <literal>true</literal> value, which is the
|
|
default. When the executables should be installed, the story is
|
|
different.
|
|
</para>
|
|
|
|
<para>
|
|
Obviously, installed executable should not hardcode paths to your
|
|
development tree. (The <code>stage</code> rule explicitly disables the
|
|
<code>hardcode-dll-paths</code> feature for that reason.) However, you
|
|
can use the <code>dll-path</code> feature to add explicit paths
|
|
manually. For example:
|
|
<programlisting>
|
|
stage installed : application : <dll-path>/usr/lib/snake
|
|
<location>/usr/bin ;
|
|
</programlisting>
|
|
will allow the application to find libraries placed to
|
|
<filename>/usr/lib/snake</filename>.
|
|
</para>
|
|
|
|
<para>If you install libraries to a nonstandard location and add an
|
|
explicit path, you get more control over libraries which will be used. A
|
|
library of the same name in a system location will not be inadvertently
|
|
used. If you install libraries to a system location and do not add any
|
|
paths, the system administrator will have more control. Each library can
|
|
be individually upgraded, and all applications will use the new library.
|
|
</para>
|
|
|
|
<para>Which approach is best depends on your situation. If the libraries
|
|
are relatively standalone and can be used by third party applications,
|
|
they should be installed in the system location. If you have lots of
|
|
libraries which can be used only by your application, it makes sense to
|
|
install it to a nonstandard directory and add an explicit path, like the
|
|
example above shows. Please also note that guidelines for different
|
|
systems differ in this respect. The Debian guidelines prohibit any
|
|
additional search paths, and Solaris guidelines suggest that they should
|
|
always be used.
|
|
</para>
|
|
|
|
</section>
|
|
|
|
<section id="bbv2.recipies.site-config">
|
|
<title>Targets in site-config.jam</title>
|
|
|
|
<para>It is desirable to declare standard libraries available on a
|
|
given system. Putting target declaration in Jamfile is not really
|
|
good, since locations of the libraries can vary. The solution is
|
|
to put the following to site-config.jam.</para>
|
|
<programlisting>
|
|
import project ;
|
|
project.initialize $(__name__) ;
|
|
project site-config ;
|
|
lib zlib : : <name>z ;
|
|
</programlisting>
|
|
|
|
<para>The second line allows this module to act as project. The
|
|
third line gives id to this project — it really has no location
|
|
and cannot be used otherwise. The fourth line just declares a
|
|
target. Now, one can write:
|
|
<programlisting>
|
|
exe hello : hello.cpp /site-config//zlib ;
|
|
</programlisting>
|
|
in any Jamfile.</para>
|
|
|
|
</section>
|
|
|
|
<section id="bbv2.faq.header-only-libraries">
|
|
<title>Header-only libraries</title>
|
|
|
|
<para>In modern C++, libraries often consist of just header files, without
|
|
any source files to compile. To use such libraries, you need to add proper
|
|
includes and, maybe, defines, to your project. But with large number of
|
|
external libraries it becomes problematic to remember which libraries are
|
|
header only, and which are "real" ones. However, with Boost.Build a
|
|
header-only library can be declared as Boost.Build target and all
|
|
dependents can use such library without remebering if it's header-only or not.
|
|
</para>
|
|
|
|
<para>Header-only libraries are declared using the <code>alias</code> rule,
|
|
that specifies only usage requirements, for example:
|
|
<programlisting>
|
|
alias mylib
|
|
: # no sources
|
|
: # no build requirements
|
|
: # no default build
|
|
: <include>whatever
|
|
;
|
|
</programlisting>
|
|
The includes specified in usage requirements of <code>mylib</code> are
|
|
automatically added to build properties of all dependents. The dependents
|
|
need not care if <code>mylib</code> is header-only or not, and it's possible
|
|
to later make <code>mylib</code> into a regular compiled library.
|
|
</para>
|
|
|
|
<para>
|
|
If you already have proper usage requirements declared for project where
|
|
header-only library is defined, you don't need to duplicate them for
|
|
the <code>alias</code> target:
|
|
<programlisting>
|
|
project my : usage-requirements <include>whatever ;
|
|
alias mylib ;
|
|
</programlisting>
|
|
</para>
|
|
|
|
</section>
|
|
|
|
|
|
</chapter>
|
|
<!--
|
|
Local Variables:
|
|
mode: nxml
|
|
sgml-indent-data: t
|
|
sgml-parent-document: ("userman.xml" "chapter")
|
|
sgml-set-face: t
|
|
End:
|
|
--> |