LINUX.ORG.RU
ФорумTalks

Кросскомпиляция в Rust

 ,


2

4

Чем больше я кросскомпилирую проекты на Си и C++ всех сортов и расцветок (особенно малоизвестные и/или не слишком аккуратно написанные), тем больше мне хочется убивать и быть убитым. Бесконечно так продолжаться не может, поэтому я задаю растоманам ЛОРа следующий вопрос: как компилятор Rust и его пакетный менеджер Cargo относятся к кросскомпиляции?

Могу ли я без особого копания во внутренностях языка собрать кросскомпилятор для интересующей меня архитектуры, положить его в какой-то стандартный каталог, а потом заставить Cargo собрать интересующее меня дерево пакетов (с зависимостями) с помощью этого компилятора, аккуратно разделяя зависимости времени сборки (которые нужно складировать в sysroot, если в Rust есть такое понятие) и зависимости времени выполнения (которые нужно разложить по каталогам для последующего опакечивания)? Разумеется, все собираемые библиотеки должны быть разделяемыми, а не статическими.

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

★★★★★

Последнее исправление: intelfx (всего исправлений: 1)

Да, действительно, почитай бложик. Если в двух словах то для поддерживаемых архитектур просто добавляешь target:

$ rustup target add mips-unknown-linux-musl
И потом при компиляции указываешь его:
$ cargo build --release --target=mips-unknown-linux-musl

Если нужно собирать под неподдерживаемую платформу, например микроконтроллеры, то ставишь xargo

$ cargo install xargo
И уже его используешь для сборки. Он умеет читать твой json файл описания архитектуры и сам соберет стандартную библиотеку под него.

pftBest ★★★★
()

Ну и надо помнить, что хоть сам компилятор раста является кросс компилятором под все архитектуры сразу, многие платформы требуют наличия своего gcc. Для того чтобы cargo знал где искать gcc, просто создаешь в проекте файлик:

$ cat .cargo/config 
[target.mips-unknown-linux-musl]
linker = "mips-openwrt-linux-musl-gcc"
Тут же можно и указать ключи компиляции, чтобы например передать в gcc -EL или --sysroot.

pftBest ★★★★
()

Под виндовс у меня такой конфиг

[target.x86_64-pc-windows-gnu]
linker = "/usr/bin/x86_64-w64-mingw32-gcc"

[target.i686-pc-windows-gnu]
linker = "/usr/bin/i686-w64-mingw32-gcc"
rustflags = "-C panic=abort"

dnb ★★★★
()
Ответ на: комментарий от NextGenenration

Вместо писания программ, что было моей мечтой, мной овладела тоска и невыразимое одиночество; и наконец я увидел страшную правду, в сторону которой остальные боялись даже дышать — непроизносимая тайна тайн открылась мне: этот язык камня и режущих звуков не способен сохранить в себе черт старого языка как Лондон старого Лондона, а Париж старого Парижа, и что на самом деле он довольно небезопасный, а его распростертые внутренности дурно набальзамированы и заселены странными существами, в действительности не имеющими ничего общего с тем, как все выглядит на этапе компиляции

makoven ★★★★★
()

Ещё можно не париться и использовать https://github.com/japaric/cross, который собирает в докере. Но это если есть зависимости от .so, без них и простого rustup-а хватит. Чаще всего как минимум от libssl зависимость есть, но там проще через OPENSSL_STATIC=1 выкручиваться, вот.

loyd
()
Ответ на: комментарий от commagray

Не то. Тема динамических библиотек и compile-time- vs run-time-зависимостей не раскрыта.

intelfx ★★★★★
() автор топика
Ответ на: комментарий от makoven

Не читал, но тоже не то. Я рад, что туда напихали достаточно магии, чтобы всё работало, но тема разделяемых библиотек и опакечивания результатов сборки не раскрыта.

Ты видел, как устроена сборочная система OpenWRT? Там каждый пакет явно описывает правила для установки своего рантайма и билдтайма, а потом это всё распихивается по разным местам: рантайм — в пакет и/или в образ будущей rootfs, рантайм и билдтайм — в sysroot тулчейна. Потом это всё очень легко и удобно пакетить.

Вопрос топика в том, можно ли устроить то же самое силами Cargo, или любой мало-мальски большой низкоуровневый проект будет, как и раньше писать, километровые портянки обёрток?

intelfx ★★★★★
() автор топика
Последнее исправление: intelfx (всего исправлений: 4)
Ответ на: комментарий от loyd

Вот кстати да, что делать с внешними (не-Rust) зависимостями в виде разделяемых библиотек — тоже хороший вопрос. Статическая компоновка не устраивает.

intelfx ★★★★★
() автор топика
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от Harald

Ничем, но мне интересно, подумали ли разработчики Rust о том, чтобы не пройтись своей супер-пафосной сборочной системой ещё раз по тем же граблям, что и сишники, или как обычно.

intelfx ★★★★★
() автор топика
Ответ на: комментарий от intelfx

Хочешь чтобы карго умел управлять сишными кросскомпиляторами и создавать пакеты для разных дистрибов?

"Чтобы *** сосать умела и при этом песни пела" ©

makoven ★★★★★
()
Ответ на: комментарий от makoven

Разумеется, я не говорю, что Cargo должен компилировать сишные проекты. OpenWRT — это пример того, как выглядит идеальная кросс-сборочная система. Про сборку пакетов (любых) я тоже не говорю.

Давай так. Во-первых, есть ли в Rust разделяемые библиотеки в том виде, в котором я привык их видеть? Т. е. можно ли единожды скомпилировать некий library crate и потом использовать результат компиляции (возможно, с некими вспомогательными файлами) в качестве build-time и run-time зависимости нескольких других crate'ов, не используя ни в каком виде исходники библиотеки? Если нет, то дальнейшие вопросы лишены смысла.

Дальше, я знаю, что в Cargo можно собрать любой интересующий проект вместе с его зависимостями одной командой. При этом он будет собран статически, а результаты сборки зависимостей будут либо лежать хз где, либо не сохранятся. Это меня не устраивает.

Я хочу, чтобы Cargo мог складировать результаты сборки library crate'ов в два разных каталога. В первый — все результаты сборки в том виде, в котором они могут быть использованы при сборке зависимых crate'ов (в т. ч. в случае продолжения сборки на другой машине или утраты исходников). Во второй — только run-time компоненты, в том виде, в котором они могут быть перемещены на целевую систему (вместе с run-time компонентами всех зависимостей) и в этом виде там запущены. Также я хочу, чтобы я мог указывать каталог с разделяемыми библиотеками внешних зависимостей.

Это можно? Или нужно обкостыливать скриптами?

intelfx ★★★★★
() автор топика
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Не знаю. Судя по обилию вопросов, гуглящихся по словам «rust [shared rlib dylib prefer-dynamic]» со сборкой из динамических библиотек по прежнему проблемы

Может эта RFC-шка чем-то поможет https://github.com/nox/rust-rfcs/blob/master/text/0404-change-prefer-dynamic.md

makoven ★★★★★
()
Последнее исправление: makoven (всего исправлений: 1)
Ответ на: комментарий от makoven

Ага, то есть в качестве достоинств динамической компоновки экономия ресурсов даже не рассматривается, а полный отказ от динамической компоновки на полном серьёзе приводится как альтернатива? Мда, хипстоязычок как он есть. Я переоценивал Rust.

intelfx ★★★★★
() автор топика
Ответ на: комментарий от intelfx

И я того же мнения. Но на Си всё-равно не вернусь :)

makoven ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.