Просто найдя Rust и прочитав первые две главы документации, я нахожу подход и способ определения языка особенно интересными. Поэтому я решил намочить пальцы и начал с Hello world ...
Я сделал это на Windows 7 x64, кстати.
fn main() {
println!("Hello, world!");
}
Выдав cargo build
и посмотрев на результат, targets\debug
я обнаружил, .exe
что получилось 3MB. После некоторого поиска (документация флагов грузовой командной строки трудно найти ...) я нашел --release
вариант и создал сборку релиза. К моему удивлению, размер .exe уменьшился лишь на незначительную величину: 2,99 МБ вместо 3 МБ.
Итак, признавшись, что я новичок в Rust и его экосистеме, я ожидал, что язык системного программирования создаст что-то компактное.
Кто-нибудь может уточнить, что компилирует Rust, как это возможно, что он производит такие огромные изображения из 3-х линейной программы? Компилируется ли это на виртуальную машину? Я пропустил команду стриптиза (отладочную информацию в сборке релиза?)? Что-нибудь еще, что могло бы позволить понять, что происходит?
источник
Ответы:
Rust использует статическую компоновку для компиляции своих программ, это означает, что все библиотеки, требуемые даже самой простой
Hello world!
программой, будут скомпилированы в ваш исполняемый файл. Это также включает среду выполнения Rust.Чтобы заставить Rust динамически связывать программы, используйте аргументы командной строки
-C prefer-dynamic
; это приведет к гораздо меньшему размеру файла, но также потребует, чтобы библиотеки Rust (включая время выполнения) были доступны вашей программе во время выполнения. По сути, это означает, что вам нужно будет предоставить их, если на компьютере их нет, занимая больше места, чем ваша исходная статически связанная программа.Для переносимости я бы порекомендовал вам статически связать библиотеки Rust и среду выполнения так, как вы это делали, если бы вы когда-нибудь распространяли свои программы среди других.
источник
cargo rustc [--debug or --release] -- -C prefer-dynamic
У меня нет систем для Windows, чтобы попробовать, но в Linux статически скомпилированный мир Rust hello на самом деле меньше, чем эквивалентный C. Если вы видите огромную разницу в размерах, это возможно потому, что вы связываете исполняемый файл Rust статически и C один динамически.
При динамическом связывании вам также необходимо учитывать размер всех динамических библиотек, а не только исполняемого файла.
Итак, если вы хотите сравнить яблоки с яблоками, вам нужно убедиться, что оба они динамические или оба статические. Разные компиляторы будут иметь разные значения по умолчанию, поэтому вы не можете просто полагаться на значения по умолчанию компилятора для получения одинакового результата.
Если вам интересно, вот мои результаты:
Они были скомпилированы с помощью gcc (Debian 4.9.2-10) 4.9.2 и rustc 1.0.0-nightly (d17d6e7f1 2015-04-02) (построено 2015-04-03), как с параметрами по умолчанию, так и
-static
для gcc и-C prefer-dynamic
для rustc.У меня было две версии C hello world, потому что я думал, что использование
puts()
может связать меньшее количество модулей компиляции.Если вы хотите попробовать воспроизвести его в Windows, вот источники, которые я использовал:
printf.c:
puts.c:
rust.rs
Кроме того, имейте в виду, что различные объемы отладочной информации или разные уровни оптимизации также могут иметь значение. Но я ожидаю, что если вы видите огромную разницу, это связано со статическим и динамическим связыванием.
источник
strip -s
, уменьшена с 1.6M до 190K. Сборка релиза (по умолчанию плюсopt-level='s'
,lto = true
и,panic = 'abort'
чтобы минимизировать размер) падает с 623K до 158K.При компиляции с Cargo вы можете использовать динамическое связывание:
Это значительно уменьшит размер двоичного файла, поскольку теперь он динамически связан.
В Linux, по крайней мере, вы также можете удалить двоичные символы с помощью
strip
команды:Это примерно вдвое уменьшит размер большинства двоичных файлов.
источник
Обзор всех способов уменьшения размера двоичного файла Rust см. В
min-sized-rust
репозитории.Текущие шаги высокого уровня для уменьшения размера двоичного файла:
jemalloc
по умолчанию не включается )Cargo.toml
cargo build --release
strip
полученный бинарный файл.С помощью
nightly
Rust можно сделать гораздо больше , но я оставлю эту информацию,min-sized-rust
поскольку она меняется со временем из-за использования нестабильных функций.Вы также можете использовать
#![no_std]
для удаления ржавчиныlibstd
. Смотритеmin-sized-rust
подробности.источник
Это особенность, а не ошибка!
Вы можете указать версии библиотеки (в связанном с проектом файле Cargo.toml ), используемые в программе (даже неявные) для обеспечения совместимости версий библиотеки. Это, с другой стороны, требует, чтобы конкретная библиотека была статически связана с исполняемым файлом, генерируя большие образы времени выполнения.
Эй, это уже не 1978 год - многие люди имеют более 2 МБ ОЗУ на своих компьютерах :-)
источник