Вопрос или проблема
Что означают различные типы присвоений в сценариях рецептов bitbake, такие как:
BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
PARALLEL_MAKE ?= "-j ${@oe.utils.cpu_count()}"
MACHINE ??= "qemux86"
Что из вышеуказанного аналогично Ruby’s bb_number_threads ||="что-то"
?
Согласно разделу 3: Синтаксис и операторы
Руководства пользователя BitBake:
?= это:
3.1.5 Установка значения по умолчанию (?=)
Вы можете использовать оператор “?=”
для достижения “более мягкого” присвоения переменной.
Этот тип присвоения позволяет вам определить переменную,
если она неопределена, когда выражение разбирается,
но оставить значение, если переменная имеет значение.
Вот пример:A ?= "aval"
Если
A
установлена на момент разбора этого выражения,
переменная сохраняет свое значение.
Однако, еслиA
не установлена, переменная устанавливается в “aval”.
??= это:
3.1.6 Установка слабого значения по умолчанию (??=)
Слабое значение по умолчанию переменной — это значение,
к которому эта переменная будет расширяться,
если ей не было присвоено значение
через любой другой оператор присвоения.
Оператор “??=” вступает в действие немедленно,
заменяя любое ранее определенное слабое значение по умолчанию.
Вот пример:W ??= "x" A := "${W}" # Немедленное расширение переменной W ??= "y" B := "${W}" # Немедленное расширение переменной W ??= "z" C = "${W}" W ?= "i"
После разбора мы получим:
A = "x" B = "y" C = "i" W = "i"
Добавление и предшествование не переписывающим стилем
не заменит слабое значение по умолчанию,
что означает, что после разбора:W ??= "x" W += "y"
мы получим:
W = " y"
С другой стороны, добавления/предшествования/удаления в переписывающем стиле применяются после замены любого активного слабого значения по умолчанию:
W ??= "x" W:append = "y"
После разбора мы получим:
W = "xy"
Краткое и четкое объяснение будет следующим:
ЕСЛИ A не установлена до и
A ?= aval
A ?= difval
в конце разбора значение A
будет aval
.
Простое правило о ?=
: будет использоваться первое установленное значение.
ЕСЛИ A не установлена до и
A ?= aval
A ??= difval
ИЛИ
A = aval
A ??= difval
в конце разбора значение A останется aval
Простое правило о ??=
: =
& ?=
перезаписывают ??=
ЕСЛИ A не установлена до и
A ??= aval
A ??= difval
в конце разбора значение A будет difval
Простое правило о ??=
: последнее установленное значение через ??=
будет иметь значение.
Ответ или решение
В системе сборки Yocto и в скриптах рецептов BitBake используются различные операторы присваивания для управления значениями переменных. Среди них выделяются ?=
и ??=
, каждая из которых выполняет определённую функцию при условии, что переменная до этого момента не была задана. Давайте более подробно рассмотрим эти операторы, их поведение и аналогии с языком Ruby.
Оператор ?=
- Описание: Оператор
?=
позволяет назначить значение переменной только в том случае, если она еще не была определена. Это значит, что если переменная уже имеет значение, оно останется неизменным. Такой подход часто используется для задания значений по умолчанию. - Пример: Если вы пишете
BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
Это означает, что если переменная
BB_NUMBER_THREADS
не была раньше задана, то ей будет присвоено значение, возвращаемое функциейoe.utils.cpu_count()
. В противном случае, текущее значение переменной останется прежним.
Оператор ??=
- Описание: Оператор
??=
задает значение переменной с "слабым" приоритетом. Это означает, что он будет действовать только в том случае, если переменная не имеет никакого значения, но при этом он может быть перезаписан другими операциями присваивания, такими как=
или?=
. - Пример: При использовании
MACHINE ??= "qemux86"
Если
MACHINE
еще не была определена, то ей будет присвоено значение "qemux86". Если же она уже имеет значение, то оно останется в силе, и "qemux86" не заменит его.
Сравнение с Ruby
В контексте языка Ruby аналогом конструкции BB_NUMBER_THREADS ?= "что-то"
может служить выражение:
bb_number_threads ||= "что-то"
Оператор ||=
в Ruby выполняет схожую функцию, при этом устанавливая значение только в том случае, если переменная до этого момента была nil
или не определена.
Подведение итогов
Эти операторы предоставляют гибкие механизмы для задания значений переменных, что особенно важно в контексте сборки программного обеспечения, где конфигурации могут меняться и адаптироваться в зависимости от контекста.
- ?= (слабое присваивание): Используется для задания значения по умолчанию, которое сохраняется только если переменная до этого не была задана.
- ??= (очень слабое присваивание): Сохраняет предыдущее значение, если оно установлено, и заменяет слабое значение, только если переменная была изначально неинициализирована.
Таким образом, используя ?=
и ??=
, разработчики могут более эффективно управлять значениями переменных и настраивать сборку системы под свои нужды.