513 lines
56 KiB
HTML
513 lines
56 KiB
HTML
<!DOCTYPE HTML>
|
||
<html lang="en" class="coal" dir="ltr">
|
||
<head>
|
||
<!-- Book generated using mdBook -->
|
||
<meta charset="UTF-8">
|
||
<title>compress rust binary size - Andrew's Blog</title>
|
||
|
||
|
||
<!-- Custom HTML head -->
|
||
|
||
<meta name="description" content="Andrew Ryan's Blog">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<meta name="theme-color" content="#ffffff">
|
||
|
||
<link rel="icon" href="../../favicon.svg">
|
||
<link rel="shortcut icon" href="../../favicon.png">
|
||
<link rel="stylesheet" href="../../css/variables.css">
|
||
<link rel="stylesheet" href="../../css/general.css">
|
||
<link rel="stylesheet" href="../../css/chrome.css">
|
||
|
||
<!-- Fonts -->
|
||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||
|
||
<!-- Highlight.js Stylesheets -->
|
||
<link rel="stylesheet" href="../../highlight.css">
|
||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||
|
||
<!-- Custom theme stylesheets -->
|
||
<link rel="stylesheet" href="../../src/style/custom.css">
|
||
|
||
<!-- MathJax -->
|
||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||
</head>
|
||
<body class="sidebar-visible no-js">
|
||
<div id="body-container">
|
||
<!-- Provide site root to javascript -->
|
||
<script>
|
||
var path_to_root = "../../";
|
||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "coal" : "coal";
|
||
</script>
|
||
|
||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||
<script>
|
||
try {
|
||
var theme = localStorage.getItem('mdbook-theme');
|
||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||
|
||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||
}
|
||
|
||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||
}
|
||
} catch (e) { }
|
||
</script>
|
||
|
||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||
<script>
|
||
var theme;
|
||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||
var html = document.querySelector('html');
|
||
html.classList.remove('coal')
|
||
html.classList.add(theme);
|
||
var body = document.querySelector('body');
|
||
body.classList.remove('no-js')
|
||
body.classList.add('js');
|
||
</script>
|
||
|
||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||
|
||
<!-- Hide / unhide sidebar before it is displayed -->
|
||
<script>
|
||
var body = document.querySelector('body');
|
||
var sidebar = null;
|
||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||
if (document.body.clientWidth >= 1080) {
|
||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||
sidebar = sidebar || 'visible';
|
||
} else {
|
||
sidebar = 'hidden';
|
||
}
|
||
sidebar_toggle.checked = sidebar === 'visible';
|
||
body.classList.remove('sidebar-visible');
|
||
body.classList.add("sidebar-" + sidebar);
|
||
</script>
|
||
|
||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||
<div class="sidebar-scrollbox">
|
||
<ol class="chapter"><li class="chapter-item affix "><a href="../../index.html">Andrew's Blog</a></li><li class="chapter-item "><a href="../../posts/linux/linux.html"><strong aria-hidden="true">1.</strong> linux</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/linux/install_linux.html"><strong aria-hidden="true">1.1.</strong> install linux</a></li><li class="chapter-item "><a href="../../posts/linux/bash_profile.html"><strong aria-hidden="true">1.2.</strong> bash profile</a></li><li class="chapter-item "><a href="../../posts/linux/command_list.html"><strong aria-hidden="true">1.3.</strong> command list</a></li><li class="chapter-item "><a href="../../posts/linux/git_guide.html"><strong aria-hidden="true">1.4.</strong> git guide</a></li><li class="chapter-item "><a href="../../posts/linux/tar.html"><strong aria-hidden="true">1.5.</strong> tar</a></li><li class="chapter-item "><a href="../../posts/linux/run_x86_elf_in_x64_setup.html"><strong aria-hidden="true">1.6.</strong> run x86 elf in x64 setup</a></li></ol></li><li class="chapter-item "><a href="../../posts/mac/mac.html"><strong aria-hidden="true">2.</strong> mac</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/mac/macos_profiles.html"><strong aria-hidden="true">2.1.</strong> macos profiles</a></li></ol></li><li class="chapter-item "><a href="../../posts/swift/swift.html"><strong aria-hidden="true">3.</strong> swift</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/swift/learn_swift.html"><strong aria-hidden="true">3.1.</strong> learn swift basics</a></li><li class="chapter-item "><a href="../../posts/swift/swift_extensions.html"><strong aria-hidden="true">3.2.</strong> Swift extensions</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_extension.html"><strong aria-hidden="true">3.3.</strong> SwiftUI extensions</a></li><li class="chapter-item "><a href="../../posts/swift/install_swift.html"><strong aria-hidden="true">3.4.</strong> install swift</a></li><li class="chapter-item "><a href="../../posts/swift/task_planner.html"><strong aria-hidden="true">3.5.</strong> implment task panner app with SwiftUI</a></li><li class="chapter-item "><a href="../../posts/swift/swift_cheat_sheet.html"><strong aria-hidden="true">3.6.</strong> Swift Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/swift/yinci_url.html"><strong aria-hidden="true">3.7.</strong> Personal privacy protocol</a></li><li class="chapter-item "><a href="../../posts/swift/swift_regular_exressions.html"><strong aria-hidden="true">3.8.</strong> Swift regular exressions</a></li><li class="chapter-item "><a href="../../posts/ios/how_to_create_beautiful_ios_charts_in_swift.html"><strong aria-hidden="true">3.9.</strong> How to Create Beautiful iOS Charts in鑱絊wift</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_source_code.html"><strong aria-hidden="true">3.10.</strong> SwiftUI source code</a></li><li class="chapter-item "><a href="../../posts/swift/use_swift_fetch_iciba_api.html"><strong aria-hidden="true">3.11.</strong> use swift fetch iciba API</a></li></ol></li><li class="chapter-item "><a href="../../posts/ios/ios.html"><strong aria-hidden="true">4.</strong> ios</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ios/cocaposd_setup_and_install_for_ios_project.html"><strong aria-hidden="true">4.1.</strong> cocaposd setup and install for ios project</a></li><li class="chapter-item "><a href="../../posts/ios/swiftui_show_gif_image.html"><strong aria-hidden="true">4.2.</strong> SwiftUI show gif image</a></li><li class="chapter-item "><a href="../../posts/ios/implement_task_planner_app.html"><strong aria-hidden="true">4.3.</strong> implement Task planner App</a></li></ol></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c.html"><strong aria-hidden="true">5.</strong> objective_c</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/objective_c/objective_c_cheat_sheet.html"><strong aria-hidden="true">5.1.</strong> Objective-C Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c_for_absolute_beginners_read_note.html"><strong aria-hidden="true">5.2.</strong> Objective-C Note</a></li></ol></li><li class="chapter-item "><a href="../../posts/dart/dart.html"><strong aria-hidden="true">6.</strong> dart</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/dart/flutter.html"><strong aria-hidden="true">6.1.</strong> Flutter Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/dart/dart_cheat_sheet.html"><strong aria-hidden="true">6.2.</strong> Dart Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/flutter/flutter_dev_test.html"><strong aria-hidden="true">6.3.</strong> Flutter dev test</a></li></ol></li><li class="chapter-item expanded "><a href="../../posts/rust/rust.html"><strong aria-hidden="true">7.</strong> rust</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/rust/offline_use_rust.html"><strong aria-hidden="true">7.1.</strong> Offline use rust</a></li><li class="chapter-item "><a href="../../posts/rust/rust_grammer.html"><strong aria-hidden="true">7.2.</strong> rust grammar</a></li><li class="chapter-item "><a href="../../posts/rust/pase_string_and_decimal_conversion.html"><strong aria-hidden="true">7.3.</strong> pase string and decimal conversion</a></li><li class="chapter-item "><a href="../../posts/rust/parse_types.html"><strong aria-hidden="true">7.4.</strong> rust types</a></li><li class="chapter-item "><a href="../../posts/rust/rust_life_cycle.html"><strong aria-hidden="true">7.5.</strong> Rust life cycle</a></li><li class="chapter-item "><a href="../../posts/rust/rust_generic.html"><strong aria-hidden="true">7.6.</strong> rust generics</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implment_matrix.html"><strong aria-hidden="true">7.7.</strong> Rust implement matrix</a></li><li class="chapter-item "><a href="../../posts/rust/rust_sort.html"><strong aria-hidden="true">7.8.</strong> Rust implement sort algorithms</a></li><li class="chapter-item "><a href="../../posts/rust/implement_aes_encryption.html"><strong aria-hidden="true">7.9.</strong> Rust implement AEC encryption and decryption</a></li><li class="chapter-item "><a href="../../posts/rust/implement_trie_data_structure.html"><strong aria-hidden="true">7.10.</strong> implement trie data structure</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_tree.html"><strong aria-hidden="true">7.11.</strong> implement tree data_structure</a></li><li class="chapter-item "><a href="../../posts/rust/list_dir.html"><strong aria-hidden="true">7.12.</strong> list dir</a></li><li class="chapter-item "><a href="../../posts/rust/fast_way_to_implment_object_trait.html"><strong aria-hidden="true">7.13.</strong> fast way to implment object trait</a></li><li class="chapter-item expanded "><a href="../../posts/rust/compress_rust_binary_size.html" class="active"><strong aria-hidden="true">7.14.</strong> compress rust binary size</a></li><li class="chapter-item "><a href="../../posts/rust/implment_file_upload_backend.html"><strong aria-hidden="true">7.15.</strong> impliment file upload</a></li><li class="chapter-item "><a href="../../posts/rust/this_is_add_post_cli_implementation_in_rust.html"><strong aria-hidden="true">7.16.</strong> this is add_post cli implementation in rust</a></li><li class="chapter-item "><a href="../../posts/rust/use_rust_implment_a_copyclipbord_cli.html"><strong aria-hidden="true">7.17.</strong> Use rust implment a copyclipbord CLI</a></li><li class="chapter-item "><a href="../../posts/rust/sqlite_database_add_delete_update_show_in_rust.html"><strong aria-hidden="true">7.18.</strong> sqlite database add delete update show in rust</a></li><li class="chapter-item "><a href="../../posts/rust/implementing_tokio_joinhandle_for_wasm.html"><strong aria-hidden="true">7.19.</strong> Implementing tokio JoinHandle for wasm</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_a_crate_for_encode_and_decode_brainfuck_and_ook.html"><strong aria-hidden="true">7.20.</strong> rust implement a crate for encode and decode brainfuck and ook</a></li><li class="chapter-item "><a href="../../posts/rust/slint_builtin_elements.html"><strong aria-hidden="true">7.21.</strong> Slint Builtin Elements</a></li><li class="chapter-item "><a href="../../posts/rust/corporate_network_install_rust_on_windows.html"><strong aria-hidden="true">7.22.</strong> Corporate network install Rust on windows</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_file_how_to_judge_static_link_or_dynamic_link_in_macos.html"><strong aria-hidden="true">7.23.</strong> rust binary file how to judge static link or dynamic link in Macos</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_include_dir_and_get_contents.html"><strong aria-hidden="true">7.24.</strong> rust binary include dir and get contents</a></li><li class="chapter-item "><a href="../../posts/rust/rust_logger_non-block.html"><strong aria-hidden="true">7.25.</strong> rust logger non-block</a></li><li class="chapter-item "><a href="../../posts/rust/rust_connect_sql_server_database.html"><strong aria-hidden="true">7.26.</strong> rust connect sql server database</a></li><li class="chapter-item "><a href="../../posts/rust/rust_websocket_implment.html"><strong aria-hidden="true">7.27.</strong> rust websocket implment</a></li></ol></li><li class="chapter-item "><a href="../../posts/java/java.html"><strong aria-hidden="true">8.</strong> java</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/java/java_grammar.html"><strong aria-hidden="true">8.1.</strong> java grammar and codewar</a></li><li class="chapter-item "><a href="../../posts/java/run_jar.html"><strong aria-hidden="true">8.2.</strong> java run .jar</a></li><li class="chapter-item "><a href="../../posts/java/java_pomxml_add_defaultgoal_to_build.html"><strong aria-hidden="true">8.3.</strong> Java pomxml add defaultGoal to build</a></li><li class="chapter-item "><a href="../../posts/java/java_set_mvn_mirror.html"><strong aria-hidden="true">8.4.</strong> Java set mvn mirror</a></li></ol></li><li class="chapter-item "><a href="../../posts/python/python.html"><strong aria-hidden="true">9.</strong> python</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/python/convert_pesn.html"><strong aria-hidden="true">9.1.</strong> convert pesn</a></li><li class="chapter-item "><a href="../../posts/python/find_remove_dir.html"><strong aria-hidden="true">9.2.</strong> find and remove dir</a></li><li class="chapter-item "><a href="../../posts/python/timing_message.html"><strong aria-hidden="true">9.3.</strong> wechat send message</a></li><li class="chapter-item "><a href="../../posts/python/use_python_openpyxl_package_read_and_edit_excel_files.html"><strong aria-hidden="true">9.4.</strong> Use python openpyxl package read and edit excel files</a></li></ol></li><li class="chapter-item "><a href="../../posts/go/go.html"><strong aria-hidden="true">10.</strong> go</a></li><li class="chapter-item "><a href="../../posts/js/js.html"><strong aria-hidden="true">11.</strong> js</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/js/js_tutorial.html"><strong aria-hidden="true">11.1.</strong> js tutorial</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_map.html"><strong aria-hidden="true">11.2.</strong> ja map</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_math.html"><strong aria-hidden="true">11.3.</strong> js math</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_object.html"><strong aria-hidden="true">11.4.</strong> js object</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_set.html"><strong aria-hidden="true">11.5.</strong> js set</a></li><li class="chapter-item "><a href="../../posts/js/single_thread_and_asynchronous.html"><strong aria-hidden="true">11.6.</strong> single thread and asynchronous</a></li><li class="chapter-item "><a href="../../posts/js/this.html"><strong aria-hidden="true">11.7.</strong> js this</a></li><li class="chapter-item "><a href="../../posts/js/js_implment_aes.html"><strong aria-hidden="true">11.8.</strong> js implment aes</a></li><li class="chapter-item "><a href="../../posts/js/getting_started_with_ajax.html"><strong aria-hidden="true">11.9.</strong> getting started with ajax</a></li><li class="chapter-item "><a href="../../posts/js/BinarySearchTree.html"><strong aria-hidden="true">11.10.</strong> binary search tree</a></li><li class="chapter-item "><a href="../../posts/js/goole_zx.html"><strong aria-hidden="true">11.11.</strong> goole zx</a></li><li class="chapter-item "><a href="../../posts/js/es6.html"><strong aria-hidden="true">11.12.</strong> es6</a></li></ol></li><li class="chapter-item "><a href="../../posts/ruby/ruby.html"><strong aria-hidden="true">12.</strong> ruby</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ruby/rails_setup_env.html"><strong aria-hidden="true">12.1.</strong> ruby on rails setup environment</a></li><li class="chapter-item "><a href="../../posts/ruby/learn_ruby.html"><strong aria-hidden="true">12.2.</strong> learn ruby</a></li><li class="chapter-item "><a href="../../posts/ruby/ruby_note.html"><strong aria-hidden="true">12.3.</strong> Ruby Note</a></li><li class="chapter-item "><a href="../../posts/ruby/setup_ruby_for_ctf.html"><strong aria-hidden="true">12.4.</strong> Setup ruby for CTF</a></li></ol></li><li class="chapter-item "><a href="../../posts/react/react.html"><strong aria-hidden="true">13.</strong> react</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/react/react_life_cycle.html"><strong aria-hidden="true">13.1.</strong> react life cycle</a></li><li class="chapter-item "><a href="../../posts/react/react_router.html"><strong aria-hidden="true">13.2.</strong> react router</a></li><li class="chapter-item "><a href="../../posts/react/react_this.html"><strong aria-hidden="true">13.3.</strong> react this</a></li><li class="chapter-item "><a href="../../posts/react/react_interviw.html"><strong aria-hidden="true">13.4.</strong> react interview</a></li><li class="chapter-item "><a href="../../posts/react/important_react_interview.html"><strong aria-hidden="true">13.5.</strong> important react interview</a></li><li class="chapter-item "><a href="../../posts/react/react_quick_reference.html"><strong aria-hidden="true">13.6.</strong> react quick reference</a></li><li class="chapter-item "><a href="../../posts/react/redux_quick_reference.html"><strong aria-hidden="true">13.7.</strong> redux quick reference</a></li></ol></li><li class="chapter-item "><a href="../../posts/vue/vue.html"><strong aria-hidden="true">14.</strong> vue</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/vue/vue_ajax.html"><strong aria-hidden="true">14.1.</strong> vue ajax</a></li></ol></li><li class="chapter-item "><a href="../../posts/angular/angular.html"><strong aria-hidden="true">15.</strong> angular</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/angular/controller_communication.html"><strong aria-hidden="true">15.1.</strong> controller communication</a></li><li class="chapter-item "><a href="../../posts/angular/creating_custom_directives.html"><strong aria-hidden="true">15.2.</strong> creating custom directives</a></li><li class="chapter-item "><a href="../../posts/angular/directive_notes.html"><strong aria-hidden="true">15.3.</strong> directive notes</a></li><li class="chapter-item "><a href="../../posts/angular/directive_communication.html"><strong aria-hidden="true">15.4.</strong> directive communication</a></li><li class="chapter-item "><a href="../../posts/angular/post_params.html"><strong aria-hidden="true">15.5.</strong> post params</a></li><li class="chapter-item "><a href="../../posts/angular/read_json_angular.html"><strong aria-hidden="true">15.6.</strong> read json angular</a></li><li class="chapter-item "><a href="../../posts/angular/same_route_reload.html"><strong aria-hidden="true">15.7.</strong> same route reload</a></li></ol></li><li class="chapter-item "><a href="../../posts/css/css.html"><strong aria-hidden="true">16.</strong> css</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/css/use_css_media.html"><strong aria-hidden="true">16.1.</strong> use css media</a></li></ol></li><li class="chapter-item "><a href="../../posts/php/php.html"><strong aria-hidden="true">17.</strong> php</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/php/for_php_string_implment_some_extemtion_functions.html"><strong aria-hidden="true">17.1.</strong> for php string implment some extemtion functions</a></li><li class="chapter-item "><a href="../../posts/php/php_cheatsheet.html"><strong aria-hidden="true">17.2.</strong> PHP cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/leetcode/leetcode.html"><strong aria-hidden="true">18.</strong> leetcode</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/leetcode/rust_leetcode.html"><strong aria-hidden="true">18.1.</strong> rust leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_codewar.html"><strong aria-hidden="true">18.2.</strong> rust codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/swift_codewar.html"><strong aria-hidden="true">18.3.</strong> swift codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/js_leetcode.html"><strong aria-hidden="true">18.4.</strong> js leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/java_leetcode.html"><strong aria-hidden="true">18.5.</strong> java leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_huawei.html"><strong aria-hidden="true">18.6.</strong> huawei test</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_utils.html"><strong aria-hidden="true">18.7.</strong> rust common functions</a></li><li class="chapter-item "><a href="../../posts/leetcode/olympiad_training.html"><strong aria-hidden="true">18.8.</strong> Computer olympiad training</a></li></ol></li><li class="chapter-item "><a href="../../posts/ctf/CTF.html"><strong aria-hidden="true">19.</strong> ctf</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ctf/CTF_Note.html"><strong aria-hidden="true">19.1.</strong> CTF Note</a></li><li class="chapter-item "><a href="../../posts/ctf/0.1_Web.html"><strong aria-hidden="true">19.2.</strong> Web</a></li><li class="chapter-item "><a href="../../posts/ctf/4.1_Misc.html"><strong aria-hidden="true">19.3.</strong> Misc</a></li><li class="chapter-item "><a href="../../posts/ctf/3.2_PWN_note.html"><strong aria-hidden="true">19.4.</strong> PWN</a></li><li class="chapter-item "><a href="../../posts/ctf/3.1_Crypto.html"><strong aria-hidden="true">19.5.</strong> Crypto</a></li><li class="chapter-item "><a href="../../posts/ctf/3.4_RSA_note.html"><strong aria-hidden="true">19.6.</strong> Rsa attack</a></li><li class="chapter-item "><a href="../../posts/ctf/3.5_Base64.html"><strong aria-hidden="true">19.7.</strong> Base64</a></li><li class="chapter-item "><a href="../../posts/ctf/0.0_SQL Injection Cheatsheet.html"><strong aria-hidden="true">19.8.</strong> SQL Injection Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/ctf/1.1_SQL_injection.html"><strong aria-hidden="true">19.9.</strong> SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.2_SQL_injection_UNION_attacks.html"><strong aria-hidden="true">19.10.</strong> SQL Injection UNION attacks</a></li><li class="chapter-item "><a href="../../posts/ctf/1.3_Blind SQL injection.html"><strong aria-hidden="true">19.11.</strong> Blind SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.4_Code Injection.html"><strong aria-hidden="true">19.12.</strong> Code Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.5_SSRF.html"><strong aria-hidden="true">19.13.</strong> SSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.6_OS command injection.html"><strong aria-hidden="true">19.14.</strong> OS command injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.7_Local file inclusion.html"><strong aria-hidden="true">19.15.</strong> Local file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.8_Remote file inclusion.html"><strong aria-hidden="true">19.16.</strong> Remote file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.9_CSRFm.html"><strong aria-hidden="true">19.17.</strong> CSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.10_NoSQL injection.html"><strong aria-hidden="true">19.18.</strong> NoSQL injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.11_JSON injection.html"><strong aria-hidden="true">19.19.</strong> JSON injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.12_CTF_Web_SQL_Note.html"><strong aria-hidden="true">19.20.</strong> CTF Web SQL Note</a></li><li class="chapter-item "><a href="../../posts/ctf/2.1_XXE.html"><strong aria-hidden="true">19.21.</strong> XXE</a></li><li class="chapter-item "><a href="../../posts/ctf/2.2_XSS.html"><strong aria-hidden="true">19.22.</strong> XSS</a></li><li class="chapter-item "><a href="../../posts/ctf/2.3_Upload File.html"><strong aria-hidden="true">19.23.</strong> Upload File</a></li><li class="chapter-item "><a href="../../posts/ctf/2.4_serialize_unserialize.html"><strong aria-hidden="true">19.24.</strong> serialize unserialize</a></li><li class="chapter-item "><a href="../../posts/ctf/2.5_Race condition.html"><strong aria-hidden="true">19.25.</strong> Race condition</a></li><li class="chapter-item "><a href="../../posts/ctf/3.2_PWN_note.html"><strong aria-hidden="true">19.26.</strong> PWN_note</a></li><li class="chapter-item "><a href="../../posts/ctf/3.3_pwn HCTF2016 brop.html"><strong aria-hidden="true">19.27.</strong> pwn HCTF2016 brop</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_patch_defense_skill.html"><strong aria-hidden="true">19.28.</strong> PWN Patch defense skill</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_stack_overflow.html"><strong aria-hidden="true">19.29.</strong> PWN stack overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_heap_overflow.html"><strong aria-hidden="true">19.30.</strong> PWN heap overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_format_string_vulnerability.html"><strong aria-hidden="true">19.31.</strong> PWN Format String Vulnerability</a></li><li class="chapter-item "><a href="../../posts/ctf/kali_linux_tutorials.html"><strong aria-hidden="true">19.32.</strong> Kali linux tutorials</a></li><li class="chapter-item "><a href="../../posts/ctf/google_dorks_2023_lists.html"><strong aria-hidden="true">19.33.</strong> Google Dorks 2023 Lists</a></li><li class="chapter-item "><a href="../../posts/ctf/dvwa_writeup.html"><strong aria-hidden="true">19.34.</strong> DVWA WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/bwapp_writeup.html"><strong aria-hidden="true">19.35.</strong> bWAPP WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/sqlilabs_writeup.html"><strong aria-hidden="true">19.36.</strong> sqlilabs WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/ctf_train_at_hangzhou.html"><strong aria-hidden="true">19.37.</strong> ctf train at hangzhou</a></li><li class="chapter-item "><a href="../../posts/ctf/ctf_common_mindmap_list.html"><strong aria-hidden="true">19.38.</strong> ctf common mindmap list</a></li><li class="chapter-item "><a href="../../posts/ctf/error_based_sql_injection.html"><strong aria-hidden="true">19.39.</strong> Error Based SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/urlfinder_tutorial.html"><strong aria-hidden="true">19.40.</strong> URLFinder Tutorial</a></li><li class="chapter-item "><a href="../../posts/ctf/observer_ward_tutorial.html"><strong aria-hidden="true">19.41.</strong> observer_ward Tutorial</a></li><li class="chapter-item "><a href="../../posts/ctf/mysql_udf_.html"><strong aria-hidden="true">19.42.</strong> MySQL UDF 提权</a></li><li class="chapter-item "><a href="../../posts/ctf/nuclei__tutorial.html"><strong aria-hidden="true">19.43.</strong> Nuclei Tutorial</a></li><li class="chapter-item "><a href="../../posts/ctf/2024_ctf_solution_thinking.html"><strong aria-hidden="true">19.44.</strong> 2024 ctf solution thinking</a></li><li class="chapter-item "><a href="../../posts/ctf/man_che_si_te_bian_ma.html"><strong aria-hidden="true">19.45.</strong> 曼彻斯特编码</a></li></ol></li></ol>
|
||
</div>
|
||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||
<div class="sidebar-resize-indicator"></div>
|
||
</div>
|
||
</nav>
|
||
|
||
<!-- Track and set sidebar scroll position -->
|
||
<script>
|
||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||
sidebarScrollbox.addEventListener('click', function(e) {
|
||
if (e.target.tagName === 'A') {
|
||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||
}
|
||
}, { passive: true });
|
||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||
sessionStorage.removeItem('sidebar-scroll');
|
||
if (sidebarScrollTop) {
|
||
// preserve sidebar scroll position when navigating via links within sidebar
|
||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||
} else {
|
||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||
var activeSection = document.querySelector('#sidebar .active');
|
||
if (activeSection) {
|
||
activeSection.scrollIntoView({ block: 'center' });
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<div id="page-wrapper" class="page-wrapper">
|
||
|
||
<div class="page">
|
||
<div id="menu-bar-hover-placeholder"></div>
|
||
<div id="menu-bar" class="menu-bar sticky">
|
||
<div class="left-buttons">
|
||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||
<i class="fa fa-bars"></i>
|
||
</label>
|
||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||
<i class="fa fa-paint-brush"></i>
|
||
</button>
|
||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||
</ul>
|
||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||
<i class="fa fa-search"></i>
|
||
</button>
|
||
</div>
|
||
|
||
<h1 class="menu-title">Andrew's Blog</h1>
|
||
|
||
<div class="right-buttons">
|
||
<a href="https://gitlink.org.cn/dnrops/dnrops.gitlink.net.git" title="Git repository" aria-label="Git repository">
|
||
<i id="git-repository-button" class="fa fa-github"></i>
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div id="search-wrapper" class="hidden">
|
||
<form id="searchbar-outer" class="searchbar-outer">
|
||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||
</form>
|
||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||
<div id="searchresults-header" class="searchresults-header"></div>
|
||
<ul id="searchresults">
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||
<script>
|
||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||
});
|
||
</script>
|
||
|
||
<div id="content" class="content">
|
||
<main>
|
||
<h1 id="optimize-rust-compilation-binary-size"><a class="header" href="#optimize-rust-compilation-binary-size">optimize rust compilation binary size</a></h1>
|
||
<h2 id="1install-cargo-bloat"><a class="header" href="#1install-cargo-bloat">1.install cargo-bloat</a></h2>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>cargo install cargo-bloat
|
||
yay -S strip
|
||
yay -S upx
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<h2 id="2cargotoml-add-profilerelease"><a class="header" href="#2cargotoml-add-profilerelease">2.Cargo.toml add profile.release</a></h2>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>[profile.release]
|
||
opt-level = 'z'
|
||
lto = true
|
||
codegen-units = 1
|
||
panic = 'abort'
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<h2 id="3run-releasesh"><a class="header" href="#3run-releasesh">3.run release.sh</a></h2>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>cargo bloat --release --crates
|
||
cargo build --release
|
||
strip -s target/release/codewar
|
||
upx -9 target/release/codewar
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<h1 id="优化-rust-程序编译体积"><a class="header" href="#优化-rust-程序编译体积">优化 Rust 程序编译体积</a></h1>
|
||
<p>Rust 发生了许多变化,比如不再自带 Jemalloc 作为内存分配器。因此更新一下文章,参考了一个新项目
|
||
<a href="https://github.com/johnthagen/min-sized-rust">min-sized-rust</a> 进行了更多的优化。
|
||
首先记录一下编译器版本</p>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>rustc --version
|
||
rustc 1.60.0-nightly (17d29dcdc 2022-01-21)
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<p>这次不再采用 Hello,world 作为演示了,因为本身就没多少代码参考意义不大,本文的目的不是探究一个 Rust 程序能做到多小,而是一个<strong>实际的</strong>
|
||
Rust 项目可以优化到多小。
|
||
翻了一下以前的项目,决定使用 <a href="https://github.com/Aloxaf/ren3/">ren3</a>
|
||
作为优化对象:规模恰到好处,有足够的代码,又没有太多依赖。
|
||
<em>那么,开始我们的 Optimization 吧!</em></p>
|
||
<h1 id="使用-release-构建"><a class="header" href="#使用-release-构建">使用 Release 构建</a></h1>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>cargo build --release
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<p>最基本的优化体积方式之一,大家都懂的。Cargo 默认的编译模式是 dev ,该下没有进行任何优化,而且附带了大量调试信息。dev
|
||
模式下的程序别说几十兆,上百兆都是有可能的……</p>
|
||
<div class="table-wrapper"><table><thead><tr><th>编译模式</th><th>体积</th><th>减少量</th></tr></thead><tbody>
|
||
<tr><td>dev</td><td>26.5M</td><td>100%</td></tr>
|
||
<tr><td>release</td><td>4.70M</td><td>17.7%</td></tr>
|
||
<tr><td>可以看到 dev 和 release 两者差距非常大,没有特殊说明的话,后文就采用 release 模式下的 4.70M 作为基准来进行对比了</td><td></td><td></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h1 id="使用-strip"><a class="header" href="#使用-strip">使用 strip</a></h1>
|
||
<pre><code class="language-sh">strip -s target/release/ren3
|
||
</code></pre>
|
||
<p>最基本的优化体积方式之二,可以去除(对正常运行)无用的符号信息</p>
|
||
<div class="table-wrapper"><table><thead><tr><th>优化方式</th><th>体积</th><th>减少量</th></tr></thead><tbody>
|
||
<tr><td>无</td><td>4.70M</td><td>100%</td></tr>
|
||
<tr><td>strip</td><td>2.11M</td><td>44.9%</td></tr>
|
||
<tr><td>效果同样非常明显,直接减少了一半。</td><td></td><td></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h1 id="调整优化等级"><a class="header" href="#调整优化等级">调整优化等级</a></h1>
|
||
<p><a href="https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections">默认的 release 优化等级为 3</a>,这个等级下编译器会进行循环展开之类的操作以体积膨胀为代价提高程序运行速度。不过这次我们在优化体积,我们不需要以体积为代价的优化。因为我们调整优化等级为
|
||
<code>z</code>,意为最小二进制体积:</p>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>[profile.release]
|
||
opt-level = 'z'
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<div class="table-wrapper"><table><thead><tr><th>优化方式</th><th>体积</th><th>变化</th></tr></thead><tbody>
|
||
<tr><td>无</td><td>4.70M</td><td>100%</td></tr>
|
||
<tr><td>strip</td><td>2.11M</td><td>44.9%</td></tr>
|
||
<tr><td><code>opt-level = 'z'</code></td><td>4.84M</td><td>103%</td></tr>
|
||
<tr><td><code>opt-level = 'z'</code> + strip</td><td>1.96M</td><td>41.7%</td></tr>
|
||
<tr><td>emmm 非常尴尬的是未 strip 时的体积竟然略有增加,不过 strip 后体积确实再次减少了一点点,聊胜于无吧。</td><td></td><td></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h1 id="开启-lto"><a class="header" href="#开启-lto">开启 LTO</a></h1>
|
||
<p>LTO(Link Time Optimization),意为链接时优化。可以消除大量冗余代码,减小二进制体积——代价是更长的链接时间</p>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>[profile.release]
|
||
lto = true
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<div class="table-wrapper"><table><thead><tr><th>优化方式</th><th>体积</th><th>变化</th></tr></thead><tbody>
|
||
<tr><td>无</td><td>4.70M</td><td>100%</td></tr>
|
||
<tr><td>strip</td><td>2.11M</td><td>44.9%</td></tr>
|
||
<tr><td><code>opt-level = 'z'</code></td><td>4.84M</td><td>103%</td></tr>
|
||
<tr><td><code>opt-level = 'z'</code> + strip</td><td>1.96M</td><td>41.7%</td></tr>
|
||
<tr><td><code>opt-level = 'z'</code> + LTO</td><td>2.79M</td><td>59.4%</td></tr>
|
||
<tr><td><code>opt-level = 'z'</code> + LTO + strip</td><td>1.56M</td><td>33.2%</td></tr>
|
||
<tr><td>体积减小非常明显!</td><td></td><td></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h1 id="调整并行代码生成单元数量"><a class="header" href="#调整并行代码生成单元数量">调整并行代码生成单元数量</a></h1>
|
||
<p>Cargo 默认会启用 16 个并行代码生成单元,对编译速度有提升,但是会妨碍某些优化的进行。我们限制到 1:</p>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>[profile.release]
|
||
codegen-units = 1
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<div class="table-wrapper"><table><thead><tr><th>优化方式</th><th>体积</th><th>变化</th></tr></thead><tbody>
|
||
<tr><td>无</td><td>4.70M</td><td>100%</td></tr>
|
||
<tr><td>strip</td><td>2.11M</td><td>44.9%</td></tr>
|
||
<tr><td>前文步骤</td><td>2.79M</td><td>59.4%</td></tr>
|
||
<tr><td>前文步骤 + strip</td><td>1.56M</td><td>33.2%</td></tr>
|
||
<tr><td>前文步骤 + <code>codegen-units = 1</code></td><td>2.62M</td><td>55.7%</td></tr>
|
||
<tr><td>前文步骤 + <code>codegen-units = 1</code> + strip</td><td>1.49M</td><td>31.7%</td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h1 id="panic-时立刻终止"><a class="header" href="#panic-时立刻终止">Panic 时立刻终止</a></h1>
|
||
<blockquote>
|
||
<p><strong>前面的优化对程序的行为都不会产生任何影响,然而这个优化会。</strong>
|
||
众所周知,Rust 程序在 panic 时会生成栈回溯,方便定位问题。而这个 flag 会禁用这种行为——请自行权衡使用。</p>
|
||
</blockquote>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>[profile.release]
|
||
panic = 'abort'
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<div class="table-wrapper"><table><thead><tr><th>编译方式</th><th>优化方式</th><th>体积</th><th>变化</th></tr></thead><tbody>
|
||
<tr><td>release</td><td>无</td><td>4.70M</td><td>100%</td></tr>
|
||
<tr><td>release</td><td>strip</td><td>2.11M</td><td>44.9%</td></tr>
|
||
<tr><td>release</td><td>前文步骤</td><td>2.62M</td><td>55.7%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + strip</td><td>1.49M</td><td>31.7%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + <code>panic = 'abort'</code></td><td>2.44M</td><td>52.0%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + <code>panic = 'abort'</code> + strip</td><td>1.40M</td><td>29.8%</td></tr>
|
||
<tr><td>又减小了一点点</td><td></td><td></td><td></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h1 id="最小化依赖"><a class="header" href="#最小化依赖">最小化依赖</a></h1>
|
||
<blockquote>
|
||
<p>上面的优化都是只用调整参数就能完成的优化,然而这个优化可能需要你改动源码 但是,如果做方法得当的话,这个可能会是<strong>效果最明显的方式</strong>
|
||
Rust 的中心化包管理系统用起来爽到不行,但是用外部库用起来太方便也带来了一个问题:一个小程序动不动就会带上上百个依赖……这体积怎么可能不大嘛
|
||
所以最小化你的依赖也是一个减小体积的重要方式
|
||
先看一下这个项目当前的依赖:</p>
|
||
</blockquote>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>[dependencies]
|
||
regex = "1.3.1"
|
||
clap = { version = "2.33.0", features = ["yaml"] }
|
||
colored = "1.9.0"
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<p>很少,只有三个,但是仍然有优化空间。</p>
|
||
<h2 id="去除不必要的依赖"><a class="header" href="#去除不必要的依赖">去除不必要的依赖</a></h2>
|
||
<p>首先使用命令 <code>cargo deps | dot -Tpng > dep.png</code>,可以将当前依赖关系绘制成一张图。(需要用到
|
||
<a href="https://github.com/m-cat/cargo-deps"><code>cargo-deps</code></a>和
|
||
<a href="https://graphviz.gitlab.io/download/"><code>graphviz</code></a>)
|
||
<img src="../../img_list/dep.png" alt="img" />
|
||
这里面看起来最 “庞大” 的是 clap。
|
||
不过这个图也未必准确,因为 Rust 拥有条件编译,这里列出的依赖并不一定会全部用到。比如 <code>winconsole</code> 就只会在 Windows
|
||
上被编译。所以我们还要使用另一个工具
|
||
<a href="https://github.com/RazrFalcon/cargo-bloat"><code>cargo-bloat</code></a>(为了方便看出结果,这里没有启用前面的优化)</p>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>cargo bloat --release --crates
|
||
Finished release [optimized] target(s) in 1m 06s
|
||
Analyzing /home/aloxaf/.cache/cargo-build/release/ren3
|
||
File .text Size Crate 7.3% 27.3% 351.7KiB clap 4.8% 17.8% 229.2KiB regex 4.7% 17.6% 226.4KiB regex_syntax 4.1% 15.2% 195.3KiB std 2.4% 9.1% 116.5KiB yaml_rust 1.5% 5.5% 70.9KiB aho_corasick 0.7% 2.8% 35.5KiB [Unknown] 0.4% 1.4% 17.5KiB ren3 0.2% 0.7% 8.8KiB colored 0.1% 0.3% 3.6KiB thread_local 0.1% 0.2% 3.2KiB ansi_term 0.1% 0.2% 3.2KiB memchr 0.0% 0.2% 2.4KiB strsim 0.0% 0.1% 1.5KiB textwrap 0.0% 0.0% 28B atty 26.7% 100.0% 1.3MiB .text section size, the file size is 4.7MiB Note: numbers above are a result of guesswork. They are not 100% correct and never will be.
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<p>使用 cargo-bloat 查看各个 crate 所占体积,可以看到 clap 和 regex 加起来占了一半。
|
||
考虑到这个工具的命令行参数并不复杂,并不需要使用 clap 这种庞大的命令行参数解析库。所以要做的首先就是将 clap 去掉,换成更基础的
|
||
<a href="https://crates.io/crates/getopts">getopts</a>。
|
||
换成 getopts 后再编译,体积再次小幅减小!</p>
|
||
<div class="table-wrapper"><table><thead><tr><th>编译方式</th><th>优化方式</th><th>体积</th><th>变化</th></tr></thead><tbody>
|
||
<tr><td>release</td><td>无</td><td>4.70M</td><td>100%</td></tr>
|
||
<tr><td>release</td><td>前文步骤</td><td>2.44M</td><td>52.0%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + strip</td><td>1.40M</td><td>29.8%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + 去掉 clap</td><td>1.96M</td><td>41.8%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + 去掉 clap + strip</td><td>1.06M</td><td>22.6%</td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h2 id="禁用不必要的-feature"><a class="header" href="#禁用不必要的-feature">禁用不必要的 feature</a></h2>
|
||
<p>这是不少人都会忽略的一点,很多 crate 默认会启用不少 feature。有些功能可能你根本没有用到,却被引入了。(这也是 cargo-deps 存在的意义)
|
||
如果这个 crate 是项目的直接依赖还好,可以在 Cargo.toml 里禁用不需要的 feature。就怕这个 crate 并不是项目的直接依赖。
|
||
举一个例子,<a href="https://github.com/image-rs/imageproc/issues/344">imageproc#344</a>:imageproc
|
||
依赖 image,并且没有禁用默认 feature,而 image 默认启用了对所有图片格式的支持。这就导致了任何使用了 imageproc
|
||
的项目都会附带一个开启了所有 feature 的 image。即使你在自己的 Cargo.toml 中禁用这些 feature 也无济于事,因为 feature
|
||
是取<strong>并集</strong>的。 如果你也遇到了这种情况建议给直接库作者提 issue 或者 PR。
|
||
回到我们的项目中来,getopts 和 colored 都十分精简,没有多余的 feature,但 regex 还是有可优化之处的。阅读 regex
|
||
的<a href="https://github.com/rust-lang/regex/blob/master/Cargo.toml#L37-L105">features 列表</a>,发现默认启用了
|
||
<code>["std", "perf", "unicode"]</code></p>
|
||
<ul>
|
||
<li>std,暂且不谈,而且看描述这和 feature 目前对于 regex 来说是必需的</li>
|
||
<li>perf,提供性能优化</li>
|
||
<li>unicode,顾名思义,提供完整的 Unicode 支持比如 <code>\p{Letter}</code>、<code>\p{Emoji}</code>
|
||
作为一个简单的文件夹改名工具,并不会用到复杂的正则,也不需要匹配奇怪的 Unicode 字符。所以我们可以禁用这两个 feature</li>
|
||
</ul>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>[dependencies]
|
||
regex = { version = "1.3.1", default-features = false, features = ["std"] }
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<p>此时再编译</p>
|
||
<div class="table-wrapper"><table><thead><tr><th>编译方式</th><th>优化方式</th><th>体积</th><th>变化</th></tr></thead><tbody>
|
||
<tr><td>release</td><td>无</td><td>4.70M</td><td>100%</td></tr>
|
||
<tr><td>release</td><td>前文步骤</td><td>1.96M</td><td>41.8%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + strip</td><td>1.06M</td><td>22.6%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + 禁用 feature</td><td>1.26M</td><td>26.8%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + 禁用 feature + strip</td><td>0.42M</td><td>8.94%</td></tr>
|
||
<tr><td>巨大进步!strip 后的程序体积终于降低到了 KB 级别!!</td><td></td><td></td><td></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h1 id="libstd-优化"><a class="header" href="#libstd-优化">libstd 优化</a></h1>
|
||
<blockquote>
|
||
<p>终于要对 libstd 下手了
|
||
Rust 的工具链自带了预编译的标准库(libstd),这样开发者就不用在每次编译 Rust 程序的时候都编译一遍 libstd,而是直接把 libstd
|
||
静态链接进去就行。
|
||
好处是很明显的,然而坏处也是很明显的:</p>
|
||
</blockquote>
|
||
<ol>
|
||
<li>预编译的 libstd 着重优化速度而不是体积</li>
|
||
<li>即使是 LTO 也无法移除 libstd 中的某些我们用不到的代码
|
||
这时就轮到 <a href="https://github.com/japaric/xargo">Xargo</a> 出场了——一个可以方便地为你的程序单独编译 libstd
|
||
的工具。
|
||
在项目根目录下创建 <code>Xargo.toml</code>(不需要删掉原来的 <code>Cargo.toml</code>),写入:</li>
|
||
</ol>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>[dependencies]
|
||
std = { default-features = false }
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<p>然后编译(target 请自行调整)</p>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>xargo build --target x86_64-unknown-linux-gnu --release
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<div class="table-wrapper"><table><thead><tr><th>编译方式</th><th>优化方式</th><th>体积</th><th>变化</th></tr></thead><tbody>
|
||
<tr><td>release</td><td>无</td><td>4.70M</td><td>100%</td></tr>
|
||
<tr><td>release</td><td>前文步骤</td><td>1.26M</td><td>26.8%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + strip</td><td>0.42M</td><td>8.94%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + 裁剪 std</td><td>378KB</td><td>7.85%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + 裁剪 std + strip</td><td>266KB</td><td>5.53%</td></tr>
|
||
<tr><td>再次获得了不小的进步</td><td></td><td></td><td></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h2 id="移除-panic-相关字符串"><a class="header" href="#移除-panic-相关字符串">移除 <code>panic</code> 相关字符串</a></h2>
|
||
<p>即使已经在 <code>Cargo.toml</code> 指定了 <code>panic = 'abort'</code>,<code>rustc</code> 默认还是会生成相关的格式化字符串。我们可以通过 feature
|
||
<code>panic_immediate_abort</code> 来禁止这个行为</p>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>[dependencies]
|
||
std = { default-features = false, features=[ "panic_immediate_abort" ] }
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<div class="table-wrapper"><table><thead><tr><th>编译方式</th><th>优化方式</th><th>体积</th><th>变化</th></tr></thead><tbody>
|
||
<tr><td>release</td><td>无</td><td>4.70M</td><td>100%</td></tr>
|
||
<tr><td>release</td><td>前文步骤</td><td>378KB</td><td>7.85%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + strip</td><td>266KB</td><td>5.53%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + <code>panic_immediate_abort</code></td><td>293KB</td><td>6.09%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + <code>panic_immediate_abort</code>+ strip</td><td>210KB</td><td>4.36%</td></tr>
|
||
<tr><td>再次进步了一点点</td><td></td><td></td><td></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h1 id="upx-压缩"><a class="header" href="#upx-压缩">UPX 压缩</a></h1>
|
||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>upx -9 target/x86_64-unknown-linux-gnu/release/ren3
|
||
<span class="boring">}</span></code></pre></pre>
|
||
<p>都懂的 XD</p>
|
||
<div class="table-wrapper"><table><thead><tr><th>编译方式</th><th>优化方式</th><th>体积</th><th>变化</th></tr></thead><tbody>
|
||
<tr><td>release</td><td>无</td><td>4.70M</td><td>100%</td></tr>
|
||
<tr><td>release</td><td>前文步骤</td><td>293KB</td><td>6.09%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + strip</td><td>210KB</td><td>4.36%</td></tr>
|
||
<tr><td>release</td><td>前文步骤 + strip + upx</td><td>98.8KB</td><td>2.06%</td></tr>
|
||
<tr><td>体积再次大幅减小!</td><td></td><td></td><td></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<h1 id="结尾"><a class="header" href="#结尾">结尾</a></h1>
|
||
<p>从 4.70MB 到 98.8 KB,非常可以了。我已经没有遗憾了(
|
||
虽然再往后还可以使用 <code>#![no_std]</code> 直接去除 libstd,不过这个限制太大,只有你使用的所有的 crate 都支持 nostd
|
||
时才能这样做,而且限制了大量 feature。一般只有嵌入式项目或者 wasm 项目中才会用到,而我想要的是对与大部分 Rust
|
||
项目来说都能使用的技巧,所以就不谈这个了。</p>
|
||
|
||
</main>
|
||
|
||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||
<!-- Mobile navigation buttons -->
|
||
<a rel="prev" href="../../posts/rust/fast_way_to_implment_object_trait.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||
<i class="fa fa-angle-left"></i>
|
||
</a>
|
||
|
||
<a rel="next prefetch" href="../../posts/rust/implment_file_upload_backend.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||
<i class="fa fa-angle-right"></i>
|
||
</a>
|
||
|
||
<div style="clear: both"></div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||
<a rel="prev" href="../../posts/rust/fast_way_to_implment_object_trait.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||
<i class="fa fa-angle-left"></i>
|
||
</a>
|
||
|
||
<a rel="next prefetch" href="../../posts/rust/implment_file_upload_backend.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||
<i class="fa fa-angle-right"></i>
|
||
</a>
|
||
</nav>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<script>
|
||
window.playground_line_numbers = true;
|
||
</script>
|
||
|
||
<script>
|
||
window.playground_copyable = true;
|
||
</script>
|
||
|
||
<script src="../../ace.js"></script>
|
||
<script src="../../editor.js"></script>
|
||
<script src="../../mode-rust.js"></script>
|
||
<script src="../../theme-dawn.js"></script>
|
||
<script src="../../theme-tomorrow_night.js"></script>
|
||
|
||
<script src="../../elasticlunr.min.js"></script>
|
||
<script src="../../mark.min.js"></script>
|
||
<script src="../../searcher.js"></script>
|
||
|
||
<script src="../../clipboard.min.js"></script>
|
||
<script src="../../highlight.js"></script>
|
||
<script src="../../book.js"></script>
|
||
|
||
<!-- Custom JS scripts -->
|
||
<script src="../../src/js/custom.js"></script>
|
||
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|