Бэкдор Rust Crates с Cargo

задняя часть Rust

Бэкдор Rust Crates с Cargo

Автор: Ван Цзянтун

Эта статья кратко расскажет, что такое «Эта неделя в Rust».Твит 409Есть информация о том, что Cargo оптимизирует двоичный размер,Твит 417Есть контент, связанный с бэкдорами ящиков, командами и инструментами Cargo.

Ящики и бэкдор

Ящики Rust обычно управляются на crates.io единообразно, однако не все ящики являются надежными и безопасными. Хотя языковая группа Rust усердно работает над созданием механизмов управления вновь загруженными библиотеками, эти механизмы управления могут быть плохо реализованы для библиотек, уже загруженных на crates.io. Например, предыдущая статья 415, упомянутая в еженедельном отчетеУязвимость безопасности ржавчины, из-за двунаправленного переопределения невидимых кодовых точек, поддерживаемых кодировкой Unicode, код, который пользователь читает в редакторе, может не совпадать с фактическим кодом. В дополнение к этой фиксированной дыре в безопасности,"Backdooring Rust crates for fun and profit«Кроме того, существует восемь способов удаленного выполнения кода на целевой машине.

Более простые методы включают использование похожих на ящики имен и префиксов, чтобы сбить с толку менее осторожных пользователей. Например, для существующей библиотекиnum_cpus, злоумышленник может загрузить библиотеку с похожим названиемnum_cpu, и по образцуnum_cpusДокументация, чтобы запутать пользователей. Кроме того, все репозитории на Craites.io не перечислены на организационные или личные счета, такие как GitHub, но размещены на общественной платформе. Поэтому некоторые проекты или разработчики используют префиксы для дифференциации их библиотек, напримерtokio-streamилиactix-http. Тем не менее, эти префиксы могут использоваться кем угодно, злоумышленники могут добавлять префиксы к небезопасным библиотекам, чтобы запутать пользователей, а для аналогичных файлов readme, репозиториев github, тегов и других поддельных свойств иногда пользователи не могут отличить их с первого взгляда Эти библиотеки не являются источниками из проверенных проектов.

Другой способ — скрыть зависимости с помощью бэкдоров, например, в дереве зависимостей библиотеки. Когда пользователь использует библиотеку, он почти не смотрит на дерево зависимостей библиотеки и, таким образом, впервые обнаруживает, что библиотека зависит от небезопасной библиотеки.

Например, когда речь идет об уязвимостях управления, злоумышленнику нужен только токен, чтобы выпустить обновление для библиотеки. Если злоумышленник получает токен, используяcargo publish --allow-dirtyкоманда, то публикация обновления не потребует от злоумышленника загрузки кода в общедоступный репозиторий, а если обновление будет опубликовано, все ящики, использующие более старую версию библиотеки, загрузят вредоносное обновление, когда пользователь использует Cargo.

Кроме того, кодирование с использованием определенных библиотек, вредоносных макросов и вредоносных build.rs может быть проблематичным.

В Rust выполнение программы начинается с основной функции, однако при использовании Linux или FreeBSD.init_arrayБлоки, macOS/iOS__DATA, __mod_init_funcблок, окна.ctors,.CRT$XCUблок, который может запускать некоторый код перед вызовом функции. например для ящикаstartup:

#[macro_export]
macro_rules! on_startup {
    ($($tokens:tt)*) => {
        const _: () = {
            // pulled out and scoped to be unable to see the other defs because
            // of the issues around item-level hygene.
            extern "C" fn __init_function() {
                // Note: currently pointless, since even when loaded at runtime
                // via dlopen, panicing before main makes the stdlib abort.
                // However, if that ever changes in the future, we want to guard
                // against unwinding over an `extern "C"` boundary, so we force
                // a double-panic, which will trigger an abort (rather than have
                // any UB).
                let _guard = $crate::_private::PanicOnDrop;
                // Note: ensure we still forget the guard even if `$tokens` has
                // an explicit `return` in it somewhere.
                let _ = (|| -> () { $($tokens)* })();
                $crate::_private::forget(_guard);
            }
            {
                #[used]
                #[cfg_attr(
                    any(target_os = "macos", target_os = "ios", target_os = "tvos"),
                    link_section = "__DATA,__mod_init_func",
                )]
                // These definitely support .init_array
                #[cfg_attr(
                    any(
                        target_os = "linux",
                        target_os = "android",
                        target_os = "freebsd",
                        target_os = "netbsd",
                    ),
                    link_section = ".init_array"
                )]
                // Assume all other unixs support .ctors
                #[cfg_attr(all(
                    any(unix, all(target_os = "windows", target_env = "gnu")),
                    not(any(
                        target_os = "macos", target_os = "ios",
                        target_os = "tvos", target_os = "linux",
                        target_os = "android", target_os = "freebsd",
                        target_os = "netbsd",
                    ))
                ), link_section = ".ctors")]
                #[cfg_attr(all(windows, not(target_env = "gnu")), link_section = ".CRT$XCU")]
                static __CTOR: extern "C" fn() = __init_function;
            };
        };
    };
}

Бэкдоры можно создать в библиотеке:

  • lib.rs
pub fn do_something() {
    println!("do something...");
}

startup::on_startup! {
    println!("Warning! You just ran a malicious package. Please read https://kerkour.com/rust-crate-backdoor for more information.");
}
  • main.rs
fn main() {
    backdoored_crate::do_something();
}

Вредоносный код запустится до запуска основной функции.

Макрос-код будет скомпилирован или использоватьcargo checkКогда инструкция выполняется,rust-analyzerМакросы также раскрываются при открытии проекта в редакторе, поэтому, если макрос в зависимой библиотеке содержит вредоносный код, этот код может выполняться без ведома пользователя. Например:

  • lib.rs
use proc_macro::TokenStream;
use std::path::Path;

fn write_warning(file: &str) {
    let home = std::env::var("HOME").unwrap();
    let home = Path::new(&home);
    let warning_file = home.join(file);

    let message = "Warning! You just ran a malicious package. Please read https://kerkour.com/rust-crate-backdoor for more information.";
    let _ = std::fs::write(warning_file, message);
}

// 属性宏
#[proc_macro_derive(Evil)]
pub fn evil_derive(_item: TokenStream) -> TokenStream {
    write_warning("WARNING_DERIVE");

    "".parse().unwrap()
}
  • lib.rs, который зависит от этой библиотеки
use malicious_macro::Evil;

#[derive(Evil)]
pub struct RandomStruct {}

другой пример:

  • lib.rs
// 类函数过程宏
#[proc_macro]
pub fn evil(_item: TokenStream) -> TokenStream {
    write_warning("WARNING_MACRO");

    "".parse().unwrap()
}
  • lib.rs, который зависит от этой библиотеки
pub fn do_something() {
    println!("do something...");
}

malicious_macro::evil!();
  • main.rs
fn main() {
    lib::do_something();
}

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

build.rs может помочь с настройкой процесса сборки, такой как компиляция или связывание сторонних библиотек, отличных от Rust. build.rs похож на макрос, при использованииcargo checkИли используйте командуrust-analyzerкогда звонили. Точно так же, если build.rs содержит вредоносный код, этот код будет выполняться при использовании этих инструкций, вызывая проблемы с безопасностью. Например:

use std::path::Path;

fn main() {
    let home = std::env::var("HOME").unwrap();
    let home = Path::new(&home);
    let warning_file = home.join("WARNING_BUILD");

    let message = "Warning! You just ran a malicious package. Please read https://kerkour.com/rust-crate-backdoor for more information.";
    let _ = std::fs::write(warning_file, message);
}

Однако, несмотря на то, что при использовании ящиков существуют риски, эти риски не являются полностью неуправляемыми, и проблемы с безопасностью можно предотвратить, например:

  • Используйте большую стандартную библиотеку, чтобы уменьшить зависимость от сторонних библиотек.
  • Используйте зависимости Rust git для поиска и обновления конкретных коммитов.
  • Используйте облачную среду разработки и среду песочницы, чтобы уменьшить ущерб от проблем с безопасностью.

Cargo

Cargo — это менеджер пакетов Rust, который отвечает за управление основным рабочим процессом Rust, может предоставлять такие функции, как контроль и сортировка зависимостей проектов Rust, а также помощь в компиляции проектов Rust. Официальное руководство на английском языке доступноdoc.rust-lang.org/cargo/, также есть…

Грузовая директива

в соответствии с"Top 10 Rust Cargo Commands", десять наиболее часто используемых инструкций выглядят следующим образом:

  • cargo install [option] crate ...

    • Установите двоичный пакет Rust в папку bin корневого каталога установки Rust.Можно установить только исполняемый файл bin или файл-пример.
    • Позиция пакета по умолчанию — crate.io, но если, например, установлен флаг--git,--path,--registryд., пакеты можно устанавливать и с других адресов. Внутреннее использование Huawei может относиться к этому параметру:откройте item.huawei.com/community, чтобы…
    • e.g.
      • cargo install sqlx
      • cargo install --path PATH
  • cargo uninstall [options] [spec...]

    • Удалите двоичный пакет, параметр spec — это идентификатор удаляемого пакета, а сведения о параметре можно найти вdoc.rust-wolf.org/cargo/comma…
    • e.g.
      • cargo uninstall ripgrep
  • cargo tree [options]

    • Посмотреть дерево зависимостей, параметры видныdoc.rust-wolf.org/cargo/comma…

    • e.g.

      • myproject v0.1.0 (/myproject)
        └── rand v0.7.3
            ├── getrandom v0.1.14
            │   ├── cfg-if v0.1.10
            │   └── libc v0.2.68
            ├── libc v0.2.68 (*)
            ├── rand_chacha v0.2.2
            │   ├── ppv-lite86 v0.2.6
            │   └── rand_core v0.5.1
            │       └── getrandom v0.1.14 (*)
            └── rand_core v0.5.1 (*)
        [build-dependencies]
        └── cc v1.0.50
        
  • cargo search [options] [query...]

    • Поиск указанных символов на CRATE.IO и вернуть результаты после набора Sytesette. Запрос относится к символу поиска, опция виднаdoc.rust-wolf.org/cargo/comma…

    • e.g.

      • cargo search serdeвернусь:

      • serde = "1.0.130"                         # A generic serialization/deserialization framework
        discord_typed_interactions = "0.1.0"      # suppose you're working with discord slash commands and you want statically typed requ…
        serde_json_experimental = "1.0.29-rc1"    # A JSON serialization file format
        alt_serde_json = "1.0.61"                 # A JSON serialization file format
        serde_json = "1.0.70"                     # A JSON serialization file format
        serde_partiql = "1.1.65"                  # A PartiQL data model serialization file format
        cargo-geiger = "0.11.1"                   # Detects usage of unsafe Rust in a Rust crate and its dependencies.
        serde-encrypt = "0.6.0"                   # Encrypts all the Serialize
        serde-encrypt-core = "0.6.0"              # Encrypts all the Serialize
        typescript-definitions = "0.1.10"         # serde support for exporting Typescript definitions
        ... and 2787 crates more (use --limit N to see more)
        
  • cargo edit

    • Это продолжение груза, и его необходимо пропустить черезcargo install cargo-editУстановить
    • Помимо непосредственного редактирования cargo.toml, редактирование зависимостей также можно редактировать с помощью команды редактирования. Подкоманды включают:
      • cargo add
      • cargo rm
      • cargo upgrade
      • cargo set-version
  • cargo +nightly udeps

    • нужно пройтиcargo install cargo-udeps --lockedУстановить
    • Это может помочь обнаружить неиспользуемую зависимость в cargo.toml. Нужна ночная версия для запуска
  • cargo expand

    • нужно пройтиcargo install cargo-expandУстановить

    • Для текущего ящика распечатайте макрос с помощью#[derive]Расширенные результаты

    • e.g.

      • Оригинальный код:
      #[derive(Debug)]
      struct S;
      
      fn main() {
          println!("{:?}", S);
      }
      
      • После использования команды развернуть
      #[prelude_import]
      use std::prelude::v1::*;
      #[macro_use]
      extern crate std;
      struct S;
      #[automatically_derived]
      #[allow(unused_qualifications)]
      impl ::core::fmt::Debug for S {
          fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
              match *self {
                  S => {
                      let mut debug_trait_builder = f.debug_tuple("S");
                      debug_trait_builder.finish()
                  }
              }
          }
      }
      fn main() {
          {
              ::std::io::_print(::core::fmt::Arguments::new_v1(
                  &["", "\n"],
                  &match (&S,) {
                      (arg0,) => [::core::fmt::ArgumentV1::new(arg0, ::core::fmt::Debug::fmt)],
                  },
              ));
          };
      }
      
  • cargo tarpaulin

    • нужно пройтиcargo install cargo-tarpaulinУстановить. tarpaulin может сообщать о покрытии кода тестами Cargo, но в настоящее время его можно использовать только на архитектуре процессора x86_64 и системах Linux.
    • e.g.
      • инструкции по использованиюcargo tarpaulin --ignore-testsРассчитать покрытие кода, исключая тестовые функции
  • cargo audit

    • нужно пройтиcargo install cargo-auditУстановить
    • Вы можете проверить файл Cargo.lock, чтобы найтиRustSec Adivisory База данныхБиблиотеки с угрозами безопасности, задокументированные в
  • cargo deny

    • нужно пройтиcargo install --locked cargo-deny && cargo deny init && cargo deny checkУстановить

    • Вы можете проверить файл Cargo.lock, чтобы найти зависимости в дереве зависимостей.Консультативная база данных RustSecБиблиотеки с угрозами безопасности ограничены использованием, лицензией, источником загрузки и версиями некоторых зависимостей.

    • e.g.

      • cargo deny check licenses
      • image.png

Некоторые другие часто используемые команды, такие как:

  • cargo help [subcommand]
    • Меню справки, вы можете найти меню справки для команды
    • Его также можно добавить после команды--help flag
  • cargo version [options]
    • Посмотреть версию
  • cargo bench [options] [benchname] [-- bench-options]
    • Скомпилируйте и выполните бенчмарки. Может выполняться только в ночной версии, можно увидеть подробные параметрыdoc.rust-wolf.org/cargo/comma…
    • e.g.
      • грузовой стенд -- foo --exact: запустить только бенчмарк с именем foo
  • cargo build [options]
    • Скомпилируйте текущий пакет
    • доступный--package,--workspace,--excludeПодождите, пока флаг установит, какие пакеты нужно скомпилировать. Подробности параметров можно увидетьdoc.rust-wolf.org/cargo/comma…
  • cargo check [option]
    • Проверьте текущий пакет и его зависимости на наличие ошибок
  • cargo clean [option]
    • Очищает цели, созданные Cargo. Иногда лучше выполнить очистку перед обновлением тестов кода или эталонных тестов.
  • cargo doc [option]
    • Генерация документов, документ находится в папке target/doc. Подробности параметров можно увидетьdoc.rust-wolf.org/cargo/comma…
  • cargo fix [option]
    • Исправлено предупреждение rustc, эквивалентноеcargo check --all-targets. Подробности параметров можно увидетьdoc.rust-wolf.org/cargo/comma…
  • cargo run [option] [-- args]
    • Запустите двоичный файл или файл примера текущего пакета. существует--Последующие аргументы запускаются как двоичные аргументы. Если сам двоичный файл требует ввода командной строки, в--之前的参数会传递给Cargo,而在之后的参数会传递给二进制文件。 Подробности параметров можно увидетьdoc.rust-wolf.org/cargo/comma…
    • e.g.
      • cargo run --example exname -- --exoption exarg1 exarg2
  • cargo test [options] [testname] [-- test-options]
    • Запускать модульные и интеграционные тесты, т. е.#[test]Функции с измененными атрибутами. иcargo runто же, в--Аргументы до передаются в Cargo, а аргументы после передаются в тестовый двоичный файл. Подробности параметров можно увидетьdoc.rust-wolf.org/cargo/comma…
    • e.g.
      • cargo test foo -- --test-threads 3

И еще немного расширения:

  • cargo depgraph

    • нужно пройтиcargo install cargo-depgraphУстановить. Создание графиков зависимости проекта с использованием метаданных Cargo и graphviz

    • Подробности можно увидеть:Хотя.Контракт/~Просто тарелка/Протрите…

    • e.g.

      • cargo depgraph --all-deps

      • Можно построить следующий граф зависимости:

image.png

  • cargo bloat

    • нужно пройтиcargo install cargo-bloatУстановить.查找可执行文件中占用存储位置最大的部分

    • Подробности можно увидеть:GitHub.com/RAZR сокол/…

    • e.g.

      • cargo bloat --crates --release
      ❯ cargo bloat --crates --release 
         Compiling bar v0.1.0 (/home/okno/_Workshop/playground/bar)
         Compiling foo v0.1.0 (/home/okno/_Workshop/playground/foo)
          Finished release [optimized] target(s) in 0.47s
          Analyzing target/release/foo
      
      File  .text     Size Crate
      6.0%  92.2% 204.5KiB std
      0.3%   4.0%   8.9KiB rand_chacha
      0.1%   0.9%   2.0KiB getrandom
      0.0%   0.7%   1.6KiB rand
      0.0%   0.1%     230B [Unknown]
      0.0%   0.1%     219B rand_core
      0.0%   0.1%     185B foo
      0.0%   0.0%      68B ppv_lite86
      6.5% 100.0% 221.9KiB .text section size, the file size is 3.3MiB
      
      Note: numbers above are a result of guesswork. They are not 100% correct and never will be.
      

cargo-sonar

В дополнение к этим директивам в еженедельных отчетах 417 упоминается новое расширение Cargo:cargo-sonar. Его можно установить с помощью следующей команды:

cargo install cargo-sonar

Sonar относится к серии SonarQube, SonarCloud, SonarSource и т.д.SonarSourceСтатические инструменты анализа качества кода и безопасности компании поддерживают ряд языков, включая C, C#, Java, Python и т. д. Для получения подробной информации перейдите по этой ссылке:Блог Woohoo.cn на.com/LF Priest/afraid/…

Хотя сообщество ржавчины обеспечивает вилку Sonarqube,sonar-rust, плагин может быть установлен только на стороне сервера и не может использоваться локально.cargo-sonarИспользуйте вывод clippy, затем используйте Sonar для анализа вывода, чтобы получить sonar.json, а затем загрузите только что сгенерированный файл json в sonarcloud.io для анализа результата.

Процесс использования примерно такой:

# 首先使用cargo clippy生成json输出
cargo clippy --all-features --all-targets --message-format=json -- --warn clippy::pedantic > clippy.json
# 使用sonar分析,生成sonar.json
cargo sonar --clippy

использоватьsonar-scannerМожет сканировать sonar.json и генерировать результаты на sonarcloud.io. Пример файла sonar-project.properties программы sonar-scanner выглядит следующим образом:

sonar.organization=woshilapin
sonar.projectKey=woshilapin_cargo-sonar
sonar.projectName=cargo-sonar
sonar.sources=.
sonar.host.url=https://sonarcloud.io
sonar.sourceEncoding=UTF-8
sonar.externalIssuesReportPaths=sonar.json	# 指向之前生成的sonar.json
sonar.login=the_token_of_the_project		# 账号相关 

Для использования sonarcloud.io требуется учетная запись, но анализ проектов с открытым исходным кодом бесплатен.

Кроме того, грузовой сонар также может анализировать выходные данные других грузовых расширений, таких как:

  • cargo-audit
cargo audit --json > audit.json
cargo sonar --audit
  • cargo-deny
cargo deny --format json check 2> deny.json
cargo sonar --deny
  • cargo-outdated
cargo outdated --depth 1 --format json --workspace > outdated.json
cargo sonar --outdated

Оптимизация размера груза и бинарных файлов

Помимо управления пакетами и зависимостями, Cargo также отвечает за компиляцию проекта. Некоторые оптимизации компиляции можно выполнить, настроив файл Cargo.toml, а также параметры времени компиляции. Формат и вид сгенерированной библиотеки, а также сегмент и соответствующий размер результата компиляции в виде динамической библиотеки можно посмотреть в 《Размер скомпилированного двоичного файла Rust и общие оптимизации, который имеет очень подробное объяснение и сравнение с C. Эта глава будет в основном основана на "Optimize Rust binaries size with cargo and Semver", в котором описаны оптимизации компиляции, достижимые с помощью профилей.

Уровень оптимизации

В Cargo.toml вы можете настроитьopt-levelАтрибуты для управления уровнем оптимизации при компиляции rustc. Как правило, чем выше уровень, тем дольше время компиляции.opt-levelсобственность в[profile.dev]Далее его можно установить, изменив Cargo.toml:

[profile.dev]
opt-level = 1               # Use slightly better optimizations.

Cargo будет настраивать профили только на основе Cargo.toml, расположенного в корневом каталоге рабочей области.Настройки Cargo.toml в зависимостях и дочерних крейтах будут игнорироваться, и будут генерироваться предупреждения. Однако настройки в Cargo.toml в корневом каталоге переопределяются переменными среды или определениями конфигурации.

Файл конфигурации можно поместить в текущий каталог крейта, родительский каталог или каталог установки Cargo для настройки текущего крейта, крейтов в родительском каталоге или всех крейтов соответственно. Например, если Cargo находится в пути к файлу/projects/foo/bar/bazВызов, затем CARGO ищет в порядке Config:

  1. /projects/foo/bar/baz/.cargo/config.toml
  2. /projects/foo/bar/.cargo/config.toml
  3. /projects/foo/.cargo/config.toml
  4. /projects/.cargo/config.toml
  5. /.cargo/config.toml
  6. $CARGO_HOME/config.toml
    • Windows: %USERPROFILE%\.cargo\config.toml
    • Unix: $HOME/.cargo/config.toml

Остальные параметры конфига можно посмотретьdoc.rust-wolf.org/cargo/refer…

Необязательные назначения для opt-level:

opt-level описывать Примечание
0 без оптимизации Интенсивность оптимизации растет вместе с цифрами
1 Базовая оптимизация
2 некоторые оптимизации
3 все оптимизации
"s" Оптимизировать размер двоичного файла
"z" Оптимизируйте размер двоичного файла и отключите оптимизацию SIMD для циклических параллельных вычислений.

Остальные настройки профиля видныdoc.rust-wolf.org/cargo/refer…

Прежде чем использовать какую-либо оптимизацию, «Оптимизируйте размер двоичных файлов Rust с помощью Cargo и Semver» исходный размер двоичного пакета:

  • coco: 5.1M
  • cog: 5.7M

Уровень 2 используется по умолчанию.

Используйте уровень s:

  • coco: 5.3M
  • cog: 5.9M

Используйте уровень Z:

  • coco: 5.5M
  • cog: 6.2M

Используйте уровень 1:

  • coco: 9.4M
  • cog: 12M

Используйте уровень 3:

  • coco: 5.1M
  • cog: 5.7M

Тем не менее, opt-level не играет роли в оптимизации бинарного размера для примеров в тексте, хотя может быть полезен для других проектов. Однако в дополнение к opt-level Cargo также предоставляет другие параметры оптимизации компилятора.

Оптимизация времени ссылки

Оптимизация времени компоновки определяет, как серверная часть LLVM оптимизирует размер двоичного файла. Время обменивается на пространство. Чем выше уровень оптимизации, тем больше время компиляции, но меньше размер двоичного пакета. Опять же, это можно установить, изменив Cargo.toml:

[profile.dev]
lto = "fat"

Список необязательных значений параметров выглядит следующим образом:

lto описывать
false Выполнять «тонкий» LTO только на блоке генерации кода текущего крейта. Нет LTO, если единица генерации кода равна 1 или уровень оптимизации равен 0
true / "fat" Выполнить оптимизацию для всех крейтов на графе зависимостей
"thin" Аналогично «жирному», но уравновешивает производительность и время, пытаясь сохранить оптимизированные результаты на одном уровне с настройкой «жирный».
"off" Нет ДН

когдаlto = "fat",opt-level = 3, двоичный размер примера в тексте:

  • coco: 3.0M
  • cog: 3.8M

когдаlto = "fat",opt-level = 2, двоичный размер примера в тексте:

  • coco: 2.9M
  • cog: 3.7M

блок генерации кода

codegen-unitsСвойство определяет количество единиц генерации кода, на которые компилятор разложит крейты, которые будут компилироваться параллельно, но параллельная компиляция может снизить производительность.codegen-unitsДиапазон значений атрибута — целое положительное значение, значение по умолчанию — 256. Чем меньше значение атрибута, тем меньше количество генерируемых единиц и больше время компиляции.

При использовании следующей конфигурации двоичный размер примера в тексте:

[profile.release]
opt-level = 2
lto = "fat"
codegen-units = 1
  • coco: 2.6M
  • cog: 3.6M

Время компиляции увеличилось на 5 секунд, несмотря на меньший размер двоичного файла. Для больших проектов время компиляции может быть больше при использовании оптимизированных настроек.

Повторяющиеся зависимости

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

❯ cargo tree --duplicates -e=no-dev            
num-traits v0.1.43
└── serde-hjson v0.9.1
    └── config v0.11.0
        └── cocogitto v3.0.0 (/home/okno/_Workshop/MyRepos/cocogitto)

num-traits v0.2.14
├── chrono v0.4.19
│   └── cocogitto v3.0.0 (/home/okno/_Workshop/MyRepos/cocogitto)
├── num-integer v0.1.44
│   └── chrono v0.4.19 (*)
└── num-traits v0.1.43 (*)

serde v0.8.23
└── serde-hjson v0.9.1 (*)

serde v1.0.130
├── cocogitto v3.0.0 (/home/okno/_Workshop/MyRepos/cocogitto)
├── config v0.11.0 (*)
├── serde_json v1.0.67
│   └── config v0.11.0 (*)
└── toml v0.5.8
    ├── cocogitto v3.0.0 (/home/okno/_Workshop/MyRepos/cocogitto)
    └── config v0.11.0 (*)

При использованииcargo depgraph --build-deps | dot -Tpng > graph.pngВ результате анализа можно получить следующий график зависимости:

image.png

как на фотоserde-hjsonЗависимости, отмеченные пунктирными линиями, являются необязательными и могут быть удалены путем отключения функции Cargo без ущерба для общей функциональности. Функции, включенные по умолчанию в конфигурации, включают:toml,json,yaml,hjson,ini; Эти функции груза можно отключить, изменив функции конфигурации:

config = { version = "^0", default-features = false, features = ["toml"] }

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

[dependencies]
rand = "^0.7" # crate requirement: >=0.7.0, <0.8.0

Измененный двоичный размер:

  • coco: 2.3M
  • cog: 3.1M

удалить конечные байты

Символы объектного файла двоичного файла — это метаданные, используемые для связывания или отладки, такие как информация для разрешения перекрестных ссылок символов между различными модулями, информация о перемещении, информация о раскручивании стека, комментарии, программные символы, информация об отладке или профилировании. Другие метаданные могут включать дату и время компиляции, имя и версию компилятора и другую идентифицирующую информацию. Хотя обычно это не рекомендуется, если вы хотите ограничить размер сжатых двоичных файлов, вы можете использовать программы unix.stripУдалить эти символы:

strip -S cog
strip -S coco

После удаления голый двоичный размер:

  • coco: 1.1M
  • cog: 1.5M

Цитировать

Грузовая книга,doc.rust-wolf.org/cargo/index…

10 лучших команд Rust Cargo,Я тоже на Dev.to/David A…

грузовой гидролокатор,hole.rabbithouse.info/cargo-sonar…

Оптимизировать размер исполняемых файлов Rust с помощью Cargo и Semver,ОК, нет, или GitHub.IO/blog/op kick m…  

Запуск ящиков Rust для удовольствия и прибыли,Доступно на rust.com/rust-crate-…

Rust скомпилировал двоичный размер и общие методы оптимизации,журнал ржавчины.GitHub.IO/rust_magazi…