Search
Write a publication
Pull to refresh

Comments 20

компилирует небольшую программу в режиме релиза, обращает внимание на размер получившегося файла

Впервые увидев такое, я быстро пришел к

[build]
rustflags = ["-Cprefer-dynamic"]

в файле .cargo/config.toml

Для того, чтобы это работало, необходим

export LD_LIBRARY_PATH+=:$(rustc --print=sysroot)/lib

C/С++ работают в подобном режиме, требуя доступ к библиотекам времени выполнения (runtime so/dll).

Забыл уточнить, что по таком подходе HelloWorld получается 16 КБ. Наличие отладочной информации в библиотеках уже не критично. А вот то, что библиотеки грузятся в память один раз на любое количество сервисов на Rust, а не бессмысленно занимают память для каждого сервиса - уже очень заметно.

Замечу, что это будет работать только если бинарь компилировался с точностью той же версией rustc, которая используется при запуске.

У Rust так и нет никакого стабильного ABI, из-за чего нет никаких гарантий, что ваши бинари будут друг с другом совместимы, если компилировались по-разному.

Там вопрос совместимости не стоит. Все библиотеки в имени имеют 64-битную версию в шестнадцатиричном представлении. Если не будет нужной версии - исполняемый файл просто не запустится.

Если в одном контейнере нужно запускать бинарные файлы Rust разных версией с динамической линковкой, то там должны быть библиотеки для каждой из этих версий. Но зачем устраивать самому себе зоопарк, если можно в CI/CD собирать всё одной версией?

Например, в проектах Liinux Kernel и plrust в PostgreSQL версия Rust прибивается гвоздями и её смена подразумевает полную перекомпиляцию. Зато, как я уже указал выше, экономия оперативной памяти получается очень существенная. Только представьте себе, что было бы, если каждый модуль ядра, использующий Rust, тащил бы за собой свою личную копию всех используемых библиотек в память.

Сама концепция статической линковки библиотек в исполняемый файл чем-то похожа на концепцию snap в Ubuntu, со всеми её минусами и плюсами.

По-моему, 415 килобайт - это все еще многовато для хелоуолда :) Помнится , минимальный ms-dos на дискете плюс-минус столько места занимал :)

Не верится что такая проблема не была решена в течении 5 лет! Вроде что-то очевидное и задача не выглядит сложной, а столько времени понадобилось чтобы хоть кто-то её сделал

Забавно, всегда считал это нормой. А так, оказывается, не должно было быть.

Есть ещё одна проблема с размером, которая актуальна не только под GNU/Linix. Не все это знают, но в Rust существует размотка стека при panic! (с вызовом деструкторов), которая (якобы) нужна, чтобы очищать ресурсы запаниковавших потоков или очищать ресурсы, если внешний код (C++) кинул исключение.
Так вот, как известно, бесплатных завтраков не бывает, и за размотку стека приходится платить, в данном случае дополнительным размером исполняемого файла. Но если размотка стека не нужна, размеры итоговых исполняемых файлов можно уменьшить, собирая проект с panic = "abort". В моих случаях это даёт выигрыш размера в 25%.
Случай, кстати, во многом аналогичен случаю из данной статьи. На практике корректной обработкой panic! мало кто занимается, ибо считается, что это признак бага в программе. Так что для большинства пользователей умолчательное поведение поддержки размотки стека неверно и ведёт к увеличению размера файлов.

Потому, что она не якобы очищает ресурсы. Например вот из стандартной библиотеки пример, пытаемся записать буфер в дропе (если не сам писатель эту панику кинул). И для этого не нужно эту панику никак специально обрабатывать, скорее возможность эту панику перехватить . По моему мнению лучше по умолчанию все же хотя бы пытаться все нормально закрыть, а не просто умирать.

опытный разработчик на C или C++ решает попробовать Rust, компилирует небольшую программу в режиме релиза, обращает внимание на размер получившегося файла, сразу же отказывается от освоения этого языка 

Почему только опытный разработчик? И почему только размер?

Вот кнопка и код к ней выходящий counter++ в slint gui после cargo build даёт 250мб, а с release аж целых 17мб.

Размер не беда. Я вот на него косо смотрю, потому что очень редко попадаются ответы на мои вопросы. То-ли это очень просто и не стоит об этом писать, то-ли наоборот это дико сложно, и об этом нужно молчать. Программу таймер я очень быстро сделал на golang, но в расте........ я пока не смог это осилить. Мне нужен раст+ gui, так как его проще установить на альт линукс, а он у меня везде.

Я вполне могу представить ситуацию, как опытный разработчик на C или C++
решает попробовать Rust, компилирует небольшую программу в режиме
релиза, обращает внимание на размер получившегося файла, сразу же
отказывается от освоения этого языка и идёт потешаться над ним на
форумах.

Проблема понятная и реально существующая, но разработчик какой-то не очень опытный, всё-таки. За десяток лет так и не узнать про strip и отладочные символы...

А воз и ныне там... Заинтересовался Rust, сделал первые шаги - первая программка "Hello, World!" исполняемый аж 12 Мегабайт ! (rustс v 1.63.0 - стандартный пакет Linux Debian). С ума можно сойти! И это язык для разработки системных программ, для системного программирования?! Вообще-то объёмы в этой сфере программирования до сих пор имеют очень важное значение.

Спасибо за статью! Удалось уменьшить размер до 440 килобайт, но это всё-равно много. Но при этом самостоятельно пришлось прописать в файле Cargo.toml:
[profile.release]
strip = "debuginfo"

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

установил Rust локально (для одного пользователя в системе) через rustup - результат заметно лучше - 3.6 Мегабайт, но всё-равно это значительный размер, релиз - 416 Кбайт

rustc 1.88.0, cargo 1.88.0

У системного программирования и подходы к программированию совсем другие, вот например минимальный бинарник размером 1.7 КБ (наверняка можно меньше, но я сам не умею)

Код по ссылке ничего не делает, но я попытался добавить системный вызов write, чтобы бинарник был не совсем пустой:

let s = b"Hello, world!\n";
unsafe {
    syscalls::syscall!(syscalls::Sysno::write, 1, s.as_ptr(), s.len()).unwrap();
}

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

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

Судя по всему, это действительно минимальный размер бинарника, но который при этом... и делать то ничего полезного не может из-за отсутствия стандартной библиотеки.
Но пример очень хороший, спасибо! :-)

Мне как-то не очень понятны ваши претензии:

  1. Системное программирование на то и системное, что изначально никакой стандартной библиотеки в принципе не существует. Если используется стандартная библиотека (та, которая про файлы, потоки, ввод-вывод и вот это вот всё), значит используется API готовой операционной системы — а это уже вполне прикладное программирование (к моему примеру с системным вызовом write это тоже относится).

  2. В других языках вроде ведь всё примерно то же самое. Когда вы делаете Hello World на том же C, вы не забываете к размеру бинарника прибавить размер libc для честного сравнения? А сколько плясок с бубном потребуется, чтобы сделать Hello World на C без libc?

Какие претензии, вы о чём?
Я лишь сказал, что изначально размер исполняемого файла в 3.6 Мегабайт может оттолкнуть интересующегося данным языком. Согласитесь, ну это слишком дохрена для библиотеки.
Я только вчера установил Rust - стало просто интересно. И тут такие новости!... Но я подумал, что должно быть какое-то разумное объяснение и решение - в инете нашёл статью, как уменьшить размер. Так что всё норм. Выдохните и успокойтесь! :-)
Вы показали очень хороший пример реализации минимального размера исполняемого файла. Ещё раз вам - Спасибо!... Не надо дальше портить впечатление.

P.S. К слову сказать... Порочная практика - "читать лекции" совершенно незнакомому человеку. Откуда вам вообще знать про мой профессиональный уровень? Я программировал в 90-е и на C, и на Assembler - без всяких библиотек, естественно. Не надо мне тут нравоучений с умным видом, пожалуйста. Терпеть не могу снобов!

Sign up to leave a comment.

Articles