Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Language

Boost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 46. Boost.Jam : 3.1.19

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

B2 имеет интерпретируемый, процедурный язык. Заявления в b2 являются определениями правил (процедуры), вызовами правил, структурами потока управления, переменными назначениями и поддержкой различных языков.

B2 рассматривает свои входные файлы как токены, разделенные белым пространством, за двумя исключениями: двойные цитаты () могут включать белое пространство для встраивания его в токен, и все между соответствующими кудрявыми брекетами ({}) в определении действия правила рассматривается как одна строка. Задняя косая черта (\) может избежать двойной цитаты или любого одного символа белого пространства.

B2 требует, чтобы белое пространство (закладки, вкладки или новые линии) окружало все токены, включая токены двоеточия (:) и полуколона (;).

B2 ключевые слова (упомянутые в этом документе) зарезервированы и обычно должны быть процитированы с двойными котировками (), чтобы использоваться в качестве произвольных токенов, таких как переменные или целевые имена.

Комментарии начинаются с символа # и продолжаются до конца строки.

Существенный объект данных b2 является целью. Построение целей - это файлы, которые необходимо обновить. Целями источника являются файлы, используемые для обновления встроенных целей. Построенные цели и исходные цели в совокупности называются файловыми целями, а часто построенные цели являются исходными целями для других построенных целей. Псевдоцели — это символы, представляющие зависимости от других целей, но сами по себе не связанные с каким-либо реальным файлом.

Идентификатором целевого файла обычно является имя файла, которое может быть абсолютно укоренено относительно каталога вызова b2 или просто локально (без каталога). Чаще всего это последний случай, и фактический путь файла связан с использованием специальных переменных $(SEARCH) и $(LOCATE). См. Переменные поиска и размещения ниже. Локальное имя файла необязательно квалифицировано с помощью grist, значения строки, используемого для обеспечения уникальности. Целевой файл с идентификатором формы file(member) является членом библиотеки (обычно архив ar(1) на Unix).

Всякий раз, когда цель связана с местоположением в файловой системе, Boost Jam будет искать переменную под названием BINDRULE (сначала «на» цель связана, затем в глобальном модуле). Если не пусто, =$(BINDRULE[1])= именует правило, которое называется именем цели и пути, к которому оно привязано. Подпись правила, названного =$(BINDRULE[1])= должны соответствовать следующему:

rule bind-rule ( target : path )

Эта функция полезна для правильного сканирования файла заголовка, так как многие компиляторы будут искать файлы #include сначала в каталоге, содержащем файл, выполняющий директиву #include. $(BINDRULE) можно использовать для записи этого каталога.

Базовый объект языка b2 называется правилом. Правило определяется в двух частях: процедура и действия. Процедура представляет собой набор джемовых утверждений, которые должны выполняться при вызове правила; действия - это команды оболочки ОС, которые выполняются при обновлении встроенных целей правила.

Правила могут возвращать значения, которые могут быть расширены в список с «[правило аргии...]». Значение правила — это значение его последнего утверждения, хотя только следующие утверждения имеют значения: «если» (значение выбранной ноги), «переключатель» (значение выбранного случая), множество (значение полученной переменной) и «возврат» (значение его аргументов).

Заявления b2 для определения и вызова правил следующие:

Определите процедуру правила, заменив любое предыдущее определение.

rule rulename { statements }

Определите действия обновления правила, заменив любое предыдущее определение.

actions [ modifiers ] rulename { commands }

Назовите правило.

rulename field1 : field2 : ... : fieldN ;

Примените правило под влиянием конкретных переменных цели.

on target rulename field1 : field2 : ... : fieldN ;

Используемый в качестве аргумента, расширяется до обратной стоимости применяемого правила.

[ rulename field1 : field2 : ... : fieldN ]
[ on target rulename field1 : field2 : ... : fieldN ]

Правило вызывается значениями в field1 через fieldN. Они могут упоминаться в заявлениях процедуры как $(1) через $(N) (9 max), и только первые два могут упоминаться в действиях команд как $(1) и $(2). $(<) и $(>) являются синонимами $(1) и $(2).

Правила делятся на две категории: правила обновления (с действиями) и правила чистой процедуры (без действий). Обновленные правила рассматривают аргументы $(1) и $(2) как встроенные цели и источники, соответственно, в то время как чистые правила процедуры могут принимать произвольные аргументы.

Когда используется правило обновления, его действия по обновлению добавляются к действиям, связанным с построенными целями ($(1)) до запуска процедуры правила. Позже, для построения целей на этапе обновления, команды передаются в командную оболочку ОС, при этом $(1) и $(2) заменяются связанными версиями имен целей. См. Обязательство выше.

Вызов правил может быть опосредован через переменную:

$(var) field1 : field2 : ... : fieldN ;
on target $(var) field1 : field2 : ... : fieldN ;
[ $(var) field1 : field2 : ... : fieldN ]
[ on target $(var) field1 : field2 : ... : fieldN ]

Значение переменной обозначает правило (или правила), на которое следует ссылаться. Для каждого элемента в списке значений $(var) используется правило. Поля field1 : field2 : ... принимаются в качестве аргументов для каждой инвокации. Для форм [...] возвращаемое значение представляет собой сцепление возвращаемых значений для всех вызовов.

Поняты следующие модификаторы действий:

actions bind vars

$(vars) будет заменен на связанные значения.

actions existing

$(>) включает только исходные цели, существующие в настоящее время.

actions ignore

Статус возврата команд игнорируется.

actions piecemeal

команды многократно вызываются с подмножеством $(>), достаточно маленьким, чтобы вписаться в буфер команд на этой ОС.

actions quietly

Действие не перекликается со стандартным выходом.

actions together

$(>) от множественных вызовов одного и того же действия на одну и ту же построенную цель.

actions updated

$(>) включает в себя только сами цели источника, отмеченные для обновления.

Вы можете описать аргументы, принятые правилом, и обратиться к ним по имени в рамках правила. Например, следующие принты «Прости, Дэйв» к консоли:

rule report ( pronoun index ? : state : names + )
{
    local he.suffix she.suffix it.suffix = s ;
    local I.suffix = m ;
    local they.suffix you.suffix = re ;
    ECHO $(pronoun)'$($(pronoun).suffix) $(state), $(names[$(index)]) ;
}
report I 2 : sorry : Joe Dave Pete ;

Каждое имя в списке формальных аргументов (разделенное на «:» в объявлении правила) связано с одним элементом соответствующего фактического аргумента, если за ним не следует один из этих модификаторов:

Символ

Семантика предшествующего символа

необязательно

Привязывается к нулю или более несвязанным элементам фактического аргумента. При появлении *, где ожидается название аргумента, принимается любое количество дополнительных аргументов. Эта функция может использоваться для реализации правил «варагов».

+

Привязан к одному или нескольким несвязанным элементам фактического аргумента.

Фактические и формальные аргументы проверяются на несоответствия, которые приводят к выходу b2 с кодом ошибки:

### argument error
# rule report ( pronoun index ?  : state  : names + )
# called with: ( I 2 foo  : sorry  : Joe Dave Pete )
# extra argument foo
### argument error
# rule report ( pronoun index ?  : state  : names + )
# called with: ( I 2  : sorry )
# missing argument names

Если вы опустите список формальных аргументов, вся проверка будет обойдена, как в «классическом» Jam. Однако списки аргументов значительно улучшают надежность и читаемость ваших правил и настоятельно рекомендуются для любого нового кода Jam, который вы пишете.

B2 имеет растущий набор встроенных правил, все из которых являются чистыми правилами процедуры без обновления действий. Они делятся на три группы: первая создает график зависимости, вторая изменяет его, а третья — просто правила полезности.

rule DEPENDS ( targets1 * : targets2 * )

Построена прямая зависимость: каждая из мишеней1 зависит от каждой из мишеней2. Как правило, цели1 будут перестроены, если цели2 сами перестроены или являются более новыми, чем цели1.

rule INCLUDES ( targets1 * : targets2 * )

Построение зависимости между братьями и сестрами: делает любую цель, которая зависит от любой из мишеней1, также зависимой от каждой из мишеней2. Это отражает зависимости, которые возникают, когда один исходный файл включает в себя другой: объект, построенный из исходного файла, зависит как от исходного, так и от включенного исходного файла, но два исходных файла не зависят друг от друга. Например:

DEPENDS foo.o : foo.c ;
INCLUDES foo.c : foo.h ;

"foo.o" зависит от "foo.c" и "foo.h" в этом примере.

Правила Всегда LEAVES, NOCARE, NOTFILE, NOUPDATE и TEMPORARY модифицируют график зависимостей таким образом, что b2 по-разному обрабатывает цели во время фазы связывания с целью. См. Обязательство выше. Обычно b2 обновляет цель, если она отсутствует, если время ее модификации файловой системы старше, чем у любой из ее зависимостей (рекурсивно), или если какая-либо из ее зависимостей обновляется. Это основное поведение может быть изменено с помощью следующих правил:

rule ALWAYS ( targets * )

Причины цели должны быть восстановлены независимо от того, являются ли они современными (они все еще должны быть в графе зависимостей). Это используется для чистых и неустановленных целей, поскольку они не имеют зависимостей и в противном случае, по-видимому, никогда не нуждаются в строительстве. Он лучше всего применяется к целям, которые также являются целями NOTFILE, но также может использоваться для обновления реального файла.

rule LEAVES ( targets * )

Делает каждую из мишеней зависящей только от ее листовых источников, а не от каких-либо промежуточных целей. Это делает его невосприимчивым к обновлению зависимостей, поскольку «листовые» зависимости — это те, которые не имеют собственных зависимостей и не обновляют действия. Это позволяет обновлять цель только при изменении исходных файлов.

rule NOCARE ( targets * )

Причин b2 игнорировать цели , которые не могут быть найдены и не имеют обновлений действий для их построения. Обычно для таких целей b2 выдает предупреждение, а затем пропускает другие цели, которые зависят от этих недостающих целей. HdrRule в Jambase использует NOCARE на именах файлов заголовка, найденных во время сканирования файлов заголовка, чтобы дать b2 знать, что включенные файлы могут не существовать. Например, если #include находится в пределах #ifdef, включенный файл может фактически не находиться вокруг.

[Warning] Warning

Для целей с действиями построения: если их действия построения выходят с ненулевым кодом возврата, зависимые цели все равно будут построены.

rule NOTFILE ( targets * )

Отметки targets как псевдоцели, а не реальные файлы. Временная метка не проверяется, и поэтому действия по такой цели выполняются только при обновлении зависимостей цели или если цель также отмечена ВСЕГДА. По умолчанию b2 цель « все » является псевдоцелью. В Jambase NOTFILE используется для определения нескольких дополнительных удобных псевдоцелей.

rule NOUPDATE ( targets * )

Вызывает игнорирование временных меток на -мишенях. Это имеет два эффекта: во-первых, после создания цели она никогда не будет обновляться; во-вторых, ручное обновление цели не приведет к обновлению других целей. Например, в Jambase это правило применяется к каталогам по правилу MkDir, потому что MkDir заботится только о том, что целевой каталог существует, а не когда он последний раз обновлялся.

rule TEMPORARY ( targets * )

Марки -мишени - временные, позволяющие удалять их после обновления других целей, зависящих от них. Если отсутствует цель TEMPORARY, b2 использует временную метку родителя цели. Jambase использует TEMPORARY для маркировки объектных файлов, которые архивируются в библиотеке после их создания, так что они могут быть удалены после их архивирования.

rule FAIL_EXPECTED ( targets * )

Для обработки целей, действия по сборке которых, как ожидается, не сработают (например, при правильном тестировании этих утверждений или проверке типа компиляции), Boost Jam предоставляет правило FAIL_EXPECTED в том же стиле, что и NOCARE, и т. д. Во время обновления цели обратный код действий по сборке для аргументов FAIL_EXPECTED перевернут: если он не сработает, построение зависимых целей продолжается так, как если бы он преуспел. Если это удастся, зависимые цели будут пропущены.

rule RMOLD ( targets * )

B2 удаляет любые целевые файлы, которые могут существовать на диске, когда правило, используемое для построения этих целей, выходит из строя. Однако цели, чьи зависимости не могут быть построены, не удаляются по умолчанию. Правило RMOLD приводит к тому, что его аргументы удаляются, если какая-либо из их зависимостей не может быть построена.

rule ISFILE ( targets * )

ISFILE обозначает цели, необходимые для файлов. Это меняет способ поиска цели b2 таким образом, что он игнорирует совпадения для элементов файловой системы, которые не являются файлами, такими как каталоги. Это позволяет избежать совпадения #include "исключение", если в пути поиска заголовка имеется каталог с именем исключения.

[Warning] Warning

В настоящее время это не полностью реализовано.

Два правила ECHO и EXIT являются правилами полезности, используемыми только в фазе разбора b2.

rule ECHO ( args * )

Отключает сообщение args в stdout.

rule EXIT ( message * : result-value ? )

Выключает сообщение , а затем выходит со статусом отказа, если не дано значение результата, в противном случае оно выходит с заданным значение результата.

"Echo", "echo", "Exit" и "exit" принимаются в качестве псевдонимов для ECHO и EXIT, поскольку трудно сказать, что это встроенные правила, а не часть языка, как "include".

Правило GLOB глобулирует имя файла.

rule GLOB ( directories * : patterns * : downcase-opt ? )

Использование тех же карточек, что и для шаблонов в заявлении переключателя. Он используется в качестве аргумента для вызова правила внутри «=[]=». Например: "FILES = [GLOB dir1 dir2 : *.c *.h ]" устанавливает FILES в список файлов источника C и заголовков в dir1 и dir2. Полученные имена файлов являются полными именами путей, включая каталог, но шаблон применяется только к имени файла без каталога.

Если предоставляется downcase-opt, имена файлов преобразуются во все нижние регистры перед сопоставлением с шаблоном; вы можете использовать это для выполнения бесчувственного сопоставления с использованием шаблонов нижних регистров. Возвращенные пути все равно будут иметь смешанный случай, если ОС их поставит. В Windows NT, Cygwin и OpenVMS имена файлов всегда уменьшаются перед сопоставлением.

Правило GLOB_ARCHIVE позволяет называть имена членов архива объектов.

rule GLOB_ARCHIVE ( archives * : member-patterns * : downcase-opt ? : symbol-patterns ? )

Подобно GLOB, это правило используется для сопоставления имен файлов-членов в архиве (библиотека статических объектов). Список успешно подобранных членов возвращается или не возвращается. Полученные имена участников квалифицируются с именем пути содержащего архива в виде archive-path(member-name). Узоры участников предназначены только для сопоставления имени участника; когда не указаны дикие карты - предполагается точное совпадение. Имена членов, как правило, соответствуют именам файлов объектов и, как таковые, являются специфичными для платформы - использование суффикса объекта, определенного платформой, в соответствующих шаблонах может обеспечить переносимость.

Если предоставляется downcase-opt, имена участников преобразуются во все нижние регистры перед сопоставлением с шаблоном; вы можете использовать это для выполнения нечувствительного к регистру сопоставления с использованием шаблонов нижних регистров. Возвращенные пути все равно будут иметь смешанный случай, если ОС их поставит. В Windows NT, Cygwin и OpenVMS имена файлов всегда понижаются перед сопоставлением.

Кроме того, участники могут быть сопоставлены с шаблонами символов / функций на поддерживаемых платформах (в настоящее время только OpenVMS). В этом случае члены, содержащие соответствующие символы, возвращаются. Узоры символов и символов применяются в качестве условий ИЛИ, причем шаблоны членов имеют приоритет. На неподдерживаемых платформах нуль возвращается, когда указаны какие-либо шаблоны символов.

Правило MATCH соответствует шаблону.

rule MATCH ( regexps + : list * )

Соответствует регулярным выражениям в стиле egrep(1) regexps против строк в list. Результатом является список соответствия () подвыражений для каждой строки в списке и для каждого регулярного выражения в regexps.

rule BACKTRACE ( )

Возвращает список четверных: filenamelinemodulerulename..., описывающий каждый более мелкий уровень стека вызовов. Это правило может использоваться для генерации полезных диагностических сообщений из правил Jam.

rule UPDATE ( targets * )

Классический джем рассматривает любой невариантный элемент командной строки как имя цели, которая должна быть обновлена. Это предотвратило более сложную обработку командной строки. Теперь это снова включено, но с дополнительными изменениями в правиле UPDATE, чтобы обеспечить гибкость изменения списка целей для обновления. Правило UPDATE имеет два эффекта:

  1. Он очищает список целей для обновления и
  2. Вызывает необходимость обновления указанных целей.

Если цель не была указана в правиле UPDATE, никакие цели не будут обновлены. Чтобы поддержать изменение списка обновлений более полезными способами, правило также возвращает цели, ранее включенные в список обновлений. Это позволяет добавлять цели как таковые:

local previous-updates = [ UPDATE ] ;
UPDATE $(previous-updates) a-new-target ;
rule W32_GETREG ( path : data ? )

Это касается только платформы Win32. Он читает реестр Windows. path - это местоположение информации, а data - это имя значения, которое мы хотим получить. Если опущены data, возвращается значение по умолчанию path. Значение path должно соответствовать формату пути ключа MS и должно быть прикреплено к одному из предопределенных корневых ключей. Как обычно,

  • HKLM эквивалентно HKEY_LOCAL_MACHINE.
  • HKCU эквивалентно HKEY_CURRENT_USER.
  • HKCR эквивалентно HKEY_CLASSES_ROOT.

Другие предопределенные корневые ключи не поддерживаются.

Поддерживаемые типы данных: REG_DWORD, REG_SZ, REG_EXPAND_SZ, REG_MULTI_SZ. Данные с помощью REG_DWORD Тип будет превращен в строку, 'REG_MULTI_SZ' в список строк, а для тех, у кого в нем переменные среды типа REG_EXPAND_SZ, будут заменены их заданными значениями. Данные с типом REG_SZ и другими неподдерживаемыми типами будут помещаться в строку без изменения. Если он не может получить значение данных, он просто возвращает пустой список. Например,

local PSDK-location =
  [ W32_GETREG HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MicrosoftSDK\\Directories : "Install Dir" ] ;
rule W32_GETREGNAMES ( path : result-type )

Это касается только платформы Win32. Он читает реестр Windows. "path" - это местоположение информации, а "тип результата" - это либо "subkeys", либо "values". Для получения дополнительной информации о формате и ограничениях path см. W32_GETREG.

В зависимости от типа результата , правило возвращает одно из следующих:

subkeys

Названия всех прямых подкатегорий path.

values

Названия значений, содержащихся в регистровом ключе, приведенные в path. Значение «по умолчанию» ключа появляется в возвращенном списке только в том случае, если его значение было установлено в реестре.

Если «тип результата » не распознан или запрошенные данные не могут быть извлечены, правило возвращает пустой список. Пример:

local key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths" ;
local subkeys = [ W32_GETREGNAMES "$(key)" : subkeys ] ;
for local subkey in $(subkeys)
{
    local values = [ W32_GETREGNAMES "$(key)\\$(subkey)" : values ] ;
    for local value in $(values)
    {
        local data = [ W32_GETREG "$(key)\\$(subkey)" : "$(value)" ] ;
        ECHO "Registry path: " $(key)\\$(subkey) ":" $(value) "=" $(data) ;
    }
}
rule SHELL ( command : * )

SHELL выполняет команду, а затем возвращает стандартный вывод команду. SHELL работает только на платформах с функцией popen() в библиотеке C. На платформах без рабочей функции popen() SHELL реализуется как no-op. SHELL работает на Unix, MacOS X и большинстве компиляторов Windows. SHELL - это no-op на компиляторах Metrowerks под Windows. Существует переменный набор допустимых вариантов в качестве дополнительных аргументов:

exit-status

Помимо вывода, в качестве второго элемента результата возвращается статус результата исполняемой команды.

no-output

Не захватывайте выход команды. Вместо вывода возвращается пустое («») значение строки.

strip-eol

Удалить следящий конечный символ из вывода, если таковой имеется.

Поскольку Perforce/Jambase определяет правило SHELL, которое скрывает встроенное правило, COMMAND может использоваться в качестве псевдонима для SHELL в таком случае.

rule MD5 ( string )

MD5 вычисляет хэш MD5 строки, пропущенной в качестве параматера, и возвращает его.

rule SPLIT_BY_CHARACTERS ( string : delimiters )

SPLIT_BY_CHARACTERS разделяет указанную строку на любой символ делимитера, присутствующий в delimiters, и возвращает полученный список.

rule PRECIOUS ( targets * )

Правило PRECIOUS указывает, что каждая из целей, переданных в качестве аргументов, не должна быть удалена, даже если команда обновления этой цели не удается.

rule PAD ( string : width )

Если строка короче, чем ширина символов, поместите ее с символами белого пространства справа и верните результат. В противном случае возвращается строка неизмененная.

rule FILE_OPEN ( filename : mode )

Правило FILE_OPEN открывает указанный файл и возвращает дескриптор файла. Параметр mode может быть либо «w», либо «r». Обратите внимание, что в настоящее время только правило UPDATE_NOW может использовать полученный номер дескриптора файла.

rule UPDATE_NOW ( targets * : log ? : ignore-minus-n ? )

UPDATE_NOW немедленно обновил указанные цели. Если обновление было успешным, возвращается непустая строка. Параметр log, если он присутствует, указывает дескриптор файла, в котором весь вывод из здания перенаправляется. Если параметр ignore-minus-n задан, цели обновляются, даже если параметр -n задан в командной строке.

B2 имеет несколько простых выражений потока управления:

for var in list { statements }

Выполняет заявления для каждого элемента в списке, устанавливая переменную var на значение элемента.

if cond { statements }
[ else { statements } ]

Делает очевидное; оговорка else необязательна. cond построен из:

a

истинно, если любой элемент a является строкой ненулевой длины

a = b

список a список совпадений b строка-в-струну

a != b

список a не соответствует списку b

a < b

a[i] строка меньше b[i] строка, где i первый несоответствующий элемент в списках a и b

a <= b

каждая строка a меньше или равна своему аналогу b

a > b

a[i] строка больше, чем b[i] строка, где i первый несоответствующий элемент

a >= b

каждая строка a больше или равна своему аналогу b

a in b

истинно, если все элементы a можно найти в b, или если a не имеет элементов

! cond

условие не верно

cond && cond

соединение

cond || cond

разделение

( cond )

группа приоритетов

include file ;

Причин b2 читать названный файл. файл связан как обычная цель (см. Обязательство выше), но в отличие от обычной цели, включающий файл не может быть построен.

Включающий файл вставляется во входной поток во время фазы разбора. Основной входной файл и все включенные файлы рассматриваются как один файл; то есть b2 не определяет границ объема из включенных файлов.

local vars [ = values ] ;

Создает новый vars внутри блока {}, заслоняя любые предыдущие значения, которые они могут иметь. Предыдущие значения для vars восстанавливаются, когда текущий блок заканчивается. Любое правило, называемое или включенный файл, будет отображать локальное, а не предыдущее значение (иногда его называют динамическим сканированием). Локальное утверждение может появиться в любом месте, даже за пределами блока (в этом случае предыдущее значение восстанавливается, когда вход заканчивается). vars инициализируются до значений , если они присутствуют, или остаются неинициализированными в противном случае.

return values ;

В органе правил заявление о возврате устанавливает значение возврата для вызова правила и возвращается абоненту.

switch value
{
    case pattern1 : statements ;
    case pattern2 : statements ;
    ...
}

Высказывание переключателя выполняет ноль или одно из прилагаемых заявлений, в зависимости от того, какой, если таковой имеется, является первым случаем, чей паттерн соответствует значению. Значения паттерна не являются переменными. Значения шаблона могут включать следующие wildcards:

?

соответствует любому отдельному персонажу

*

сопоставить ноль или больше персонажей

[chars]

сопоставить любой один символ в chars

[^chars]

сопоставить любой один символ в chars

\x

матч x (ускользает от других карточек)

while cond { statements }

Неоднократно выполнять заявления, в то время как cond остается верным при вводе. (См. описание синтаксиса выражения cond ниже, если, выше).

break ;

Немедленно выходит из ближайшего окружения во время или для петли.

continue ;

Подпрыгивает к верхней части ближайшего окружения во время или для петли.

Переменные B2 представляют собой списки нулевых или более элементов, причем каждый элемент является значением строки. Неопределенная переменная неотличима от переменной с пустым списком, однако определенная переменная может иметь еще один элемент, который является нулевой строкой. Все переменные называются $( вариабельными).

Переменные являются глобальными или целевыми. В последнем случае переменная принимает заданное значение только при обновлении конкретной цели.

Переменная определяется с:

variable = elements ;
variable += elements ;
variable on targets = elements ;
variable on targets += elements ;
variable default = elements ;
variable ?= elements ;

Первые две формы устанавливаются по всему миру variable. Третья и четвертая формы устанавливают целевую переменную. Оператор = заменяет любые предыдущие элементы вариабельного с элементами ; операция += добавляет элементы к вариабельному списку элементов. Заключительные две формы являются синонимами: они устанавливают переменный глобально, но только если он был ранее не установлен.

Переменные, на которые ссылаются при обновлении команд, будут заменены их значениями; целевые значения имеют приоритет над глобальными значениями. Переменные, передаваемые в качестве аргументов ($(1) и $(2)) к действиям, заменяются их связанными значениями; модификатор bind может использоваться для действий, чтобы заставить другие переменные заменяться связанными значениями. Смотрите модификаторы действий выше.

Переменные B2 не реэкспортируются в среду оболочки, которая выполняет действия обновления, но действия обновления могут ссылаться на переменные b2 с $(переменная).

При разборе b2 выполняет расширение переменной на каждом токене, который не является ключевым словом или именем правила. Такие токены со встроенными переменными ссылками заменяются нулевыми или более токенами. Переменные ссылки имеют форму $(v) или $(vm), где v является переменным именем, а m являются необязательными модификаторами.

Переменное расширение в действиях правила похоже на переменное расширение в утверждениях, за исключением того, что строка действия токенизируется в белом пространстве независимо от цитирования.

Результатом токена после расширения переменной является продукт компонентов токена, где каждый компонент представляет собой буквальную подстроку или список, заменяющий переменную ссылку. Например:

$(X) -> a b c
t$(X) -> ta tb tc
$(X)z -> az bz cz
$(X)-$(X) -> a-a a-b a-c b-a b-b b-c c-a c-b c-c

Вариабельное имя и модификаторы могут сами содержать переменную ссылку, и это также относится к продукту:

$(X) -> a b c
$(Y) -> 1 2
$(Z) -> X Y
$($(Z)) -> a b c 1 2

Из-за этого расширения продукта, если какая-либо переменная ссылка в токене не определена, результатом расширения является пустой список. Если любой переменный элемент представляет собой нулевую строку, то результат распространяется на ненулевые элементы:

$(X) -> a ""
$(Y) -> "" 1
$(Z) ->
-$(X)$(Y)- -> -a- -a1- -- -1-
-$(X)$(Z)- ->

Значение строк переменного элемента можно разобрать на гранитные и связанные с именем файла компоненты. Модификаторы переменной используются для выбора элементов, выбора компонентов и замены компонентов. Модификаторами являются:

[n]

Выберите номер элемента n (начиная с 1). Если переменная содержит меньше элементов n, результатом является список нулевых элементов. n может быть отрицательным, в этом случае возвращается число элемента n от последнего левого направления.

[n-m]

Выберите элементы с номером n до m. n и m могут быть отрицательными, в этом случае они относятся к элементам, считающимся с последнего левого направления.

[n-]

Выберите число элементов n до последнего. n может быть отрицательным, в этом случае он относится к подсчету элементов с последнего левого направления.

:B

Выберите базу имен файлов.

:S

Выберите (последний) суффикс имени файла.

:M

Выберите имя члена архива.

:D

Выберите путь каталога.

:P

Выберите родительский каталог.

:G

Выберите Грист.

:U

Заменить строчные символы на верхние.

:L

Заменить верхние символы строчными.

:T

Преобразует все задние слэши («\») в передние слэши («/»). Например

x = "C:\\Program Files\\Borland" ; ECHO $(x:T) ;

"C:/Program Files/Borland"

:W

При вызове Windows-инструментов из Cygwin может быть важно передать им истинные пути в стиле окон. Модификатор :W, под Cygwin только , превращает путь цикла в путь Win32 с помощью функции cygwin_conv_to_win32_path. Например

x = "/cygdrive/c/Program Files/Borland" ; ECHO $(x:W) ;

печать "C:\Program Files\Borland" на Cygwin

Аналогично, при использовании на OpenVMS модификатор :W переводит путь в стиле POSIX в нативный формат в стиле VMS с использованием decc$to_vms Функция CRTL. Этот модификатор обычно используется внутри блоков действий для правильного указания путей файлов в командах VMS. Например

x = "subdir/filename.c" ; ECHO $(x:W) ;

prints "[.subdir]filename.c" на OpenVMS

На других платформах строка неизменна.

:chars

Выберите компоненты, перечисленные в chars.

:G=grist

Заменить grist на grist.

:D=path

Заменить каталог path.

:B=base

Заменить основную часть имени файла base.

:S=suf

Заменить суффикс имени файла suf.

:M=mem

Заменить имя члена архива mem.

:R=root

Приготовьте root ко всему имени файла, если оно еще не укоренено.

:E=value

Назначить значение переменной, если она не установлена.

:J=joinval

Сопоставьте элементы списка в один элемент, разделенный joinval.

В VMS $(var:P) является родительским каталогом $(var:D).

Boost Jam позволяет объявить локальную переменную для управления циклом прямо в цикле:

x = 1 2 3 ;
y = 4 5 6 ;
for local y in $(x)
{
    ECHO $(y) ; # prints "1", "2", or "3"
}
ECHO $(y) ;     # prints "4 5 6"

Во время расширения выражений b2 также ищет подэкспрессии формы @(имя файла:E=filecontents) и заменяет выражение filename после создания данного файла с содержанием, установленным на filecontents. Это полезно для создания файлов ответа компилятора и других «внутренних» файлов. Расширение работает как при разборе, так и при выполнении действий. Таким образом, можно создавать файлы на любом из трех этапов сборки.

В этом разделе рассматриваются переменные, имеющие особое значение b2. Все они должны быть определены или использованы в глобальном модуле - использование этих переменных внутри названного модуля не будет иметь желаемого эффекта. См. Модули .

Эти две переменные контролируют связывание целевых имен файлов с местоположениями в файловой системе. Как правило, $(SEARCH) используется для поиска существующих источников, в то время как $(LOCATE) используется для фиксации местоположения для построенных целей.

Корневые (абсолютный путь) файловые цели связаны как есть. Некорневые целевые имена файлов также обычно связаны как есть и, таким образом, относительно текущего каталога, но настройки $(LOCATE) и $(SEARCH) изменяют это:

  • Если установлен $(LOCATE), то цель связана с первым каталогом в $(LOCATE). Для связывания используется только первый элемент.
  • Если установлен $(SEARCH), то цель связана с первым каталогом в $(SEARCH), где целевой файл уже существует.
  • Если поиск $(SEARCH) терпит неудачу, цель в любом случае связана с текущим каталогом.

Как $(SEARCH), так и $(LOCATE) должны быть ориентированы на конкретные цели, а не глобально. Если бы они были установлены глобально, b2 использовал бы одни и те же пути для всех связываний файлов, что вряд ли приведет к нормальным результатам. При написании собственных правил, особенно тех, которые не построены на тех, которые находятся в Jambase, вам может потребоваться установить $(SEARCH) или $(LOCATE) напрямую. Почти все правила, определенные в наборе Jambase $(SEARCH) и $(LOCATE), соответствуют разумным значениям для источников, которые они ищут, и целей, которые они создают, соответственно.

Эти две переменные контролируют сканирование файла заголовка. $(HDRSCAN) - это шаблон egrep(1), с () именем файла, используемым для поиска заявлений о включении файла в исходные файлы. Jambase использует $(HDRPATTERN) в качестве шаблона для $(HDRSCAN). $(HDRRULE) - это название правила, которое нужно вызвать с результатами сканирования: отсканированный файл - цель, найденные файлы - источники. Это единственное место, где b2 вызывает правило через переменную настройку.

Оба $(HDRSCAN) и $(HDRRULE) должны быть установлены для сканирования файла заголовка, и они должны быть установлены для конкретной цели, а не глобально. Если бы они были установлены глобально, все файлы, включая исполняемые файлы и библиотеки, были бы отсканированы для файла заголовка.

Сканирование включения файла заголовка не является точным, но оно по крайней мере динамическое, поэтому нет необходимости запускать что-то вроде makedepend (GNU) для создания статического файла зависимости. Механизм сканирования ошибается на стороне включения (т.е. он с большей вероятностью возвращает имена файлов, которые на самом деле не используются компилятором, чем пропускает файлы), потому что он не может сказать, находятся ли строки #включают внутри #ifdefs или другой условной логики. В Jambase HdrRule применяет правило NOCARE к каждому файлу заголовка, найденному во время сканирования, так что, если файл еще не присутствует, компиляция не выйдет из строя, b2 не будет иметь значения.

Кроме того, сканирование для регулярных выражений работает только там, где включенное имя файла буквально находится в исходном файле. Он не может обрабатывать языки, которые позволяют включать файлы с использованием переменных имен (как это делает сам язык Jam).

Иногда желательно запретить параллельное выполнение некоторых действий. Например:

  • Старые версии yacc используют файлы с фиксированными именами. Таким образом, выполнение двух действий ЯКК опасно.
  • Можно выполнять параллельное компиляцию, но не делать параллельное связывание, потому что связывание связано и только замедляется.

Крейг МакПитерс расширил Perforce Jam для решения таких проблем, и это расширение было интегрировано в Boost. Джем.

Любая цель может быть назначена семафором , путем установки переменной под названием SEMAPHORE на эту цель. Значение переменной — имя семафора. Оно должно отличаться от наименований любой заявленной цели, но произвольно в противном случае.

Семантика семафоров заключается в том, что в группе целей, имеющих один и тот же семафор, в данный момент может обновляться только один, независимо от опции «-j».

Ряд встроенных переменных Jam можно использовать для идентификации платформы среды выполнения:

OS

Строка идентификатора OS

OSPLAT

Основная архитектура, если применимо

MAC

правда на платформе MAC

NT

правда на платформе NT

OS2

правда на платформе OS2

UNIX

правда на платформах Unix

VMS

правда на платформе VMS

JAMDATE

Время и дата запуска b2 в качестве значения ISO-8601 UTC.

JAMUNAME

Ouput команды uname(1) (только для Unix)

JAMVERSION

b2 версия, в настоящее время "3.1.19"

JAM_VERSION

Предопределенная глобальная переменная с двумя элементами указывает номер версии Boost Jam. Версии Boost Jam начинаются с «03» «00». Более ранние версии Jam автоматически не определяют JAM_VERSION.

Когда b2 выполняет блок действия правила, он разветвляет и выполняет оболочку, передавая блок действия в качестве аргумента оболке. Вызыв оболочки можно контролировать с помощью $(JAMSHELL). По умолчанию в Unix, например:

JAMSHELL = /bin/sh -c % ;

% заменяется текстом блока действий.

B2 напрямую не поддерживает строительство параллельно на нескольких хостах, поскольку это сильно зависит от местной среды. Чтобы построить параллельно несколько хостов, вам нужно написать свою собственную оболочку, которая обеспечивает доступ к нескольким хостам. Затем вы сбрасываете $(JAMSHELL), чтобы ссылаться на него.

Точно так же, как b2 расширяет %, чтобы быть текстом блока действий правила, он расширяет !, чтобы быть числом слота для нескольких процессов. Количество слотов варьируется от 1 до количества одновременных заданий, разрешенных флагом -j в командной строке. Вооружившись этим, можно написать несколько оболочек хоста. Например:

#!/bin/sh
# This sample JAMSHELL uses the SunOS on(1) command to execute a
# command string with an identical environment on another host.
# Set JAMSHELL = jamshell ! %
#
# where jamshell is the name of this shell file.
#
# This version handles up to -j6; after that they get executed
# locally.
case $1 in
1|4) on winken sh -c "$2";;
2|5) on blinken sh -c "$2";;
3|6) on nod sh -c "$2";;
*) eval "$2";;
esac

__TIMING_RULE__ и _ACTION_RULE__ может быть установлено на имя правила для b2 вызова после действия, завершающегося для цели. Они оба дают диагностическую информацию о завершившемся действии. Для __TIMING_RULE__ правило называется:

rule timing-rule ( args * : target : start end user system )

И __ACTION_RULE___ называется:

rule action-rule ( args * : target : command status start end user system : output ? )

Аргументы в пользу обоих:

args

Любые значения, следующие за именем правила в _TIMING_RULE__ или _ACTION_RULE__, передаются здесь.

target

Создана цель b2.

command

Текст выполненной команды в органе действия.

status

Целый результат выполненной команды.

start

Стартовая временная метка исполняемой команды как значение ISO-8601 UTC.

end

Временная метка завершения выполненной команды как значение ISO-8601 UTC.

user

Количество секунд процессора пользователя выполненная команда провела как значение плавающей точки.

system

Количество секунд процессора системы исполняемая команда проводила как значение плавающей точки.

output

Выход команды как единая строка. Содержание вывода отражает использование опции -pX.

[Note] Note

Если обе переменные установлены для цели, то сначала __TIMING_RULE__, затем _ACTION_RULE__.

Boost Jam представляет поддержку модулей, которые обеспечивают некоторую элементарную защиту пространства имен для правил и переменных. Также было введено новое ключевое слово «модуль». Функции, описанные в этом разделе, являются примитивными, что означает, что они предназначены для обеспечения операций, необходимых для написания правил Jam, которые обеспечивают более элегантный интерфейс модуля.

module expression { ... }

Код в {...} выполняется в модуле, названном путем оценки выражения. Определения правил можно найти в собственном пространстве имен модуля, а в пространстве имен глобального модуля как имя модуля . имя правила , поэтому в модуле другие правила в этом модуле всегда могут использоваться без квалификации:

module my_module
{
    rule salute ( x ) { ECHO $(x), world ; }
    rule greet ( ) { salute hello ; }
    greet ;
}
my_module.salute goodbye ;

Когда вызываемое правило не найдено в пространстве имен текущего модуля, оно просматривается в пространстве имен глобального модуля, поэтому квалифицированные вызовы работают в разных модулях:

module your_module
{
    rule bedtime ( ) { my_module.salute goodnight ; }
}

Каждый модуль имеет свой собственный набор динамически вложенных переменных областей. Когда выполнение переходит от модуля А к модулю В, все переменные связывания из А становятся недоступными и заменяются связываниями, которые принадлежат В. Это в равной степени относится к локальным и глобальным переменным:

module A
{
    x = 1 ;
    rule f ( )
    {
        local y = 999 ; # becomes visible again when B.f calls A.g
        B.f ;
    }
    rule g ( )
    {
        ECHO $(y) ;     # prints "999"
    }
}
module B
{
    y = 2 ;
    rule f ( )
    {
        ECHO $(y) ; # always prints "2"
        A.g ;
    }
}

Единственный способ получить доступ к переменным другого модуля - это ввести этот модуль:

rule peek ( module-name ? : variables + )
{
    module $(module-name)
    {
        return $($(>)) ;
    }
}

Обратите внимание, что поскольку существующие переменные привязки изменяются всякий раз, когда вводится новый объем модуля, привязки аргументов становятся недоступными. Это объясняет использование «$(>)» в правиле пика выше.

local rule rulename...

Правило объявляется локально текущему модулю. Он не вводится в глобальный модуль с квалификацией, а его название не появится в результате:

[ RULENAMES module-name ]
rule RULENAMES ( module ? )

Возвращает список имен всех нелокальных правил в данном модуле. Если модуль опущен, имена всех нелокальных правил в глобальном модуле возвращаются.

rule VARNAMES ( module ? )

Возвращает список имен всех переменных связываний в данном модуле. Если модуль опущен, имена всех переменных связываний в глобальном модуле возвращаются.

[Note] Note

Это включает в себя любые локальные переменные в правилах из стека вызовов, которые не вернулись во время вызова VARNAMES.

IMPORT позволяет использовать псевдонимы правил в разных модулях:

rule IMPORT ( source_module ? : source_rules *
            : target_module ? : target_rules * )

Правило IMPORT копирует правила source_module в target_module в виде локальных правил. Если source_module или target_module не поставляется, это относится к глобальному модулю. source_rules указывает, какие правила из source_module импортировать; target_rules указывает имена, чтобы дать эти правила в target_module. Если source_rules содержит имя, не соответствующее правилу source_module, или если оно содержит иное количество элементов, чем target_rules, выдается ошибка. Например,

# import m1.rule1 into m2 as local rule m1-rule1.
IMPORT m1 : rule1 : m2 : m1-rule1 ;
# import all non-local rules from m1 into m2
IMPORT m1 : [ RULENAMES m1 ] : m2 : [ RULENAMES m1 ] ;

EXPORT позволяет использовать псевдонимы правил в разных модулях:

rule EXPORT ( module ? : rules * )

Экспорт Знаки правил правила из модуля source_module как нелокальные (и, следовательно, экспортируемые). Если элемент правил не называет правило в модуле, выдается ошибка. Например,

module X {
  local rule r { ECHO X.r ; }
}
IMPORT X : r : : r ; # error - r is local in X
EXPORT X : r ;
IMPORT X : r : : r ; # OK.
rule CALLER_MODULE ( levels ? )

CALLER_MODULE возвращает имя области действия модуля, включающей вызов, своему абоненту (если уровни поставляются, это интерпретируется как целое число дополнительных уровней стека вызовов для пересечения, чтобы найти модуль). Если область применения относится к глобальному модулю, или если такого модуля не существует, возвращается пустой список. Например, следующие отпечатки "{Y} {X}":

module X {
    rule get-caller { return [ CALLER_MODULE ] ; }
    rule get-caller's-caller { return [ CALLER_MODULE 1 ] ; }
    rule call-Y { return Y.call-X2 ; }
}
module Y {
    rule call-X { return X.get-caller ; }
    rule call-X2 { return X.get-caller's-caller ; }
}
callers = [ X.get-caller ] [ Y.call-X ] [ X.call-Y ] ;
ECHO {$(callers)} ;
rule DELETE_MODULE ( module ? )

DELETE_MODULE удаляет все вариабельные привязки и иные правила из данного модуля (или глобального модуля, если модуль не поставляется) и возвращает их память в систему.

[Note] Note

Хотя это не повлияет на правила, которые в настоящее время выполняются до их завершения, Delete_Module следует использовать с особой осторожностью, потому что это немедленно уничтожит любые другие и все переменные (включая местных жителей в этом модуле). Из-за того, как работает динамическое связывание, переменные, которые скрыты местными жителями, не будут уничтожены, поэтому результаты могут быть действительно непредсказуемыми.


PrevUpHomeNext

Статья Language раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 46. Boost.Jam : 3.1.19 может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 46. Boost.Jam : 3.1.19 ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 07:16:47/0.028162956237793/1