Ports/loongarch64/Porting

Материал из ALT Linux Wiki
Stub.png
Данная страница находится в разработке.
Эта страница ещё не закончена. Информация, представленная здесь, может оказаться неполной или неверной.


Здесь описаны замечания и рекомендации по исправлению сборки пакетов Сизифа на loongarch64.

Общие замечания

loongarch64 -- архитектура, содержащая на удивление немного сюрпризов и подвохов с точки зрения переносимого кода на linux. Обычный, не слишком низкоуровневый код, чаще всего просто собирается и работает.

Проблемы сборки пакетов, уже успешно работающих на 3-4 архитектурах, обычно связаны с тем, что loongarch64 появилась сравнительно недавно и её поддержка просочилась ещё не во все архитектурно-специфичные компоненты.

C/C++

loongarch64 -- little endian, char по умолчанию signed.

Чтобы понять, что Вы на loongarch64, нужно посмотреть на символ __loongarch__ и убедиться, что __loongarch_grlen равен 64 (как-то так). Если важно именно ABI, смотрите на __loongarch_lp64d. Обо всём этом можно прочитать в документации.

cannot find 'ld'

Пример ошибки:

collect2: fatal error: cannot find 'ld'
compilation terminated.

Чаще всего возникает, когда пакет, не проверив, пытается использовать gold. gold на loongarch64 нет, он даже не собирается. Отрывайте.

gcc 10, llvm 12 и сотоварищи

Полноценная поддержка (и вообще поддержка) loongarch64 появилась в GCC 13 и llvm 16.0. Соответственно, более ранних версий этих тулчейнов под loongarch64 нет и не предвидится.

Если какой-то пакет сборочно зависит, например, от gcc12, посмотрите, может он ему не так уж и нужен (пример). Если всё-таки нужен, excludearch неизбежен.

clang/llvm/lld

clang 16.0 и 17.0 не особо поддерживают LSX и LASX (SIMD extensions). Если кто-то их где-то уже пытается применить, отрывайте.

LLD (LLVM linker) не поддерживает многих нужных релокаций и пока (as of 17.0) не умеет в релаксации вообще. clang 17 собран так, чтобы по умолчанию использовать ld.bfd (GNU binutils), так что если вы видите ошибку вроде такой:

ld.lld: error: /usr/bin/../lib64/gcc/loongarch64-alt-linux/13/../../../../lib64/Scrt1.o:(.text+0x0): unknown relocation (102) against symbol
clang: error: linker command failed with exit code 1 (use -v to see invocation)

то кто-то явно передал clang'у -fuse-ld=lld. Уберите эту опцию и всё соберётся.

autotools

Чаще всего проблема в том, что в пакете лежат слишком старые config.guess и config.sub. Ошибка сборки может выглядеть, например, так:

configure: error: cannot guess build type; you must specify one

Если в пакете используется %autoreconf, то такой проблемы быть не должно; если нет, лучше сделать чтобы использовался, хотя для этого иногда приходится проявить изобретательность. Ничего плохого от этого обычно не происходит, а вот хорошее может.

Если с %autoreconf ничего не выходит, можно найти в пакете config.guess и config.sub и заменить их на свежие, системные, самым простым способом:

cp -f /usr/share/autoconf/build-aux/config.{guess,sub} ./где/они/тут

autotools vs boost

Пример ошибки:

checking whether the Boost::System library is available... yes
configure: error: Could not find a version of the library!

Приложите патч, например так.

golang

golang на loongarch64 работает. Архитектура в терминах Google называется loong64.

В логах упавшей сборки стоит поискать слово undefined: (примеры ниже).

Условная сборка

Иногда достаточно объяснить компилятору, какие файлы брать. Для этого в go используются особые директивы в специальных комментариях: пример.

Обновление завендоренного

Часто достаточно обновить завендоренный код до чуть более нового выпуска, в котором поддержка loongarch64 уже добавлена. Просто взять последнюю получается не всегда, так как для этого надо бы поднимать требуемую версию go в проекте, что не всегда хорошо. Приходится искать что-то, что уже поддерживает loong64, но ещё не требует свежести от go.

Если есть go.mod, то обновить завендоренный модуль можно примерно так:

go get 'golang.org/x/sys@v0.0.0-20220712014510-0a85c31ab51e'
go mod tidy
rm -rf vendor
go mod vendor

Каталог vendor часто присутствует в .gitignore, так что нужны специальные меры:

git add -f vendor
git commit -a

И проверьте, что ничего нужного не осталось:

git clean -nxd

Можно править спек и собирать пакет.

Если нет go.mod, импровизируйте.


golang.org/x/sys

Пример ошибки:

[...]
vendor/golang.org/x/sys/unix/ztypes_linux.go:22:11: undefined: Timespec
vendor/golang.org/x/sys/unix/ztypes_linux.go:23:11: undefined: Timespec
vendor/golang.org/x/sys/unix/ztypes_linux.go:1112:12: undefined: SockaddrStorage
[...]

Поддержка loongarch64 в golang.org/x/sys появилась в 2022 году, более старые версии нужно обновить. Мы успешно использовали версию golang.org/x/sys@v0.0.0-20220712014510-0a85c31ab51e

github.com/cilium/ebpf

Пример ошибки:

 ../../vendor/github.com/cilium/ebpf/internal/vdso.go:64:28: undefined: NativeEndian

github.com/cilium/ebpf получил поддержку loongarch64 в версии 0.11.0, однако в ней немало breaking changes в API, поэтому старые (чаще всего 0.9+) версии луше не обновлять, а приложить тривальный патч, например так.

go.etcd.io/bbolt

Пример ошибки:

vendor/go.etcd.io/bbolt/db.go:440:10: undefined: maxMapSize
vendor/go.etcd.io/bbolt/db.go:441:8: undefined: maxMapSize
vendor/go.etcd.io/bbolt/bolt_unix.go:68:15: undefined array length maxMapSize or missing type constraint

Поддержка loongarch64 появилась в 1.3.7, можно попробовать обновиться, иногда получается.

Есть также заброшенный github.com/boltdb/bolt, от которого изначально всё пошло. В него для поддержки loongarch64 нужно добавить файлик.

modernc.org/*

Что-то похожее на начальную поддержку loongarch64 появилось в modernc.org/libc v1.24.1. Хватит ли этого для работы конкретного пакета -- непонятно.

modernc.org/sqlite, modernc.org/tcl, ... -- всё ещё сложнее: https://gitlab.com/cznic/sqlite/-/merge_requests/58

rust

rust под loongarch64 работает, rust под loongarch64 хорош.

Однако часто встречаются довольно старые версии завендоренных зависимостей, которые ещё не знают про loongarch64.

Тогда можно обновить версию в Cargo.lock, например так:

  cargo update --precise 0.12.7 -p target-lexicon

Затем закоммитить и перевендорить зависимости.

Другой вариант решения проблемы -- приложить патч (примеры ниже). Патчи на многие библиотеки тривиальны и добавляют одну-две строки в понятных местах. Однако для завендоренных зависимостей cargo хранит контрольные суммы файлов, поэтому, помимо применения патчей, нужно поправить соответсвующий .cargo-checksum.json. Есть вариант пересчитать контрольные суммы при помощи cargo-vendor-checksum; но часто проще удалить контрольные суммы файлов, cargo на это не ругается, примерно так:

# allow patching vendored rust code
sed -i -e 's/"files":{[^}]*}/"files":{}/' \
     ./path/to/.cargo-checksum.json

nix

Pull request пока (2023-11-17) не принят, пример патча.

target-lexicon

Нужна версия 0.12.7 или новее.

rustix

Поддержка loongarch64 появилась в версии 0.38.5 (ce0d97e75). Однако может оказаться проще приложить патч.

qt5-webengine, qt6-webengine

Нет и в ближайшее время не предвидится. Если в пакете используются rpm-macros-qt5-webengine (или, соответсвенно, rpm-macros-qt6-webengine для Qt6), всё должно работать само. Если нет, переходите на эти макросы (например так).