![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
TutorialBoost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 45. Boost.Build User Manual
|
![]() |
Tip |
---|---|
Значение< |
Если нам нужны те же требования к другой цели<hello2
>, мы можем просто дублировать их. Тем не менее, по мере роста проектов этот подход приводит к большому количеству повторяющихся байлеров в Jamfiles. К счастью, есть способ получше. Каждый проект может указывать наборатрибутов, включая требования:
project : requirements <include>/home/ghost/Work/boost <threading>multi ; exe hello : hello.cpp ; exe hello2 : hello.cpp ;
Результат будет таким, как если бы мы указали одно и то же требование для<hello
>и<hello2
>.
Пока мы рассматривали только примеры с одним проектом, с одним написанным пользователем Boost. Файл Джема,<Jamroot
>. Типичная большая кодовая база состоит из множества проектов, организованных в дерево. Верхняя часть дерева называется корнем проекта. Каждый подпроект определяется файлом<Jamfile
>в каталоге-потомке корня проекта. Родительский проект подпроекта определяется ближайшим<Jamfile
>или<Jamroot
>файлом в каталоге предков. Например, в следующем макете каталога:
top/ | +-- Jamroot | +-- app/ | | | +-- Jamfile | `-- app.cpp | `-- util/ | +-- foo/ . | . +-- Jamfile . `-- bar.cpp
Корень проекта<top/
>. Проекты<top/app/
>и<top/util/foo/
>являются непосредственными детьми основного проекта.
![]() |
Note |
---|---|
Когда мы ссылаемся на файл “Jamfile, ” установленный в нормальном типе, мы имеем в виду файл под названием< |
Проекты наследуют все атрибуты (например, требования) от своих родителей. Унаследованные требования сочетаются с любыми требованиями, указанными в подпроекте. Например, если<top/Jamroot
>
<include>/home/ghost/local
В своих требованиях, тогда все его подпроекты будут иметь его в своих требованиях. Конечно, любой проект может добавить пути к тем, которые указаны его родителями.<hello2
>Более подробную информацию можно найти вразделе под названием & #8220; Проекты & #8221;.
Включениеb2без явного указания каких-либо целей в командной строке строит проект, укорененный в текущем каталоге. Построение проекта автоматически не приводит к созданию его подпроектов, если только JAMFILE не запрашивает его. В нашем примере<top/Jamroot
>может содержаться:
build-project app ;
Это означает, что проект в 90 году будет построен всякий раз, когда проект в 91 году будет построен. Однако цели в<top/util/foo/
>будут строиться только в том случае, если они нужны целям в<top/
>или<top/app/
>.
При построении цели<X
>, которая зависит от первого построения другой цели<Y
>(например, библиотеки, которая должна быть связана сX),<Y
>называется зависимостью<X
>и<X
>называется зависимостью<Y
>.
Чтобы почувствовать зависимость от цели, давайте продолжим приведенный выше пример и посмотрим, как<top/app/Jamfile
>может использовать библиотеки из<top/util/foo
>. Если<top/util/foo/Jamfile
>содержит
lib bar : bar.cpp ;
Чтобы использовать эту библиотеку в<top/app/Jamfile
>, мы можем написать:
exe app : app.cpp ../util/foo//bar ;
Хотя<app.cpp
>относится к обычному исходному файлу,<../util/foo//bar
>является ссылкой на другую цель: библиотеку<bar
>, объявленную в Jamfile на<../util/foo
>.
![]() |
Tip |
---|---|
Некоторые другие системы сборки имеют специальный синтаксис для перечисления зависимых библиотек, например< |
Предположим, что мы строим<app
>:
b2 app optimization=full define=USE_ASM
Какие объекты будут использоваться для строительства<foo
>? Ответ заключается в том, что некоторые функциираспространяютсяи #8212; Повышение. Создавайте попытки использовать зависимости с одинаковым значением распространяемых функций. Распространена функция<<optimization>
>, поэтому и<app
>, и<foo
>будут скомпилированы с полной оптимизацией. Но<<define>
>не распространяется: его значение будет добавлено как есть к флагам компилятора<a.cpp
>, но не повлияет<foo
>.
Давайте еще больше улучшим этот проект. Библиотека, вероятно, имеет некоторые заголовки, которые должны использоваться при компиляции<app.cpp
>. Мы могли бы вручную добавить необходимые<#include
>пути к<app
>требованиям в качестве значений<<include>
>функции, но затем эта работа будет повторяться для всех программ, которые используют<foo
>. Лучшим решением является изменение<util/foo/Jamfile
>таким образом:
project : usage-requirements <include>. ; lib foo : foo.cpp ;
Требования к использованию применяются не к заявленной цели, а к ее иждивенцам. В этом случае<<include>.
>будет применяться ко всем целям, которые напрямую зависят от<foo
>.
Еще одним усовершенствованием является использование символьных идентификаторов для ссылки на библиотеку, в отличие от местоположения<Jamfile
>. В большом проекте библиотека может использоваться многими мишенями, и если все они используют<Jamfile
>местоположение, изменение организации каталогов влечет за собой большую работу. Решение заключается в использовании ids—символических имен, не привязанных к макету каталога. Во-первых, мы должны назначить идентификатор проекта, добавив этот код<Jamroot
>:
use-project /library-example/foo : util/foo ;
Во-вторых, мы модифицируем<app/Jamfile
>для использования идентификатора проекта:
exe app : app.cpp /library-example/foo//bar ;
Синтаксис</library-example/foo//bar
>используется для обозначения цели<bar
>в проекте с идентификатором<
/library-example/foo
>. Мы достигли нашей цели— если библиотека перенесена в другой каталог, только<Jamroot
>должен быть изменен. Обратите внимание, что идентификаторы проектов являются глобальными— двум Jamfiles не разрешается назначать один и тот же идентификатор проекта в разные каталоги.
![]() |
Tip |
---|---|
Если вы хотите, чтобы все приложения в каком-либо проекте ссылались на определенную библиотеку, вы можете избежать необходимости указывать непосредственно источники каждой цели, используя свойство< project : requirements <library>/boost/filesystem//fs ; |
Библиотеки могут быть либостатическими, что означает, что они включены в исполняемые файлы, которые их используют, илисовместно используемыми(а.к.а.динамическими), которые упоминаются только из исполняемых файлов и должны быть доступны во время выполнения. Повышаю. Построение может создавать и использовать оба вида.
Тип библиотеки, созданной из цели<lib
>, определяется значением функции<link
>. Значение по умолчанию составляет<shared
>, а для построения статической библиотеки значение должно быть<static
>. Вы можете запросить статическую сборку на командной строке:
b2 link=static
или в соответствии с требованиями библиотеки:
lib l : l.cpp : <link>static ;
Мы также можем использовать свойство<<link>
>для выражения требований к увязке на целевой основе. Например, если конкретный исполняемый файл может быть правильно построен только со статической версией библиотеки, мы можем квалифицировать целевую ссылкуисполняемого файлана библиотеку следующим образом:
exe important : main.cpp helpers/<link>static ;
Независимо от того, какие аргументы указаны в командной строкеb2,<important
>будет связан только со статической версией<helpers
>.
Определение свойств в целевых ссылках особенно полезно, если вы используете библиотеку, определенную в каком-либо другом проекте (который вы не можете изменить), но вы все равно хотите статическую (или динамическую) связь с этой библиотекой во всех случаях. Если эта библиотека используется многими целями, вымогли быиспользовать ссылки на цели везде:
exe e1 : e1.cpp /other_project//bar/<link>static ; exe e10 : e10.cpp /other_project//bar/<link>static ;
Но это далеко не удобно. Лучшим подходом является введение уровня косвенности. Создайте локальныйпсевдоним, который относится к статической (или динамической) версии<foo
>:
alias foo : /other_project//bar/<link>static ; exe e1 : e1.cpp foo ; exe e10 : e10.cpp foo ;
Правилопсевдонимаспециально используется для переименования ссылки на цель и, возможно, изменения свойств.
![]() |
Tip |
---|---|
Когда одна библиотека использует другую, вы помещаете вторую библиотеку в список источников первой. Например: lib utils : utils.cpp /boost/filesystem//fs ; lib core : core.cpp utils ; exe app : app.cpp core ; Это работает независимо от того, какие ссылки используются. Когда< |
![]() |
Note |
---|---|
(перенаправлено с «Unix System») Как правило, общие библиотеки должны быть установлены в каталог в пути поиска динамического линкера. В противном случае приложения, использующие общие библиотеки, не могут быть запущены. В Windows путь поиска динамического линкера определяется переменной среды< |
Иногда необходимо поддерживать определенные отношения между свойствами построения цели. Например, вы можете установить конкретный<
#define
>, когда библиотека построена как общая, или когда построен вариант<release
>цели. Этого можно добиться, используяусловные требования.
lib network : network.cpp : <link>shared:<define>NETWORK_LIB_SHARED <variant>release:<define>EXTRA_FAST ;
В приведенном выше примере, когда<network
>построен с<<link>shared
>,<<define>NETWORK_LIB_SHARED
>также будет в его свойствах. Кроме того, всякий раз, когда будет построен его вариант выпуска,<<define>EXTRA_FAST
>появится в его свойствах.
Иногда способы построения цели настолько различны, что описать их с помощью условных требований будет сложно. Например, представьте, что библиотека на самом деле использует различные исходные файлы в зависимости от набора инструментов, используемых для ее создания. Мы можем выразить эту ситуацию, используяцелевые альтернативы:
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
При строительстве<demangler
>. Build будет сравнивать требования к каждой альтернативе со свойствами сборки, чтобы найти лучшее соответствие. Например, когда будет выбрано здание с<<toolset>gcc
>альтернативой 2, и когда будет выбрано здание с<<toolset>msvc
>альтернативой 3. Во всех остальных случаях будет построена самая общая альтернатива 1.
Чтобы ссылаться на библиотеки, инструкции по сборке которых не даны в Jamfile, необходимо создать<lib
>цели с соответствующим<file
>свойством. Целевые альтернативы могут быть использованы для объединения нескольких библиотечных файлов с одной концептуальной целью. Например:
# util/lib2/Jamfile lib lib2 : : <file>lib2_release.a <variant>release ; lib lib2 : : <file>lib2_debug.a <variant>debug ;
В этом примере определены две альтернативы для<lib2
>, и для каждого имени предварительно построенный файл. Естественно, источников нет. Вместо этого для указания имени файла используется функция<<file>
>.
Как только предварительно построенная цель была объявлена, ее можно использовать так же, как и любую другую цель:
exe app : app.cpp ../util/lib2//lib2 ;
Как и в случае с любой мишенью, выбранная альтернатива зависит от свойств, распространяемых от иждивенцев<lib2
>. Если мы создадим релиз и отладку, версии<app
>будут связаны с<lib2_release.a
>и<lib2_debug.a
>соответственно.
Системные библиотеки & #8212; те, которые автоматически обнаруживаются набором инструментов путем поиска по некоторому набору заранее определенных путей & #8212; должны быть объявлены почти как обычные:
lib pythonlib : : <name>python22 ;
Мы снова не указываем никаких источников, но даем<name
>, который должен быть передан компилятору. Если набор инструментов gcc был использован для связи исполняемой цели с<pythonlib
>,<-lpython22
>появится в командной строке (другие компиляторы могут использовать разные опции).
Мы также можем указать, где набор инструментов должен искать библиотеку:
lib pythonlib : : <name>python22 <search>/opt/lib ;
И, конечно, целевые альтернативы можно использовать обычным способом:
lib pythonlib : : <name>python22 <variant>release ; lib pythonlib : : <name>python22_d <variant>debug ;
Более продвинутое использование предварительно построенных целей описано вразделе под названием “Цели в site-config.jam”.
<hello2
>Многие функции будут отменены, а не добавлены в подпроекты. См.раздел под названием & #8220; Атрибуты характеристик & #8221;для получения дополнительной информации
Статья Tutorial раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 45. Boost.Build User Manual может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Chapter 45. Boost.Build User Manual ::
реклама |