Значение ?= и ??= в bitbake/yocto

Вопрос или проблема

Что означают различные типы присвоений в сценариях рецептов 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 или не определена.

Подведение итогов

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

  • ?= (слабое присваивание): Используется для задания значения по умолчанию, которое сохраняется только если переменная до этого не была задана.
  • ??= (очень слабое присваивание): Сохраняет предыдущее значение, если оно установлено, и заменяет слабое значение, только если переменная была изначально неинициализирована.

Таким образом, используя ?= и ??=, разработчики могут более эффективно управлять значениями переменных и настраивать сборку системы под свои нужды.

Оцените материал
Добавить комментарий

Капча загружается...