精华内容
下载资源
问答
  • Windows系统中玩rust,通过Rust-Init.exe准备rustup.exe, 用rustup 安装gnu工具链前,需要准备gnu编译环境。解压这里的下载的mingw64.rar到任意文件夹,比如d:\programs, 将d:\programs\mingw64\bin添加到Path路径中...
  • 这个make脚本旨在帮助Rusties用Makefile编译Rust程序。 用法 获取资源 git submodule add git://github.com/KokaKiwi/rust-mk.git 或者,如果您不在本地Git存储库中工作: git clone git://github....
  • C语言编译的过程主流的编译器GCCLLVMC语言编译过程LLVM编译过程将C源码转为LLVM IR将IR转化为BitCode将BitCode转为目标平台汇编码执行BitCode 主流的编译器 GCC GCC编译器是由GNU开发的编译器,原名为GUN编译器,...

    主流的编译器

    GCC

    GCC编译器是由GNU开发的编译器,原名为GUN编译器,原本只能处理C语言随着发展,后续支持了C++,Java,Go等语言,所以改名为GNU编译器套件,GCC主要分为以下接口

    1. 前端接口: 将源码经过词法分析,语法分析生成与语言无关的低级中间语言表示层,然后经过优化后转化为RTL中间表示层
    2. 中间接口: 中间接口主要在RTL中间表示上进行各种优化,如循环优化,公共子表达式删除,指令重排等等
    3. 后端接口:GCC对每条RTL通过模板匹配方法调用对应的汇编模板生成汇编代码,生成的代码因处理器的不同而不同

    LLVM

    LLVM由C++编写,用于优化任意语言编写的程序,LLVM的命名最早源于Low Level Virtual Machine的缩写,LLVM代码有3种表示形式,IR,bitcode,汇编码,llvm提供了不同的优化Pass,对每个Pass的源码编译,得到一个Object文件,之后这些文件链接得到一个库,Pass之间由LLVM Pass管理器来统一管理
    LLVM有很多其项目其中包括 LLVM Core libraries,ClangLLD,LLDB,libc++ & libc++ ABI等等

    C语言编译过程

    一般的编译过程流程图大概是这样的

    编译
    汇编器
    链接器
    源代码
    汇编语言
    目标文件
    可执行文件

    但是不同的编译器有着不同的编译方式,下面我们使用LLVM对C语言编译的过程进行实践

    LLVM编译过程

    clang
    llvm-as
    llc
    main.c
    main.ll IR文件
    main.bc bitCode
    目标平台汇编码

    我们开始准备LLVM的一些环境

    • llvm
    • llvm-as(Windows 安装llvm时没有这个文件,打开网站后输入llvm-as.exe搜索下载)
    • llc (同llvm-as)

    首先我们创建一个test.c文件然后输入以下内容

    int mult() {
        int a = 5; 
        int b = 3; 
        int c = a * b;
        return c; 
    }
    

    将C源码转为LLVM IR

    输入一下命令

    clang -emit-llvm -S test.c -o  test.ll
    

    其中我们使用了clang作为前端进行编译,-emit-llvm用于LLVM IR写到.ll文件,-S表示仅运行预处理和编译步骤,-o参数用于将生成的内容输出到test.ll文件中

    执行完毕后会在test.c同级目录下生成一个test.ll文件,将C语言代码分解为Token流(每个Token可表示标识符,字面量,运算符等等),Token流会传递给语法分析器,语法分析器使用CFG(上下文无关文法)组织成AST(抽象语法树),紧接着进行语义分析,然后生成IR

    将IR转化为BitCode

    我们使用一个较为简单的IR文件,内容如下

    // test.ll
    define i32 @mult(i32 %a, i32 %b) #0 { 
       %1 = mul nsw i32 %a, %b  
       ret i32 %1
    }
    

    使用命令如下

    llvm-as test.ll -o test.bc
    

    我们使用llvm-as(LLVM汇编器)将LLVM IR转为BitCode,-o参数用于将生成的BitCode输出到test.bc文件中

    将BitCode转为目标平台汇编码

    我们使用LLVM的静态编译器LLC把BitCode转为汇编码,命令如下

    llc test.bc -o test.s
    

    或者我们可以使用Clang从BitCode文件生成汇编码,命令如下

    clang -S test.bc -o test.s -fomit-frame-pointer
    

    我们使用了fomit-frame-pointer参数消除帧指针,因为Clang默认不消除帧指针,但是llc却默认消除帧指针

    llc命令把LLVM的BitCode编译为指定架构的汇编语言,如果命令中没有指定任何架构默认生成的本机汇编码

    执行BitCode

    我们把test.c的内容换为以下内容

    #include<stdio.h> 
    
    int main(){
    	int num = 5; 
     	printf("number is %d\n", num); 
     	return 0; 
    }
    
    

    然后我们按照之前的步骤将test.c转为BitCode

    $ clang -emit-llvm -S test.c -o test.ll 
    $ llvm-as test.ll -o test.bc 
    

    注: 在Windows执行第2步是会出现以下错误
    llvm-as: test.ll:31:62: error: expected ‘global’ or ‘constant’
    @"??_C@_0O@BAPFBKAP@number?5is?5? C F d ? 6 ? CFd?6? CFd?6?AA@" = linkonce_odr dso_local unnamed_addr constant [14 x i8] c"number is %d\0A\00", comdat, align 1
    错误原因等待解决

    最后我们使用LLI命令来运行BitCode

    $ lli test.bc
    

    LLI使用LLVM bitcode格式 作为输入并且使用即时编译器(JIT)执行,如果当前的架构不 存在JIT编译器,会用解释器执行

    Rust编译过程

    Rust使用的是rustc进行编译,编译的过程如下

    语法分析,宏扩展
    类型检查
    转换
    LLVM
    链接
    RustCode
    HIR
    MIR
    LLVM IR
    .o文件
    可执行程序

    详细过程如下

    1. 解析输入:将.rs文件作为输入并进行解析生成AST(抽象语法树)
    2. 名称解析,宏扩展和属性配置:解析完毕后处理AST,处理#[cfg]节点解析路径,扩展宏
    3. 转为HIR:名称解析完毕后将AST转换为HIR(高级中间表示),HIR比AST处理的更多,但是他不负责解析Rust的语法,例如((1+2)+3)1+2+3在AST中会保留括号,虽然两者的含义相同但是会被解析成不同的树,但是在HIR中括号节点将会被删除,这两个表达式会以相同的方式表达
    4. 类型检查以及后续分析:处理HIR的重要步骤就是类型检查,例如使用x.f时如果我们不知道x的类型就无法判断访问的哪个f字段,类型检查会创建TypeckTables其中包括表达式的类型,方法的解析方式
    5. 转为MIR以及后置处理:完成类型检查后,将HIR转为MIR(中级中间表示)进行借用检查以及优化
    6. 转为LLVM IR和优化:LLVM进行优化,从而生成许多.o文件
    7. 链接: 最后将那些.o文件链接在一起

    我们开始实践这一过程

    首先我们创建一个Cargo项目

    ~$ cargo new complier_test
    

    main.rs文件中的内容如下

    fn main(){
        println!("Hello");
    }
    

    将源代码转为HIR
    我们可以使用cargo的 -Zunpretty参数来生成hir,rustc命令没有找到。。

    ~/complier_test$ cargo rustc -- -Zunpretty=hir-tree -o main.hir
    

    然后在src目录下会生成main.hir文件

    将源代码转为MIR
    转为mir的过程我们可以使用rustc来完成

    ~/complier_test/src$ rustc --emit mir  -o main.mir main.rs
    

    我们使用emit来生成emit用来生成mir,除此之外还可以使用emit来生成LLVM IR

    ~/complier_test/src$ rustc --emit llvm-ir -o main.ll main.rs
    

    转换为BitCode

    然后我们可以使用llvm-as将IR转为BitCode

    ~/complier_test/src$ llvm-as main.ll -o main.bc
    

    或者我们可以使用rustc的emit参数生成

    ~/complier_test/src$ rustc --emit llvm-bc -o main.bc
    

    最后我们可以使用LLI来运行BitCode

    ~/complier_test/src$ lli main.bc
    

    下一步做什么

    在下一篇文章我们使用Rust实现一个分词器,我们还需要掌握一些关于分词的理论知识

    展开全文
  • 用于在MacOS或Linux上轻松将Rust编译成WebAssembly
  • Linux 下 rust 默认使用 gcc 作为链接器,编译后的文件在运行时需要glibc 运行库和其他的一些库。 这就导致在某个Linux版本下编译的执行文件,无法在另一个Linux版本上顺利运行。而且,如果你的程序还使用了Ope


    关于windows环境: https://blog.csdn.net/u013195275/article/details/103397888

    Linux 环境

    Linux 下 rust 默认使用 gcc 作为链接器,编译后的文件在运行时需要glibc 运行库和其他的一些库。

    这就导致在某个Linux版本下编译的执行文件,无法在另一个Linux版本上顺利运行。而且,如果你的程序还使用了OpenSSL动态库,那这样的问题会更加突出。

    下面,我们做个最简单的实验。

    1. 用Cargo创建一个可执行项目。
    2. 编译这个项目
    3. 用ldd命令查看编译出来的执行文件依赖了哪些动态链接库
    $ cargo -V
    cargo 1.31.0 (339d9f9c8 2018-11-16)
    $ cargo new --bin hello
    $ cd hello
    $ cargo build
    $ ldd target/debug/hello
            linux-vdso.so.1 (0x00007ffdc47e4000)
            libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6db611a000)
            librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f6db5f12000)
            libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6db5cf3000)
            libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f6db5adb000)
            libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6db56ea000)
            /lib64/ld-linux-x86-64.so.2 (0x00007f6db6587000)
    

    可以看到这个执行文件依赖了多个.so的动态链接库。而且这种依赖是基于绝对路径的。一旦运行时环境下没有这些动态库文件,那程序执行的结果就只有一个:报错!

    那么,Rust能否像Golang那样编译成独立的静态可执行文件呢?答案是可以的,这需要使用MUSL 静态库。

    使用MUSL进行静态编译

    使用MUSL编译,首先需要安装musl环境。命令如下:

    $ rustup target add x86_64-unknown-linux-musl
    或者
    $ rustup target add x86_64-unknown-linux-musl --toolchain=nightly
    

    然后,我们编译前面创建的hello工程。

    $ cd hello
    $ cargo build --release --target=x86_64-unknown-linux-musl
    $ ldd target/x86_64-unknown-linux-musl/release/hello
            not a dynamic executable
    

    可以看到新的可执行文件已经不再依赖任何动态链接库。我们可以将这个文件放到任何一个Linux操作系统里运行了。

    当然,这只是一个最简单的例子。实际工作中,我们可能会遇到更复杂的场景。如:依赖了OpenSSL库。在这样的场景里,我们还需要做很多配置才能获得我们想要的静态编译文件。这里就不再详细介绍了。

    笔者想介绍的是如何避免各种繁复的配置,尽可能快捷的进行MUSL编译。就是下面章节的内容。

    使用预置好的Docker容器进行MUSL编译

    为解决使用MUSL编译配置繁琐的问题,国外的开发者贡献了一个预置好的容器。用这个容器来进行MUSL编译会非常方便快捷。

    项目地址是:https://gitlab.com/rust_musl_docker/image

    我们直接用这个容器来编译我们前面创建的hello工程。然后依然用ldd来查看编译好的可执行文件。

    $ cd hello
    $ docker run -it --rm \
    > -v $PWD:/workdir \
    > -v ~/.cargo/git:/root/.cargo/git \
    > -v ~/.cargo/registry:/root/.cargo/registry \
    > registry.gitlab.com/rust_musl_docker/image:stable-latest \
    > cargo build --release -vv --target=x86_64-unknown-linux-musl
    
    $ ldd target/x86_64-unknown-linux-musl/release/hello
            not a dynamic executable
    12345678910
    

    这个容器镜像里已经配置了对OpenSSL库的静态编译。笔者亲测可用。更详细的内容,读者可以去看项目里的注释,已经非常详尽了。

    CentOS docker

    rust docker交叉编译静态单体执行文件
    编译对应平台的docker image(https://github.com/messense/rust-musl-cross).

    Rust toolchainCross Compile TargetDocker Image Tag
    stablex86_64-unknown-linux-muslx86_64-musl
    stablei686-unknown-linux-musli686-musl
    stablearm-unknown-linux-musleabiarm-musleabi
    stablearm-unknown-linux-musleabihfarm-musleabihf
    stablearmv7-unknown-linux-musleabihfarmv7-musleabihf
    stablearmv5te-unknown-linux-musleabiarmv5te-musleabi
    stablemips-unknown-linux-muslmips-musl
    stablemipsel-unknown-linux-muslmipsel-musl

    用法:

    1. 先拉取对应镜像:docker pull messense/rust-musl-cross:armv7-musleabihf
    2. 为了方便使用,重命名
      alias rust-musl-builder='docker run --rm -it -v "$(pwd)":/home/rust/src messense/rust-musl-cross:armv7-musleabihf'
    3. 用"rust-musl-builder"这个命令简化使用
      rust-musl-builder cargo build --release
    4. 上面就和使用普通cargo打包一样了,调这个命令其它就相当于挂载本地项目到容器中打包。
    5. 以上镜像为了打包静态单体,镜像中已包含了(为了有这个教程,就是在centos中打包静态单体时需要openssl,解决了普通openssl的打包,发现静态打包还需要musl-gcc,而centos找了半天也没有找到,所以就想到了docker省得自己搭环境了)
      • The standard musl-libc libraries.
      • OpenSSL, which is needed by many Rust applications.

    https://blog.csdn.net/u013195275/article/details/106074495
    https://blog.csdn.net/castellan/article/details/86063775

    展开全文
  • 使用React和基于Rust编译的WebAssembly样板应用程序
  • Rustup 是官方提供的安装工具,不仅可以下载 Rustc 编译工具,还可以下载各种 Rust 的工具链。 Rustup 镜像/反代 使用方式 把一下代码复制到.bashrc或者类似文件(.zshrc等)然后执行source .bashrc或者将其添加到...

    使用 Rustup

    Rustup 是官方提供的安装工具,不仅可以下载 Rustc 编译工具,还可以下载各种 Rust 的工具链。

    Rustup 镜像/反代

    • 使用方式
      把一下代码复制到.bashrc或者类似文件(.zshrc等)然后执行source .bashrc或者将其添加到环境变量
    export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup
    
    • 安装 Rustup
      先打开 Rustup 的官网:https://rustup.rs,然后根据提示下载或运行命令就可以了。

    比如在 Linux 下执行:
    curl https://sh.rustup.rs -sSf | sh 即可。

    • 配置 crate.io 镜像
      因为cargo等下载需要连接 crate.io 网络如果不是很好的话会特别慢,可以在$HOME/.cargo/下建立一个config文件,加入如下配置:
    [source.crates-io]
    replace-with = 'tuna'
    
    [source.tuna]
    registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"
    

    安装nightly版本及 racer

    安装nightly版本: rustup install nightly && rustup default nightly
    安装src : rustup component add rust-src
    安装racer: cargo install racer

    参考:
    https://www.jianshu.com/p/5efdd9ce8565
    https://www.cnblogs.com/onsunsl/p/rust-cargo-proxy-and-crates-io-china-mirro.html
    Rust Develop(Learn) Environment

    展开全文
  • RUSTrust 编译C code

    2021-04-29 16:31:11
    主要讲我们要怎么让rust帮我们把C的部分调用gcc编译出来 这里我们展示如何编出一个so 我们先要写一 .c档,把他放在src/c_lib下面 ├── build.rs ├── Cargo.lock ├── Cargo.toml ├── src │ ├── c_...

    rust调用C code的一部分
    主要讲我们要怎么让rust帮我们把C的部分调用gcc编译出来
    这里我们展示如何编出一个so

    1. 我们先要写一 .c档,把他放在src/c_lib下面

    ├── build.rs
    ├── Cargo.lock
    ├── Cargo.toml
    ├── src
    │   ├── c_lib
    │   │   └── mylib.c
    │   ├── ffi.rs
    │   └── main.rs
    看到我们在 c_lib下面放了mylib.c

    展开全文
  • 配置Rust编译环境

    2020-11-25 15:43:48
    配置Rust开发环境 Step1Step1Step1:确保已完成MinGW-w64的安装; Step2Step2Step2:下载Rust安装程序rustup-init.exe; Step3Step3Step3:打开命令窗口输入以下命令: @REM SET CARGO_HOME= @REM SET RUSTUP_HOME...
  • [WebAssembly技术]Rust编译成wasm文件

    千次阅读 2019-04-03 15:39:59
    WebAssembly (以下简称WASM)...由于 WASM 是静态类型,因此很难直接使用我们熟悉的 JavaScript来直接编写,目前的 WASM 都是通过其他静态语言编译而来。目前支持 WASM 的语言有 C++、Rust、Go等。其中 Rust 对 WA...
  • 名为compile的文件上的命令行用于将rust编译为wasm并将重新使用的静态文件移动到可服务的目录中。 您可以按原样使用它,也可以根据自己的喜好复制和修改命令。 跑步 尽管生成的文件100%在客户端运行。 由于跨域安全...
  • 为什么Rust编译出的可执行文件那么大?#rust #exe为什么相同应用用Rust编译出的可执行文件比C编译出的要大?下面这篇文章详细阐述了原因,并提出了多重可行的方案,帮你减小可执行...
  • Vs_Code2019快速配置RUST编译环境

    千次阅读 2019-11-14 15:22:53
    Vs_Code快速配置rust编译环境1.RUST安装2.新建rs项目3.vscode配置编译环境如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个...
  • cargo交叉编译rust程序

    2021-01-07 03:22:41
    0、安装rust环境参考:...2、在~/.cargo/config配置参数,配置目标平台交叉编译连接器 vim ~/.cargo/config [target.arm-unknown-linux-gnueabi] linker = arm-hisiv400-linux-gnue
  • Rust 编译模型之殇

    2020-03-02 17:58:53
    作者介绍: Brian Anderson 是 Rust 编程语言及其姊妹项目 Servo Web 浏览器的共同创始人之一...Rust 编译缓慢的根由在于语言的设计。 我的意思并非是此乃 Rust 语言的设计目标。正如语言设计者们相互争论时经常说的...
  • ructe:具有静态文件处理功能的Rust编译模板
  • 安装rust 编译工具链

    千次阅读 2020-06-14 11:41:09
    Rust 版本管理工具: rustup 项目主页是: https://github.com/rust-lang-nursery/rustup.rs Features 管理安装多个官方版本的 Rust 二进制程序。...安装额外的 std 用于交叉编译。 安装自定义的工具链。
  • 通过Rust编译时出现的错误来学习Rust

    千次阅读 2020-12-29 16:43:11
    通过Rust编译时出现的错误来学习Rust cannot assign twice to immutable variable x 不能复制两次不可变x fn main() { let x = 5; // solution: let mut x = 5; println!("The value of x is {}", x); x = 6; ...
  • rustc .\hello.rs error: linker `link.exe` not found | = note: 系统找不到指定的文件。 (os error 2) note: the msvc targets depend on the msvc linker but `link.exe` was not found note: please ensure ...
  • 从Mac到Linux交叉编译Rust 如何将Rust从macOS交叉编译到Linux x86_64-unknown-linux-gnu的示例 背景/最初动机 截至2020年11月,我macOS笔记本电脑上的使用来迭代Kubernetes集群更改,然后再将其应用于生产集群。 ...
  • 编译的代码中删除了对Rust crate的引用,从而使我们的编译后的代码可以编译为没有libc的目标,例如WebAssembly目标 。 该存储库每周使用GitHub Actions拉取libsamplerate的master分支,以将其移植到Rust中。
  • 在用rust语言开发一个访问mysql数据库的demo编译程序的时候出现如下的错误信息 failed to run custom build command for miniz-sys v0.1.7 安装mingw-w64-install软件就能解决 转载于:...
  • Centos 7 yum install mysql-devel 转载于:https://www.cnblogs.com/ilovewindy/p/11573539.html
  • 字符串混淆对Rust编译时字符串文字混淆。 实例附带一个简单的宽度! 宏,以提供编译时间utf16字符串lite字符串混淆。Rust编译时字符串文字混淆。 实例附带一个简单的宽度! 提供编译时间utf16字符串文字的宏:让...
  • min-size-rust::crab:如何最小化Rust二进制大小:package:
  • rust语言是一个系统编程语言,安全,并发,稳定,没有垃圾回收机制。 在arm开发板使用非常好
  • rust - Windows 编译执行

    2021-02-03 23:16:25
    一,新建文件 新建一个main.txt 的文件,写一个Hello, world!...打开cmd命令窗口,编译main.rs文件 文件夹的内如如下:多个main.exe执行文件和main.pdb 三,执行文件 执行文件main.exe ...
  • Rust 减小程序编译后的体积

    千次阅读 2020-10-29 11:16:01
    Rust编译出的可执行文件大解决方法 有时会痛苦的感慨Rust程序编译后的文件为什么那么大,而C语言的那么小。其实,Rust之所以大,是因为里面包含了较多的标准库等相关的东西。 当然,Rust体积也是可以缩小的。这里给...
  • rust 安装成功后编译失败,windows环境。 错误原因是,电脑上没有c++编译环境。 错误的解决方法是:下载visualcppbuildtools_full.exe 然后点击默认安装,至少花了2个小时下载,安装后的软件如下: 这个c++ ...
  • Rust编译时字符串常量混淆。 字符串常量本身以混淆形式嵌入并在本地进行混淆。 对该临时值的引用必须在生成该语句的同一语句中使用。 有关更多高级用例,请参见文档。 例子 obfstr! 宏将反混淆后的字符串作为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,805
精华内容 4,322
关键字:

rust编译