• MIPS台OpenWrt在系统内的路由器Rust应用程序开发


    笔者:Liigo(庄小莉)

    迄今:2014年9一个月17日本 (9一个月29日更新,11一个月19日本再次更新。在最后可用更新)

    原文链接:http://blog.csdn.net/liigo/article/details/39347541

    。转载请注明出处:http://blog.csdn.net/liigo


    目标

    使用 Rust 语言。交叉编译开发 MIPS(el) + OpenWrt 路由器平台(MT7620A CPU)下的应用软件。


    编译rustc

    首先自行编译Rust编译器源码。生成支持 mipsel-unknown-linux-gnu 平台的交叉编译器rustc

    ./configure --target=mipsel-unknown-linux-gnu && make && make install

    注意编译过程中会调用 MIPS(el) + OpenWrt 平台的开发包SDK。详细来说就是 mipsel-unknown-linux-gnu-gcc 和 mipsel-unknown-linux-gnu-ar。

    可是SDK内的工具命名格式是 mipsel-openwrt-linux-uclibc-gcc/ar,跟Rust编译脚本所要求的不同。一个简单的做法是,创建符号链接文件:

    cd <openwrt>/staging_dir/toolchain-mipsel_r2_gcc-4.7-linaro_uClibc-0.9.33.2/bin
    ln -s mipsel-openwrt-linux-uclibc-gcc mipsel-unknown-linux-gnu-gcc
    ln -s mipsel-openwrt-linux-uclibc-ar  mipsel-unknown-linux-gnu-ar


    使用Rust标准库std

    编写源文件 histd.rs:

    fn main() {
    	println!("Hi Rust! (uses std crate)");
    }
    编译 histd:

    rustc --target=mipsel-unknown-linux-gnu -C linker=mipsel-unknown-linux-gnu-gcc -C target-cpu=mips32r2 histd.rs

    将生成目标平台下的可运行文件histd。文件尺寸是 1,389,884 字节,约 1.32 MB (11月19日Liigo用最新Rust编译后更新) 932013 字节。约 930 KB,相当的大!对于路由器设备而言,差点儿是难以接受。

    这是静态编译生成的可执行文件。没有额外的执行时库依赖。严格地说仅依赖目标系统内的libc.so。当然假设不须要向控制台输出文本。连libc.so也不须要。


    使用Rust核心库core(不使用标准库std)

    编写源文件 hicore.rs:

    #![no_std]
    #![feature(lang_items)]
    
    extern crate libc;
    extern crate core;
    
    use libc::puts;
    use core::str::StrPrelude; // &str::as_prt()
    
    #[start]
    fn start(_argc: int, _argv: *const *const u8) -> int {
        unsafe {
            puts("Hi Rust! (uses core crate)".as_ptr() as *const i8);
        }
        return 0;
    }
    
    #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
    #[lang = "eh_personality"] extern fn eh_personality() {}
    
    #[lang = "panic_fmt"]
    extern fn panic_fmt(_args: &core::fmt::Arguments,
                       _file: &str,
                       _line: uint) -> ! {
        loop {}
    }

    编译 hicore.rs:

    rustc --target=mipsel-unknown-linux-gnu -C linker=mipsel-unknown-linux-gnu-gcc -C target-cpu=mips32r2 hicore.rs

    将生成目标平台下的可运行文件hicore,文件尺寸仅仅有 7419 字节。约 7KB,相当的小!

    这是静态编译生成的可执行文件,没有额外的执行时库依赖。

    严格地说仅依赖目标系统内的libc.so,当然假设不须要向控制台输出文本。连libc.so也不须要。


    不用标准库std。也不用核心库core,纯裸奔

    编写源码 hi.rs:

    #![no_std]
    #![feature(lang_items)]
    #![feature(intrinsics)]
    
    #[link(name = "c")]
    extern {
        fn puts(s: *const u8);
    }
    
    #[start]
    fn start(_argc: int, _argv: *const *const u8) -> int {
        let s = "Hi Rust!"; // &str
        unsafe {
            let (s,_): (*const u8, uint) = transmute(s); // see core::raw::Slice
            puts(s);
        }
        return 0;
    }
    
    #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
    #[lang = "eh_personality"] extern fn eh_personality() {}
    
    #[lang="sized"] trait Sized {}
    
    extern "rust-intrinsic" {
        fn transmute<T, U>(x: T) -> U;
    }

    编译 hi.rs:

    rustc --target=mipsel-unknown-linux-gnu -C linker=mipsel-unknown-linux-gnu-gcc -C target-cpu=mips32r2 hi.rs
    将生成目标平台下的可运行文件hi,文件尺寸仅仅有 6552 字节。约 6KB。相当的小!比使用核心库core的hicore还要小,但相差不大。

    这是静态编译生成的可执行文件,没有额外的执行时库依赖。严格地说仅依赖目标系统内的libc.so,当然假设不须要向控制台输出文本,连libc.so也不须要。


    可运行文件尺寸对照

    使用Rust标准库std编译生成的histd。使用Rust核心库core编译生成的的hicore,和不用标准库也不用核心库编译生成的hi,这三者的可运行文件尺寸对照方下:

    -rwxr-xr-x 1 liigo liigo 932013  11月 19 20:20 histd
    -rwxr-xr-x 1 liigo liigo   7419  11月 19 20:19 hicore
    -rwxr-xr-x 1 liigo liigo   6552  11月 19 20:19 hi
    使用标准库std编译出来的程序histd太大,不适合嵌入式设备,首先被淘汰;使用核心库core编译出来的程序hicore非常小。跟不使用不论什么库的hi不相上下。既然用不用核心库core,在文件尺寸上没有多大变化,而核心库core还能带来非常多编码上的便利,故推荐在嵌入式平台内使用核心库core。

    以上是 mipsel-unknown-linux-gnu 平台的情况。以下作为对照,我们再看一下 x86_64-unknown-linux-gnu 平台:

    -rwxr-xr-x 1 liigo liigo 668621  9月 17 20:16 histd
    -rwxr-xr-x 1 liigo liigo   8920  9月 17 20:16 hicore
    -rwxr-xr-x 1 liigo liigo   8159  9月 17 20:16 hi

    对照后发现,x86_64 平台下的可运行文件整体上比 mipsel 平台略大,但差距不大。情况也类似。

    11月19日Liigo注:跟两个月前最初发表本文时相比,mipsel 平台和 windows 平台的 histd 尺寸分别缩小了 450KB 和 320KB,体现了标准库的优化结果(比如 RFC #230);但 hicore 和 hi 的尺寸变化非常小。


    Rust支持的主流交叉编译平台 (target triples)

    信息来源:https://github.com/rust-lang/rust/tree/master/mk/cfg

    arm-apple-ios
    arm-linux-androideabi
    arm-unknown-linux-gnueabi
    arm-unknown-linux-gnueabihf
    i386-apple-ios
    i686-apple-darwin
    i686-pc-windows-gnu
    i686-unknown-linux-gnu
    mipsel-unknown-linux-gnu
    mips-unknown-linux-gnu
    x86_64-apple-darwin
    x86_64-pc-windows-gnu
    x86_64-unknown-dragonfly
    x86_64-unknown-freebsd
    x86_64-unknown-linux-gnu

    用法:

    编译Rust本身:./configure --target=triple1,triple2 && make && make install

    编译Rust程序:rustc --target=triple -C linker=triple-gcc

    必要时创建相应交叉编译平台SDK编译工具的符号链接文件 triple-gcc、triple-ar 等。


    本文涉及到多个源码文件已上传到Github:https://github.com/liigo/hirust 。作者Liigo。


    Liigo 20140929 更新内容

    1、修正 lang_item `sized` 和 `fail_fmt`。与当前最新 rustc 编译器修改同步;

    2、添加编译參数 `-C target-cpu=mips32r2`,针对測试所用CPU。消除编译警告信息。

    3、注明測试採用的硬件路由器CPU型号`MT7620A CPU`。


    Liigo 20141119 更新内容

    1、修正目标平台为 mipsel-unknown-linux-gnu (原 mipsel-linux 已废弃)。

    2、更新Rust支持的主流交叉编译平台列表(triples);

    3、更新文中Rust演示样例代码(与 https://github.com/liigo/hirust 同步);

    4、採用今日最新Rust交叉编译器的源代码,再和更新文本数据。


    版权声明:这篇文章的博客Liigo原版的,不得擅自转载。

  • 相关阅读:
    工作中的那些事(1)
    bootstrap-简单实用的垂直手风琴滑动菜单列表特效
    lua ffi简介
    CUDA常见问题与解答
    CUDA的软件体系
    CUDA并行存储模型
    基于纹理内存的CUDA热传导模拟
    函数指针 && 指针函数
    小弟在研究CUDA时出现一个问题,求解
    cuda科普像素坐标和线性偏移
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4891405.html
Copyright © 2020-2023  润新知