RPM/Rust: различия между версиями

Материал из ALT Linux Wiki
< RPM
м (Vt переименовал страницу RPM/rust в RPM/Rust: Upcase)
 
(не показано 18 промежуточных версий 3 участников)
Строка 1: Строка 1:
= Как быстро сделать Rust пакет =
= Как быстро сделать Rust пакет с вендорингом =


Мы пошли по пути "вендоринга", то есть сборки зависимостей одновременно с исходным пакетом (в отличии от помещения их в отдельные пакеты и использования BuildRequires). Как завендорить растовые зависимости (в дире с пакетом):
Вендоринг — сохранение внешних зависимостей вместе с исходным пакетом (в отличии от помещения их в отдельные пакеты и использования <code>BuildRequires</code>). Как завендорить растовые зависимости (в дире с пакетом):


  $ cargo vendor
$ cargo vendor
  $ find vendor -name '*.a' -delete
$ find vendor -name '*.a' -delete
  $ git add -A vendor
$ git add -A -f vendor Cargo.lock
  $ git commit -m "cargo vendor"
$ git commit -m "cargo vendor"


* cargo vendor - поместит все зависимости в диру vendor/, желательно, чтоб она была пустая.
* <code>cargo vendor</code> - поместит все зависимости в диру vendor/, желательно, чтоб она была пустая.
* find - удалит бинарные библиотеки из виндовых зависимостей (winapi*).
* <code>find</code> - удалит бинарные библиотеки из виндовых зависимостей (winapi*). Ниже есть более сложный пример.
* <code>git add -f</code> - чтобы избежать возможных проблем с <code>.gitignore</code>.


В спеке:
В спеке:


  BuildRequires: /proc
BuildRequires: /proc
  BuildRequires: rust-cargo
BuildRequires: rust-cargo


* /proc необходим для работы cargo.
* <code>/proc</code> необходим для работы cargo.


В секции %prep после %setup:
В секции <code>%prep</code> после <code>%setup</code>:


  mkdir -p .cargo
mkdir -p .cargo
  cat >> .cargo/config <<EOF
cat >> .cargo/config <<EOF
  [source.crates-io]
[source.crates-io]
  replace-with = "vendored-sources"
replace-with = "vendored-sources"
 
  [source.vendored-sources]
[source.vendored-sources]
  directory = "vendor"
directory = "vendor"
 
  [term]
[term]
  verbose = true
verbose = true
 
quiet = false
  [install]
  root = "%buildroot%_prefix"
[install]
 
root = "%buildroot%_prefix"
  [build]
  rustflags = ["-Cdebuginfo=1"]
[build]
  EOF
rustflags = ["-Copt-level=3", "-Cdebuginfo=1"]
[profile.release]
strip = false
EOF


* эта конструкция подключит вендореные исходники, настроит опции сборки и инсталляции.
* эта конструкция подключит вендореные исходники, настроит опции сборки и инсталляции.


В %build:
В <code>%build</code>:


  cargo build %_smp_mflags --offline --release
cargo build %_smp_mflags --offline --release


В %install (если пакет не библиотека, а бинарник):
В <code>%install</code> (если пакет не библиотека, а бинарник):


  cargo install %_smp_mflags --offline --no-track --path .
cargo install %_smp_mflags --offline --no-track --path .


В %check, если нужен:
В <code>%check</code>, если нужен:


  cargo test %_smp_mflags --release --no-fail-fast
cargo test %_smp_mflags --release --no-fail-fast
 
= Полезные советы =
* Более глубокая очистка от бинарных артефактов:
find vendor/ \( -name '*.a' -o -name '*.lib' -o -name '*.dll' -o -name '*.obj' \) -delete
sed -Ei 's!,"[^"]+\.(a|lib|dll|obj)":"[^"]+"!!g' $(find vendor -name .cargo-checksum.json)
Такая чистка часто ломает <code>rustix</code>, что решается включением <code>use-libc</code> feature (например добавлением при сборке к rustflags <code>--cfg=rustix_use_libc</code>) или включением <code>cc</code> feature — пример как это выглядит в <code>Cargo.toml</code>:
[dependencies]
rustix = { features = ["cc"] }
 
Нужно учитывать, что использование переменой окружения <code>RUSTFLAGS</code> отменяет значение <code>build.rustflags</code> из созданного выше <code>.cargo</code> (в этом случае отключится оптимизация и debuginfo). Поэтому надо добавлять новые опции в <code>.cargo</code>:
rustflags = ["-Copt-level=3", "-Cdebuginfo=1", "--cfg=rustix_use_libc"]
 
* Решение проблем с windows/unix кодировкой текстовых файлов:
grep -sq -w 'text' .gitattributes && echo '* -text' > vendor/.gitattributes
 
* Часто <code>cargo install</code> начинает пересобирать исходники, поэтому лучше делать обычный <code>install</code>:
install -Dp target/release/%name -t %buildroot%_bindir
 
* Сборка упала на 32-битных архитектурах с <code>LLVM ERROR: out of memory</code> <code>Allocation failed</code>. Возможно, апстрим включил излишнюю оптимизацию в Cargo.toml. Её можно перекрыть в создаваемом выше <code>.cargo</code> (в зависимости от того что было включено), например:
[profile.release]
lto = "thin"
codegen-units = 16
 
= Сборка через etersoft-build-utils =
В etersoft-build-utils предусмотрена автоматизация обновления в git-репозитории пакетов rust, требуемых для сборки. Подробности здесь: https://www.altlinux.org/Etersoft-build-utils/extra_sources
 
= Ссылки =
* https://doc.rust-lang.org/cargo/reference/config.html The Cargo Book
* https://nnethercote.github.io/perf-book/build-configuration.html The Rust Performance Book


[[Категория:Devel]]
[[Категория:Devel]]

Текущая версия от 16:33, 1 апреля 2024

Как быстро сделать Rust пакет с вендорингом

Вендоринг — сохранение внешних зависимостей вместе с исходным пакетом (в отличии от помещения их в отдельные пакеты и использования BuildRequires). Как завендорить растовые зависимости (в дире с пакетом):

$ cargo vendor
$ find vendor -name '*.a' -delete
$ git add -A -f vendor Cargo.lock
$ git commit -m "cargo vendor"
  • cargo vendor - поместит все зависимости в диру vendor/, желательно, чтоб она была пустая.
  • find - удалит бинарные библиотеки из виндовых зависимостей (winapi*). Ниже есть более сложный пример.
  • git add -f - чтобы избежать возможных проблем с .gitignore.

В спеке:

BuildRequires: /proc
BuildRequires: rust-cargo
  • /proc необходим для работы cargo.

В секции %prep после %setup:

mkdir -p .cargo
cat >> .cargo/config <<EOF
[source.crates-io]
replace-with = "vendored-sources"

[source.vendored-sources]
directory = "vendor"

[term]
verbose = true
quiet = false

[install]
root = "%buildroot%_prefix"

[build]
rustflags = ["-Copt-level=3", "-Cdebuginfo=1"]

[profile.release]
strip = false
EOF
  • эта конструкция подключит вендореные исходники, настроит опции сборки и инсталляции.

В %build:

cargo build %_smp_mflags --offline --release

В %install (если пакет не библиотека, а бинарник):

cargo install %_smp_mflags --offline --no-track --path .

В %check, если нужен:

cargo test %_smp_mflags --release --no-fail-fast

Полезные советы

  • Более глубокая очистка от бинарных артефактов:
find vendor/ \( -name '*.a' -o -name '*.lib' -o -name '*.dll' -o -name '*.obj' \) -delete
sed -Ei 's!,"[^"]+\.(a|lib|dll|obj)":"[^"]+"!!g' $(find vendor -name .cargo-checksum.json)

Такая чистка часто ломает rustix, что решается включением use-libc feature (например добавлением при сборке к rustflags --cfg=rustix_use_libc) или включением cc feature — пример как это выглядит в Cargo.toml:

[dependencies]
rustix = { features = ["cc"] }

Нужно учитывать, что использование переменой окружения RUSTFLAGS отменяет значение build.rustflags из созданного выше .cargo (в этом случае отключится оптимизация и debuginfo). Поэтому надо добавлять новые опции в .cargo:

rustflags = ["-Copt-level=3", "-Cdebuginfo=1", "--cfg=rustix_use_libc"]
  • Решение проблем с windows/unix кодировкой текстовых файлов:
grep -sq -w 'text' .gitattributes && echo '* -text' > vendor/.gitattributes
  • Часто cargo install начинает пересобирать исходники, поэтому лучше делать обычный install:
install -Dp target/release/%name -t %buildroot%_bindir
  • Сборка упала на 32-битных архитектурах с LLVM ERROR: out of memory Allocation failed. Возможно, апстрим включил излишнюю оптимизацию в Cargo.toml. Её можно перекрыть в создаваемом выше .cargo (в зависимости от того что было включено), например:
[profile.release]
lto = "thin"
codegen-units = 16

Сборка через etersoft-build-utils

В etersoft-build-utils предусмотрена автоматизация обновления в git-репозитории пакетов rust, требуемых для сборки. Подробности здесь: https://www.altlinux.org/Etersoft-build-utils/extra_sources

Ссылки