交叉编译openwrt php,交叉编译n2n,以openwrt为例子

交叉编译n2n,以openwrt为例子

预备知识

1 什么是交叉编译?

1.1 本地编译

简单粗暴的解释一下,在当前架构的pc下,直接由编译工具编译生成的程序或者是库文件,可以直接在当前的环境运行。这样的编译,可以叫做本地编译。在当前架构/平台下编译出来的程序,只能在当前架构/平台下运行。

1.2 交叉编译

交叉编译是一个相对的概念,就是在一种架构/平台下编译出来的程序或是库文件,放到别的架构/平台上运行。目标执行该程序的架构和环境不一样,属于交叉的编译。

交叉编译是做嵌入是开发的基本概念。

1.3 例子

就拿n2n来说,开发者提供了源码给我们,想要在各个平台上运行该程序,就需要交叉编译出不同目标平台/架构的应用程序,才能保证程序可以运行。

2 为什么需要交叉编译?

嵌入式系统中的资源太少!!

具体的解释就是:交叉编译出来的程序,所要运行的目标环境中,各种资源,都相对有限,所以很难进行直接的本地编译。

3 常见的平台,并非所有的

darwin_amd64

freebsd_386

freebsd_amd64

linux_386

linux_amd64

linux_arm

linux_arm64

linux_mips

linux_mips64

linux_mips64le

linux_mipsle

windows_386

windows_amd64

简单解释一下:amd64,说的就是64位的机器,386,说的是32位的机器。至于其他i686,x86等,大家可以自行搜索相关的关键字,了解一下,这里不做阐述了。

至于前缀,一目了然,不做说明。

4 还需要了解的基本概念

这个文档针对的是n2n但不限于其他知识的了解,简单的描述一下linux相关的基本概念。

4.1 linux用户

Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统。

管理员用户:root,拥有最高的权限。

当你登录了linux的时候,绝大多数机器默认使用的是bash交互环境,可以通过提示符区分用户。

root@soul-PC:~#

注意到上面的那一行,root便是只的是你当前用户,@后面的是主机,~表示的是当前用户[root]的家目录,通常是/root。最后的#号是最容易区分的,一般#号标示的就是root用户。

下面看看普通用户:

soul@soul-PC:~$

$ 符号,通常标示的是普通用户,

在绝大多数的情况下,我们用到的都是普通用户,一般机器登录也是普通用户。

在以后的编译过程中,我用的都是普通用户做演示。

当然,当你需要用到超级用户权限的时候,有很多的方式可以获得管理员权限。你可以装sudo软件包,这样,需要管理员权限的时候,只需要在命令前面加上sudo就可以了。

soul@soul-PC:~$ sudo ifconfig

4.2 环境变量

还是简单的介绍一下吧。

我们为什么可以使用Linux的命令,是因为linux系统的命令所在的路径,基本上行都是设置了环境变量。

注意:每个用的的环境变量可能不是一样的,环境变量可以全局配置,也可以某个用户自己配置自己的。

一般个人的linux‘系统,不需要做全局环境变量的配置。只需要在当前用户的家目录下修改配置文件就可以了。

我个人习惯是配置在.bashrc文件里配置。

soul@soul-PC:~$ pwd

/home/soul

soul@soul-PC:~$ ls -al .bashrc

-rw-r--r-- 1 soul soul 3822 6月 4 2018 .bashrc

我们可以用下面的命令来查看当然用户的环境变量:

soul@soul-PC:~$ echo $PATH

/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/sbin:/usr/sbin

看到我在soul用户下的环境变量路径有这些,意味着,在这个路径下的所有可以执行的文件,我都可以在任何地方使用他,比如ls 命令。

再说一下,一个命令它是放在哪里,它是什么,我怎么知道他?跟我做。举个例子,一ls命令为例子:

soul@soul-PC:~$ which ls #我要看ls在那个路径下

/bin/ls

soul@soul-PC:~$ whereis ls #我要看路径等其他的

ls: /bin/ls /usr/share/man/man1/ls.1.gz

soul@soul-PC:~$ type ls #我要看ls是什么类型的命令

ls 是 `ls --color=auto' 的别名

/bin/ 目录下,包含了我们常用的命令。就简单介绍到这里吧。环境变量的配置,后面会讲。

准备工作

要编译,就现在搭建环境,当然,你也得会一些常用的linux操作命令,基本常识。

一台linux机器(苹果也可以),虚拟机装linux也可以。

我的linux机子如下:

~$ uname -a

Linux soul-PC 4.15.0-21deepin-generic #21 SMP Mon May 21 05:20:09 UTC 2018 x86_64 GNU/Linux

OpenSSL 一会用的到

下载地址:http://distfiles.macports.org/openssl/

Openwrt 的 SDK 或 toolchain

首先你的知道openwrt的下载的官网,http://downloads.openwrt.org/,进入后你会看到各个版本和分支。这里我以Chaos Calmer 15.05.1为例子,我手里有一个联发科板子。

1546772790055.png

找到你对应的型号芯片

1546772871889.png

具体的芯片

1546772888985.png

进去里面有很多该芯片的各类固件!你不刷机,不要管。

1546772946464.png

找到sdk

1546772977778.png

我们只需要下载sdk开发工具就可以了!

下载以后解压出来,解压命令自己学习一下就行了。

注意,新的压缩包为了减小体积,是两层压缩,xz,结尾,tar结尾。所以你得解压两次。

soul@soul-PC:~/Downloads$ tar -jxvf OpenWrt-SDK-15.05.1-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar.bz2

更改一下sdk的名字,路径太长,如果有报错,不便于分析。

soul@soul-PC:~/Downloads$ mv OpenWrt-SDK-15.05.1-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64 sdk

接着把sdk复制到你偏爱的目录。

找到sdk的gcc工具目录

soul@soul-PC:~/op/sdk/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin$ ls

c_rehash mipsel-openwrt-linux-strip

g++-uc mipsel-openwrt-linux-uclibc-addr2line

g++-uc+std mipsel-openwrt-linux-uclibc-ar

ldd mipsel-openwrt-linux-uclibc-as

mipsel-openwrt-linux-addr2line mipsel-openwrt-linux-uclibc-c++

mipsel-openwrt-linux-ar mipsel-openwrt-linux-uclibc-c++filt

mipsel-openwrt-linux-as mipsel-openwrt-linux-uclibc-cpp

mipsel-openwrt-linux-c++ mipsel-openwrt-linux-uclibc-elfedit

mipsel-openwrt-linux-c++filt mipsel-openwrt-linux-uclibc-g++

mipsel-openwrt-linux-cpp mipsel-openwrt-linux-uclibc-gcc

mipsel-openwrt-linux-elfedit mipsel-openwrt-linux-uclibc-gcc-4.8.3

mipsel-openwrt-linux-g++ mipsel-openwrt-linux-uclibc-gcc-ar

mipsel-openwrt-linux-gcc mipsel-openwrt-linux-uclibc-gcc-nm

mipsel-openwrt-linux-gcc-4.8.3 mipsel-openwrt-linux-uclibc-gcc-ranlib

mipsel-openwrt-linux-gcc-ar mipsel-openwrt-linux-uclibc-gcov

mipsel-openwrt-linux-gcc-nm mipsel-openwrt-linux-uclibc-gdb

mipsel-openwrt-linux-gcc-ranlib mipsel-openwrt-linux-uclibc-gprof

mipsel-openwrt-linux-gcov mipsel-openwrt-linux-uclibc-ld

mipsel-openwrt-linux-gdb mipsel-openwrt-linux-uclibc-ld.bfd

mipsel-openwrt-linux-gprof mipsel-openwrt-linux-uclibc-nm

mipsel-openwrt-linux-ld mipsel-openwrt-linux-uclibc-objcopy

mipsel-openwrt-linux-ld.bfd mipsel-openwrt-linux-uclibc-objdump

mipsel-openwrt-linux-nm mipsel-openwrt-linux-uclibc-ranlib

mipsel-openwrt-linux-objcopy mipsel-openwrt-linux-uclibc-readelf

mipsel-openwrt-linux-objdump mipsel-openwrt-linux-uclibc-size

mipsel-openwrt-linux-ranlib mipsel-openwrt-linux-uclibc-strings

mipsel-openwrt-linux-readelf mipsel-openwrt-linux-uclibc-strip

mipsel-openwrt-linux-size openssl

mipsel-openwrt-linux-strings

接着添加环境比变量

soul@soul-PC:~/op/sdk/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin$ pwd

/home/soul/op/sdk/staging_dir/toolchain-mipsel_24kc_gcc-7.3.0_musl/bin

soul@soul-PC:~/op/sdk/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin$ gedit ~/.bashrc

在最后加上

export PATH=$PATH:/home/soul/op/sdk/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin

export STAGING_DIR=/home/soul/op/sdk/staging_dir

保存,退出

接着让配置文件生效,这样做:

soul@soul-PC:~/op/sdk/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin$ source ~/.bashrc

soul@soul-PC:~/op/sdk/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin$ echo $PATH

/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/sbin:/usr/sbin:/home/soul/op/sdk/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin

看到我们添加的环境变量已经生效了。此时你就可以在任何地方使用你的工具了。

在命令行敲mips[tab],应该能自动补全你的命令了。

接着编译一个简单的是程序,helloworld

#include

int main(int argc,char* argv[])

{

puts("Hello World!");

return 0;

}

soul@soul-PC:~/op/c$ mipsel-openwrt-linux-gcc -o hello hello.c

soul@soul-PC:~/op/c$ ls

hello hello.c

soul@soul-PC:~/op/c$ ./hello

bash: ./hello: cannot execute binary file: Exec format error

soul@soul-PC:~/op/c$

尝试在本机上执行文件,报错。不是可执行文件,那当然,这是在目标平台执行的文件,此时把文件放到你的目标机器上执行,就可以输出helloworld啦。

到此,基本环境已经搭建测试成功了。

交叉编译OpenSSL

下载源码,解压

下载地址:http://distfiles.macports.org/openssl/

soul@soul-PC:~/Downloads$ tar -zxvf openssl-1.0.2q.tar.gz

进入openssl目录,设置生成路径,不需要生成汇编

soul@soul-PC:~/op/openssl-1.0.2q$ ./config no-asm shared --prefix=/home/soul/op/sdk/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2

接着修改 MakeFile 文件 ,指定交叉编译的gcc

...

CC= mipsel-openwrt-linux-gcc

...

AR= mipsel-openwrt-linux-ar $(ARFLAGS) r

RANLIB= mipsel-openwrt-linux-ranlib

...

NM= mipsel-openwrt-linux-nm

...

MAKEDEPPROG= mipsel-openwrt-linux-gcc

同时,删除-m64,两个地方需要删除。

之后编译,最后,安装,编译时间看机器性能了。

soul@soul-PC:~/op/openssl-1.0.2q$ make

安装:

soul@soul-PC:~/op/openssl-1.0.2q$ make install

到此,openssl,编译结束

交叉编译n2n

好的 接下来我们下载源码:

~$ git clone https://github.com/meyerd/n2n.git

之后你就看到n2n的目录了。进去目录,看了下,可以使用cmake构建编译工程,我这里直接使用makefile编译,不使用cmake。

~$ cd n2n/n2n_v2/

~/n2n/n2n_v2(master)$ ls

benchmark.c gen_keyfile.py n2n.c n2n_wire.h supernode.1 twofish.c

benchmark_hashtable.c HACKING n2n.h NEW_FEATURES.txt transform_aes.c twofish.h

cmake/ INSTALL n2n_keyfile.c openwrt/ transform_null.c unix-scm.c

CMakeLists.txt lzoconf.h n2n_keyfile.h README transform_tf.c version.c

COPYING lzodefs.h n2n.spec scm.h tuntap_freebsd.c win32/

debian/ minilzo.c n2n_test.c scripts/ tuntap_linux.c wire.c

edge.8 minilzo.h n2n_transforms.h sglib.h tuntap_netbsd.c wireshark/

edge.c munin/ n2n_v2.7 sn.c tuntap_osx.c

~/n2n/n2n_v2(master)$

打开n2n工程目录,创建或者复制Makefile文件。

注意文件内容指定了“Makefile”,所以你创建文件的时候,名字也得大写M开头。

N2N_VERSION=2.1.0

N2N_OSNAME=$(shell uname -p)

########

CC= mipsel-openwrt-linux-gcc

DEBUG?=-g3

#OPTIMIZATION?=-O2

WARN?=-Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs

#Ultrasparc64 users experiencing SIGBUS should try the following gcc options

#(thanks to Robert Gibbon)

PLATOPTS_SPARC64=-mcpu=ultrasparc -pipe -fomit-frame-pointer -ffast-math -finline-functions -fweb -frename-registers -mapp-regs

N2N_DEFINES=

N2N_OBJS_OPT=

LIBS_EDGE_OPT=

N2N_OPTION_AES?="yes"

#N2N_OPTION_AES=no

ifeq ($(N2N_OPTION_AES), "yes")

N2N_DEFINES+="-DN2N_HAVE_AES"

LIBS_EDGE_OPT+=-lcrypto

endif

CFLAGS+=$(DEBUG) $(OPTIMIZATION) $(WARN) $(OPTIONS) $(PLATOPTS) $(N2N_DEFINES)

INSTALL=install

MKDIR=mkdir -p

INSTALL_PROG=$(INSTALL) -m755

INSTALL_DOC=$(INSTALL) -m644

# DESTDIR set in debian make system

PREFIX?=$(DESTDIR)/usr

#BINDIR=$(PREFIX)/bin

SBINDIR=$(PREFIX)/sbin

MANDIR?=$(PREFIX)/share/man

MAN1DIR=$(MANDIR)/man1

MAN7DIR=$(MANDIR)/man7

MAN8DIR=$(MANDIR)/man8

N2N_LIB=n2n.a

N2N_OBJS=n2n.o n2n_keyfile.o wire.o minilzo.o twofish.o \

transform_null.o transform_tf.o transform_aes.o \

tuntap_freebsd.o tuntap_netbsd.o tuntap_linux.o tuntap_osx.o version.o unix-scm.o

LIBS_EDGE+=$(LIBS_EDGE_OPT)

LIBS_SN=

#For OpenSolaris (Solaris too?)

ifeq ($(shell uname), SunOS)

LIBS_EDGE+=-lsocket -lnsl

LIBS_SN+=-lsocket -lnsl

endif

APPS=edge

APPS+=supernode

DOCS=edge.8.gz supernode.1.gz n2n_v2.7.gz

all: $(APPS) $(DOCS)

edge: edge.c $(N2N_LIB) n2n_wire.h n2n.h Makefile

$(CC) $(CFLAGS) edge.c $(N2N_LIB) $(LIBS_EDGE) -o edge

test: test.c $(N2N_LIB) n2n_wire.h n2n.h Makefile

$(CC) $(CFLAGS) test.c $(N2N_LIB) $(LIBS_EDGE) -o test

supernode: sn.c $(N2N_LIB) n2n.h Makefile

$(CC) $(CFLAGS) sn.c $(N2N_LIB) $(LIBS_SN) -o supernode

benchmark: benchmark.c $(N2N_LIB) n2n_wire.h n2n.h Makefile

$(CC) $(CFLAGS) benchmark.c $(N2N_LIB) $(LIBS_SN) -o benchmark

.c.o: n2n.h n2n_keyfile.h n2n_transforms.h n2n_wire.h twofish.h Makefile

$(CC) $(CFLAGS) -c $<

%.gz : %

gzip -c $< > $@

$(N2N_LIB): $(N2N_OBJS)

ar rcs $(N2N_LIB) $(N2N_OBJS)

# $(RANLIB) $@

version.o: Makefile

$(CC) $(CFLAGS) -DN2N_VERSION='"$(N2N_VERSION)"' -DN2N_OSNAME='"$(N2N_OSNAME)"' -c version.c

clean:

rm -rf $(N2N_OBJS) $(N2N_LIB) $(APPS) $(DOCS) test *.dSYM *~

install: edge supernode edge.8.gz supernode.1.gz n2n_v2.7.gz

echo "MANDIR=$(MANDIR)"

$(MKDIR) $(SBINDIR) $(MAN1DIR) $(MAN7DIR) $(MAN8DIR)

$(INSTALL_PROG) supernode $(SBINDIR)/

$(INSTALL_PROG) edge $(SBINDIR)/

$(INSTALL_DOC) edge.8.gz $(MAN8DIR)/

$(INSTALL_DOC) supernode.1.gz $(MAN1DIR)/

$(INSTALL_DOC) n2n_v2.7.gz $(MAN7DIR)/

至此,编译结束,看下生成的文件。

soul@soul-PC:~/n2n/n2n_v2$ ls

CMakeLists.txt edge.8 n2n.h scm.h transform_tf.o unix-scm.c

COPYING edge.8.gz n2n.o scripts tuntap_freebsd.c unix-scm.o

HACKING edge.c n2n.spec sglib.h tuntap_freebsd.o version.c

INSTALL gen_keyfile.py n2n_keyfile.c sn.c tuntap_linux.c version.o

Makefile lzoconf.h n2n_keyfile.h supernode tuntap_linux.o win32

NEW_FEATURES.txt lzodefs.h n2n_keyfile.o supernode.1 tuntap_netbsd.c wire.c

README minilzo.c n2n_test.c supernode.1.gz tuntap_netbsd.o wire.o

benchmark.c minilzo.h n2n_transforms.h transform_aes.c tuntap_osx.c wireshark

benchmark_hashtable.c minilzo.o n2n_v2.7 transform_aes.o tuntap_osx.o

cmake munin n2n_v2.7.gz transform_null.c twofish.c

debian n2n.a n2n_wire.h transform_null.o twofish.h

edge n2n.c openwrt transform_tf.c twofish.o

看了下edge,supmode文件,还是有点大,怎么办?可以soul@soul-PC:~/n2n/n2n_v2$ mipsel-openwrt-linux-strip edge supernode一下,稍微减小了一些体积。

在Makefile文件可以适当的参考gcc工具的用法,编译输出选项,调整后,体积也适当减小,这里不做阐述了。

未完,待更新。有建议或者意见留言评论。

90%(9)

10%(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值