笔者: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)\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-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原版的,不得擅自转载。

MIPS台OpenWrt在系统内的路由器Rust应用程序开发的更多相关文章

  1. MIPS(极路由1s[mt7620a])平台OpenWrt路由器系统内的Go应用程序开发

    起因,由于coolpy5核心转换到go语言开发,所以目前超人正在进行相关的技术攻关,在程序编写方面一切都相对顺利.由于coolpy5是一个真正的商业级性能的系统也考滤到coolpy之前的版本已经确定的 ...

  2. 专访Rust——由Mozilla开发的系统编程语言(目标人群就是那些纠结的C++程序员,甚至也是他们自己)

    Rust是由Mozilla开发的专门用来编写高性能应用程序的系统编程语言.以下是对Rust的创始人——Graydon Hoare的采访. Graydon Hoare,自称为职业编程语言工程师,从200 ...

  3. 不用rustup,Windows下gnu版Rust安装与开发环境配置

    写在前面 本文介绍了在不使用rustup的情况下,在Windows上安装gnu版的Rust,并配置开发环境(VSCode + rust-analyzer,CLion + IntelliJ Rust)的 ...

  4. 两台openwrt 间的免登陆ssh

    参考文档: http://www.360doc.com/content/13/1013/21/3884271_321222563.shtml http://blog.csdn.net/u0110079 ...

  5. Linux下同一网段内的IP中两台主机通信不经过路由器(ARP)(转)

    答案一:同一网段A与B通信,不需要路由器介入. A直接广播ARP request 到广播域,B处于同一广播域,可以接收到ARP request,B用单播方式直接告诉A自己的MAC B 地址.A收到B的 ...

  6. 如何编写一个路由器的界面1-Luci开发入门

    Howto:如何写Module(模块)-----------------这一部分主要是翻译github上的document 注意:如果您打算将模块加入LUCI整合之前,您应该阅读Module参考. 本 ...

  7. 文盘Rust -- 把程序作为守护进程启动

    当我们写完一个服务端程序,需要上线部署的时候,或多或少都会和操作系统的守护进程打交道,毕竟谁也不希望shell关闭既停服.今天我们就来聊聊这个事儿. 最早大家部署应用的通常操作是 "nohu ...

  8. 主机,路由器,应用程序,sockets api的关系

  9. 把路由器改装成git服务器(OpenWRT环境的GIT服务器搭建)

    在单位中,通常都标配了git服务器用来管理代码. 对于家庭或者小办公室,这种方式有点不经济.当然如果是开源项目就简单了,刚刚被微软收购的github是理想选择.但如果没有打算开源,我今天的话题可能对你 ...

随机推荐

  1. 从零開始学android&lt;Menu菜单组件.三十.&gt;

    在Android系统之中.菜单一共同拥有三类:选项菜单(OptionsMenu).上下文菜单(ContextMenu)和子菜单(SubMenu). 今天我们就用几个样例来分别介绍下菜单的使用 acti ...

  2. 上Https 和 http 差分

    HTTPS 和 HTTP 差协议 超文本传输协定HTTP 对于web 浏览器和现场服务之间传递消息,HTTP 以纯文本协议 发送内容 无论不提供数据加密方法 假设拦截攻击web 浏览器和网站serve ...

  3. Oracle“记录被另一个用户锁住” 无法更新删除的解决办法

    1.查看数据库锁,诊断锁的来源及类型: select object_id,session_id,locked_mode from v$locked_object; 或者用以下命令: select b. ...

  4. 解析php混淆加密解密的手段,如 phpjm,phpdp神盾,php威盾

    原文 解析php混淆加密解密的手段,如 phpjm,phpdp神盾,php威盾 php做为一门当下非常流行的web语言,常常看到有人求解密php文件,想当年的asp也是一样.一些人不理解为什么要混淆( ...

  5. Bigcommerce: 给已完成购买的客户发送一封产品评论邮件,让客户直接进行产品评论

    需求说明:进入后台的Order列表,更新订单状态:Awaiting Pickup后,就会给客户发送一封希望他们能进行评论的邮件.在邮件中展示该订单下的所有产品,每个产品都有一个评论的跳转链接,点击后直 ...

  6. poj1459(最大流)

    传送门:Power Network 题意:在一个网络图中有n个点,其中有np个发电站,nc个用户,m条电线;每个发电站,用户,和电线都对应有一个最大的电流;让求出该网络中最大的电流. 分析:最大流裸题 ...

  7. POJ 2676/2918 数独(dfs)

    思路:记录每行每列每一个宫已经出现的数字就可以.数据比較弱 另外POJ 3074 3076 必须用剪枝策略.但实现较麻烦,还是以后学了DLX再来做吧 //Accepted 160K 0MS #incl ...

  8. Unity3D游戏开发从零单排(四) - 制作一个iOS游戏

    提要 此篇是一个国外教程的翻译,尽管有点老,可是适合新手入门. 自己去写代码.debug,布置场景,能够收获到非常多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一 ...

  9. iOS ,呼叫捕获抛出勉未知方法的障碍

    iOS 捕获未知方法的调用,避勉抛出异常 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 ...

  10. (适合入门)JVM堆内存相关的启动参数:年轻一代、岁和永久代内存分配

    假设你要观察JVM进程消耗的堆内存,通过命令工具jmap或可视化工具jvisualvm.exe.JVM这些参数的默认启动值.假设你想知道JVM内存分配策略,最开始手动设置这些参数.通过JDK统计结果, ...