mirror of
https://github.com/boostorg/build.git
synced 2026-02-16 01:12:13 +00:00
257 lines
8.6 KiB
XML
257 lines
8.6 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>
|
|
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 ojects 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>
|
|
<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 modules ;
|
|
local path = [ modules.peek : 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>
|
|
<title>Can I get output of external program as a variable in a Jamfile?
|
|
</title>
|
|
|
|
<para>From time to time users ask how to run an external program and save
|
|
the result in Jamfile variable, something like:
|
|
<programlisting>
|
|
local gtk_includes = [ RUN_COMMAND gtk-config ] ;
|
|
</programlisting>
|
|
Unfortunately, this is not possible at the moment. However, if the
|
|
result of command invocation is to be used in a command to some tool,
|
|
and you're working on Unix, the following workaround is possible.
|
|
<programlisting>
|
|
alias gtk+-2.0 : : : :
|
|
<cflags>"`pkg-config --cflags gtk+-2.0`"
|
|
<inkflags>"`pkg-config --libs gtk+-2.0`"
|
|
;
|
|
</programlisting>
|
|
If you use the "gtk+-2.0" target in sources, then the properties
|
|
specified above will be added to the build properties and eventually
|
|
will appear in the command line. Unix command line shell processes
|
|
the backticks quoting by running the tool and using its output --
|
|
which is what's desired in that case. Thanks to Daniel James for
|
|
sharing this approach.
|
|
</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> to a finer control:
|
|
<programlisting>
|
|
exe a : a.cpp b ;
|
|
obj b : b.cpp : <variant>release:<optimization>off ;
|
|
</programlisting>
|
|
|
|
</para>
|
|
</section>
|
|
|
|
|
|
</chapter>
|
|
<!--
|
|
Local Variables:
|
|
mode: xml
|
|
sgml-indent-data: t
|
|
sgml-parent-document: ("userman.xml" "chapter")
|
|
sgml-set-face: t
|
|
End:
|
|
--> |