Тулчейн как расширение SDK#
Пример показывает, как добавить в готовый SDK набор инструментов, не пересобирая сам SDK. За основу взят компилятор из репозитория Astra: он приезжает отдельным расширением и монтируется в точку, объявленную в SDK.
Тулчейн при этом живёт своим циклом: его можно обновить или поставить рядом другую версию, не трогая ни SDK, ни собранные на нём приложения. Скачивают его только те, кому он нужен.
Точка расширения в SDK#
Расширение встаёт только туда, где хост объявил точку. Проверить, что точка есть и как она называется:
flatpak info -m org.astra.mainSdk//1.8.6
В выводе нужна секция вида:
[Extension org.astra.Sdk.Extension]
directory=lib/sdk
subdirectories=true
version=1.8.6
add-ld-path=lib
no-autodownload=true
Отсюда берутся три вещи. Каталог монтирования lib/sdk означает, что
содержимое окажется в /usr/lib/sdk. Включённое subdirectories разрешает
нескольким расширениям встать в подкаталоги одной точки, каждое в свой. Значение
version задаёт ветку, с которой расширение обязано совпасть.
Имя расширения должно начинаться с имени точки: ref
org.astra.Sdk.Extension.llvm-19 встаёт в подкаталог llvm-19, то есть в
/usr/lib/sdk/llvm-19.
Манифест#
version: "1.0"
metadata:
id: org.astra.Sdk.Extension.llvm-19
name: "LLVM/Clang 19 SDK Extension"
version: "1.8.6"
arch: amd64
branch: "1.8.6"
extends:
ref: runtime/org.astra.mainSdk/x86_64/1.8.6
directory: lib/sdk/llvm-19
buildRuntime:
id: org.astra.mainSdk
version: "1.8.6"
sdk: org.astra.mainSdk
source:
type: repository
repository:
package: clang-19
dependencies:
force:
- llvm-19
- llvm-19-dev
- clang-19
- libclang-19-dev
- libclang-cpp19
- libllvm19
- lld-19
layout:
- { from: usr/lib/llvm-19, to: "" }
- { from: usr/lib/x86_64-linux-gnu, to: lib }
files:
write:
- path: enable.sh
executable: true
content: |
export PATH="/usr/lib/sdk/llvm-19/bin${PATH:+:${PATH}}"
export LD_LIBRARY_PATH="/usr/lib/sdk/llvm-19/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
export CC=/usr/lib/sdk/llvm-19/bin/clang
export CXX=/usr/lib/sdk/llvm-19/bin/clang++
export LLVM_CONFIG=/usr/lib/sdk/llvm-19/bin/llvm-config
build:
sbom: true
export:
repository: ./repo
Что здесь важно.
Ветка 1.8.6 в metadata.branch совпадает с version точки расширения.
Расхождение приведёт к тому, что расширение просто не смонтируется, и никакой
ошибки при этом не будет.
Секция buildRuntime задаёт среду, по составу которой отсекается лишнее.
Всё, что уже есть в org.astra.mainSdk, в расширение не попадает, и оно не
дублирует библиотеки хоста.
Список dependencies.force перечисляет пакеты, которые нужны в расширении
несмотря на отсечение. Тулчейн должен быть самодостаточным: он работает из
своего каталога, а не из системных путей хоста.
Раскладка уплощает дерево. Пакеты Debian кладут тулчейн в
usr/lib/llvm-19, а разделяемые библиотеки в каталог архитектуры. Первое
правило поднимает содержимое usr/lib/llvm-19 в корень расширения, второе
кладёт библиотеки в lib. После этого bin, lib и include
оказываются там, где их ждёт enable.sh.
Файл enable.sh не обязателен, но избавляет от ручной настройки путей: его
достаточно подключить в начале сборки.
Сборка#
aft-extension validate llvm.yaml
sudo aft-extension build llvm.yaml
В одном файле можно описать несколько версий тулчейна, разделив документы
строкой ---. Они соберутся по очереди и встанут в соседние подкаталоги
одной точки.
Проверка#
Расширение ставится отдельно от SDK: точка объявлена с no-autodownload,
поэтому само оно не приедет:
sudo flatpak remote-add --if-not-exists --no-gpg-verify local-repo ./repo
sudo flatpak install -y local-repo org.astra.Sdk.Extension.llvm-19//1.8.6
Проверить, что расширение смонтировалось и работает, можно прямо в песочнице SDK:
flatpak run --command=sh runtime/org.astra.mainSdk/x86_64/1.8.6
Внутри:
ls /usr/lib/sdk
. /usr/lib/sdk/llvm-19/enable.sh
clang --version
echo 'int main(){return 0;}' > /tmp/t.c && clang /tmp/t.c -o /tmp/t && /tmp/t
Пустой каталог /usr/lib/sdk означает, что расширение не смонтировалось.
Самые частые причины две: ветка расширения не совпадает с version точки, или
имя ref не начинается с имени точки.
Использование при сборке приложения#
Расширение SDK подключается на время сборки и в готовое приложение не попадает.
Для источника sourcedir подключение делается первой командой сборки:
source:
type: sourcedir
sourcedir:
path: ./src
buildCommands:
- . /usr/lib/sdk/llvm-19/enable.sh && cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/app
- . /usr/lib/sdk/llvm-19/enable.sh && cmake --build build -j
- cmake --install build