MIPS平台OpenWrt路由器系统内的Rust应用程序开发
来源:互联网 发布:java接口的意义 编辑:程序博客网 时间:2024/05/22 03:05
作者: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/binln -s mipsel-openwrt-linux-uclibc-gcc mipsel-unknown-linux-gnu-gccln -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)\0".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!\0"; // &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-iosarm-linux-androideabiarm-unknown-linux-gnueabiarm-unknown-linux-gnueabihfi386-apple-iosi686-apple-darwini686-pc-windows-gnui686-unknown-linux-gnumipsel-unknown-linux-gnumips-unknown-linux-gnux86_64-apple-darwinx86_64-pc-windows-gnux86_64-unknown-dragonflyx86_64-unknown-freebsdx86_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源代码重新交叉编译并更新文中相关数据。
- MIPS平台OpenWrt路由器系统内的Rust应用程序开发
- MIPS平台OpenWrt路由器系统内的Rust应用程序开发
- 基于openwrt系统的智能路由器
- 开发OpenWrt路由器上LuCI的模块
- 开发OpenWrt路由器上LuCI的模块
- 开发OpenWrt路由器上LuCI的模块+++
- OpenWrt路由器上的LuCI模块开发
- [原]OpenWrt路由器开发
- 路由器逆向分析------MIPS系统网络的配置(QEMU)
- OpenWRT(小米路由器使用系统)组建N2N VPN网络实现内网设备之间的相互访问
- 使用Rust为OpenWRT开发应用.
- openwrt交叉编译自己的应用程序(openwrt应用开发)
- OpenWrt——适用于路由器的Linux系统
- 基于openwrt系统的小米路由器创建自启动脚本
- 基于RTL8186的MIPS开发系统
- OpenWrt编译出ARM/MIPS等平台的native GCC (toolchain)
- 开发OpenWrt路由器上LuCI的模块 - 大魔王mAysWINd
- 开发OpenWrt路由器上LuCI的模块-参考
- 缺陷也是一种美丽
- 修改源码
- 模拟退火算fa
- Linux中man查询的命令格式说明
- UDP卷1:第六章(I/O复用:select和poll函数)
- MIPS平台OpenWrt路由器系统内的Rust应用程序开发
- 红黑树
- 场景切换与内存
- 我做题、比赛的头文件,不断更新中
- 可综合不可综合
- NSString的几种常用方法
- BZOJ1575 USACO 2009 Jan Gold 2.The Baric Bovine
- OpenWrt 系列教程汇总
- AOP技术应用和研究--AOP语言