简易解inode802.1x认证实战(6)交叉编译

3 篇文章 0 订阅
1 篇文章 0 订阅

简易解inode认证实战


1

2

3

4

5

6、交叉编译


经过一番折腾,我们终于写完了这一个认证过程,并且在Linux系统上运行正常。

本篇主要内容为编译&&交叉编译


 Hello World编译流程:

一、假定我们有这么一个helloworld.c的文件

#include <stdio.h>
#include <stdlib.h>
int main()
{
    printf("hello world");
    return 0;
}

(1)我们可以用gcc来编译

gcc -c helloworld.c

 命令执行后,没有错误的话,会多出一个文件helloworld.o

(2)也可以用g++来编译

g++ -c helloworld.c 

同样的,多出了.o文件

(3)连接,同样用gcc或者g++都可以

gcc helloworld.o -o helloworld

g++ helloworld.o -o helloworld

 执行完后,会有如下:helloword文件,

输入如下命令执行:

./helloworld

 二、如果我们的文件是cpp文件,即C++

#include <iostream> 
using namespace std;
int main()
{
    cout<<"hello world"<<endl;
    return 0;
}

 则,编译:可用gcc或g++,   连接:一般只能用g++。

 若链接用gcc,大概会报如下错误:

三、关于Makefile

我们可以使用makefile来将编译和连接的步骤连起来,相当于一个脚本

.c的Makefile

helloworld : helloworld.o
	$(CC) $(LDFLAGS) helloworld.o -o helloworld
 
helloworld.o : helloworld.c
	$(CC) $(CFLAGS) -c helloworld.c
 
clean :
	rm *.o

.cpp的Makefile

helloworld : helloworld.o
	$(CXX) $(LDFLAGS) helloworld.o -o helloworld
 
helloworld.o : helloworld.cpp
	$(CXX) $(CFLAGS) -c helloworld.cpp
 
clean :
	rm *.o

就是把CC改成CXX而已,

CC:指用gcc

CXX:指用g++

然后在目录下执行make,即生成.o 以及执行文件helloworld

执行make clean,则会清除.o文件


 一、Debian Linux下编译&&连接

(1)先检查一下我们的代码包括了哪些文件

  • main.cpp
  • MD5.cpp
  • MD5.h
  • packethandle.cpp
  • packethandle.h

 (2)由上面的helloworld例子,我们可以跟着写出Makefile如下,注意到是CPP,因此用CXX:

Makefile:

main : main.o MD5.o packethandle.o
	$(CXX) $(LDFLAGS) main.o MD5.o packethandle.o  -lpcap  -Istdc++ -o main

MD5.o : MD5.h MD5.cpp
	$(CXX) $(CFLAGS) -c MD5.cpp

packethandle.o : packethandle.h packethandle.cpp
	$(CXX) $(CFLAGS) -c packethandle.cpp -lpcap

main.o : main.cpp
	$(CXX) $(CFLAGS) -c main.cpp -lpcap

clean :
	rm *.o 

(3)执行一下make,不报错的话,有如下文件

(4)测试一下文件是否可以正常运行:

ok,正常运行,那么在Debian Linux下编译连接工作就到这里。接下来就是交叉编译了


二、交叉编译

(1)先确定好固件类型、版本号,我们才能选择对应的SDK,否则编译出来的程序不能在平台上运行【很重要】

比如我有不可描述的K2路由器,则进入192.168.1.1,描述如下

可以看到,我们路由器运行pandoraBox 17.09版本

 当然,我们也可以用xshell,192.168.1.1,端口22,连接后有如下,也可以看版本

(2)确定版本后,我们选择对应SDK下载【当然,也要知道你路由器的硬件配置,主要是CPU】

(3)将下载文件放入虚拟机,(必备啊)

  • mkdir build         我新建了个文件夹来放
  • tar xvJf  ***.tar.xz  ,解压
tar xvjf PandoraBox-SDK-ralink-mt7620_gcc-4.8-linaro_uClibc-1.0.x.Linux-x86_64.tar.xz 
  • 解压完后,需要在bashrc文件上加入对应环境
  • 可以改/etc/bash.bashrc  或者/home/$USER/.bashrc    ,$USER是你的用户名,自行替换即可
  • 这里我改/home/$USER/.bashrc 文件
gedit /home/msi/.bashrc

 在文件末尾,添加类似如下,至于路径,则自行根据环境修改【即不要直接复制我的,根据自己环境修改】

export PATH=$PATH:/home/msi/build/PandoraBox-SDK-ralink-mt7620_gcc-4.8-linaro_uClibc-1.0.x.Linux-x86_64/PandoraBox-SDK-ralink-mt7620_gcc-4.8-linaro_uClibc-1.0.x.Linux-x86_64/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-1.0.x/bin
export STAGING_DIR=/home/msi/build/PandoraBox-SDK-ralink-mt7620_gcc-4.8-linaro_uClibc-1.0.x.Linux-x86_64/PandoraBox-SDK-ralink-mt7620_gcc-4.8-linaro_uClibc-1.0.x.Linux-x86_64/staging_dir/

(4)检查toochains环境配置是否完成

  • 在命令行中输入lip, 按TAB,看是否会自动补全
  • 如下:

 自动补全,则环境配置完成 

(5)尝试利用mipsel-openwrt-linux-gcc,来编译连接我们刚刚的helloworld

  • 在helloworld目录下,执行
mipsel-openwrt-linux-g++ -c helloworld.cpp
mipsel-openwrt-linux-g++  helloworld.o -o helloworld

 如果编译链接报错,那么可能是本机缺少一些SDK运行所需的库,先检查一下,

一个关键的c库【提示什么cloog、C compiler cannot可以尝试以下来解决】:

sudo apt-get install ccache
sudo apt-get update
sudo apt-get install git-core build-essential libssl-dev libncurses5-dev unzip gawk
sudo apt-get install subversion mercurial

 

  • 这个操作,实际上就是交叉编译了,我们利用的是SDK中的Pandorabox平台的编译器
  • 这个过程,很像上面一开始的编译连接过程,只不过是gcc变成了lip。。。。-gcc。
  • 我们尝试在Debian Linux下执行编译出来的文件,提示错误,这是正常的,因为这是openwrt环境下的可执行文件

(6) 接下来,将这个helloworld文件,从虚拟机拖到电脑上,再利用winscp工具,将它上传到路由器上,看能否执行

  • winscp到处都能下,就不提供下载地址了
  • 上传的步骤如下:
  • 打开winscp,登录 192.168.1.1 账户 root 密码 admin,然后将helloworld拖到root目录下

  •  再登录XSHELL,执行如下:
chmod +x helloworld
./helloworld
  • 如果可正常输出,则表示SDK版本选择对了
  • 如果提示缺失一个什么libstdc++.so.6文件,而你的路由此时不能上网,那么可以回到虚拟机,在SDK的文件下中寻找该文件,然后将libstdc++.so.6文件拖到路由器的/lib 目录即可
  • 如果提示segment fault,那么很可能你的SDK版本对不上你的固件,也有可能是程序的问题,但是一般helloworld不会出现这个问题,所以helloworld的作用也在这里体现了
  • 如果你的libstdc++.so.6文件是网上下载的,也有可能版本不对,貌似也会出现segment fault的问题
  • 如果执行输出如下,恭喜你,可以进行下一步操作了

 (7)既然成功交叉编译了hellowrold,那么我们可以用同样的套路来编译我们的认证程序

  • 在程序目录下,依次执行
mipsel-openwrt-linux-g++ -c MD5.cpp
mipsel-openwrt-linux-g++ -c packethandle.cpp
mipsel-openwrt-linux-g++ -c main.cpp 
  • 链接obj
mipsel-openwrt-linux-g++ main.o MD5.o packethandle.o -o main
  • 一般来说,会报错如下:

 原因是,我们的认证程序用到了libpcap,而这个libpcap并没有在SDK的平台上,因此,我们需要给它装上这个库

a)下载libpcap-1.6.2

链接:https://pan.baidu.com/s/16RO8ByXcXclj0Cbgoe105Q 提取码:o7dl 

b)解压,进入对应文件夹 

c)安装,注意并非安装到本机目录,而是要安装到SDK的目录下,因此./configure时,要添加参数

./configure --host=mipsel CC=/home/msi/build/PandoraBox-SDK-ralink-mt7620_gcc-4.8-linaro_uClibc-1.0.x.Linux-x86_64/PandoraBox-SDK-ralink-mt7620_gcc-4.8-linaro_uClibc-1.0.x.Linux-x86_64/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-1.0.x/bin/mipsel-openwrt-linux-gcc --prefix=/home/msi/build/PandoraBox-SDK-ralink-mt7620_gcc-4.8-linaro_uClibc-1.0.x.Linux-x86_64/PandoraBox-SDK-ralink-mt7620_gcc-4.8-linaro_uClibc-1.0.x.Linux-x86_64/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-1.0.x/ --with-pcap=linux

--host 表示你要安装的平台,然后  CC= 填写你SDK中toolchain-mipsel,gcc的地址,

--prefix表示安装的路径,--with-pcap=linux , 【路径那些,按照你的本地环境SDK路径改就好了】

d)安装成功,继续操作

  • 再次链接obj,这时要加上参数  -pcap,表示用这个库
mipsel-openwrt-linux-g++ main.o MD5.o packethandle.o -pacp -o main

 这时候应该就可以链接成功了,生成如下

(8)路由器上测试我们的程序

  • 同样winscp上传
  • chmod +x main
  • ./main
  • 如果提示缺失libstdc++.so.6,按上面提到的方法处理即可【后面会有更好的方法解决】
  • 如果提示缺libpcap库,这里给一个下载地址尝试安装该库:链接:https://pan.baidu.com/s/15wWwMcqzaMnpIYWD6-Ihdw 提取码:mcfd   【一般来说应该不会,貌似我们的程序静态编译了这个库?】
  • 路由器opkg安装ipk文件,貌似要进行配置,请参见:https://blog.csdn.net/weixin_29465425/article/details/82668292

成功运行如下:

(9)到这里,我们的交叉编译可执行文件基本就OK了。接下来会讲利用SDK生成IPK安装包


 三、利用SDK生成IPK安装包

(1)如果我们交叉编译的可执行文件可以在路由上运行,那么实际上已经成功了大半

(2)接下来,我们还是先以helloworld为例子,生成其ipk文件

  • 进入程序文件夹,新建一个src文件夹,并将helloworld.cpp  Makefile移入src文件夹
  • 检查src文件夹内的Makefile文件
  • src:Makefile:  里面都是$(CXX), 而不是直接的g++,因为生成ipk时会自动改成mipsel-openwrt-linux-g++
helloworld : helloworld.o
	$(CXX) $(LDFLAGS) helloworld.o -o helloworld
 
helloworld.o : helloworld.cpp
	$(CXX) $(CFLAGS) -c helloworld.cpp
 
clean :
	rm *.o

(3)我们在原来Makefile【上面的Makefile已经被移到src文件夹了】的位置,重新建一个Makefile:

警告:从这里复制过去的Makefile,可执行命令前面都变成空格,请自行将空格重新替换为TAB,否则接下来你会很头疼,会提示什么missing separator

include $(TOPDIR)/rules.mk

PKG_NAME:=helloworld
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)

include $(INCLUDE_DIR)/package.mk

define Package/helloworld
	SECTION:=utils
	CATEGORY:=Utilities
	TITLE:=Helloworld -- prints a snarky message
endef

define Package/helloworld/description
	It's my first package demo.
endef

define Buile/Prepare
	mkdir -p $(PKG_BUILD_DIR)
	$(CP) ./src/* $(PKG_BUILD_DIR)/
endef

define Package/helloworld/install
	echo "Here is Package/install***********************"
	$(INSTALL_DIR) $(1)/bin
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/bin/
endef

$(eval $(call BuildPackage,helloworld))
  • 关于Makefile,这里不说太多【因为个人也不太懂】
  • 只讲关键的:
  • PKG_NAME:=  _这里填文件夹的名字_, 例:文件夹名字为helloworld,则填hellworld
  • define Package/_这里同上_,  即宏定义中Package/后面跟着文件夹名字,
  • 重点:define Package/helloworld/install 宏定义中,第三条 $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/bin/   ,红字helloworld并非代表文件夹,而是代表最终输出的可执行文件的名字,如果你src中的Makefile 链接 -o main,则红字改成main
  • 其他一般不会有太大改动

(4)到这里,文档编辑类基本完成,先看看目录包含什么:

(5)接下来,将整个文件夹复制到SDK目录的Package目录下

(6)在SDK目录下,执行 make menuconfig,如果提示错误,请检查依赖库是否安装(自行百度)

make menuconfig

出现如下界面:

  • 可在键盘敲 "/",进入搜索模式,然后输入helloworld进行搜索,搜索结果显示在Utilities,选择它,按空格进入
  • 选中helloworld,按空格,使它前面的M变成*号,表示参加build
  • 保存,退出

 (7)返回命令行,执行

make package/helloworld/compile

输出:

然后报错如下:

Package helloworld is missing dependencies for the following libraries:
libstdc++.so.6

 说少了这个依赖库,但是实际上我们是可以在SDK包中找到这个文件的,查找结果如下:

结合实际编译执行的感受,他这个提示可能是说,他这个版本的固件本身不带这个库,实际操作上也是,编译CPP程序到刷了这个PandoraBox 17.09固件上执行,会提示缺失这个库

解决方案:

解决方案参考自:https://my.oschina.net/hevakelcj/blog/411944  ,并对其方案三(这里的方案2)作出了修正

方案(1):在 Makefile 中的 Package/helloworld/install 宏中准备所需的库文件,即可以在这个宏里,将它需要的几个库文件复制到 $(1) 对应的目录下。

即修改Makefile:

define Package/helloworld/install
    $(INSTALL_DIR) $(1)/bin
    $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/bin

    $(INSTALL_DIR) $(1)/usr/lib
    $(INSTALL_DATA) $(TOOLCHAIN_DIR)/lib/libstdc++.so.6 $(1)/usr/lib
endef

警告:从这里复制过去的Makefile,可执行命令前面都变成空格,请自行将空格重新替换为TAB,否则接下来你会很头疼,会提示什么missing separator

 方案(2):在 Makefile 文件的 Package/helloworld宏中加 DEPENDS 描述

define Package/helloworld
    ...<略>
    DEPENDS+=libstdcpp
endef

警告:从这里复制过去的Makefile,可执行命令前面都变成空格,请自行将空格重新替换为TAB,否则接下来你会很头疼,会提示什么missing separator

 (8)Makefile修改完成后,重新 make package/helloworld/compile

make package/helloworld/compile

这时候应该没有报错了。

我们去bin目录看一下生成的IPK

 (9)对于我们的认证程序,操作步骤基本同步骤(1)~(8),这里就不再展示了

(10)将编译完成的IPK上传的路由器root目录,进行安装

chmod +x helloworld_1_mipsel_24kec_dsp.ipk
opkg install helloworld_1_mipsel_24kec_dsp.ipk

安装完成后,直接用helloworld,即可执行

(11)如果编译过程中,make Package/inode/compile,报错如下:

Package inode is missing dependencies for the following libraries:
libc.so.6
libm.so.6
libpcap.so.0.8
 

建议清理 掉所有的.o和可执行文件,重新生成 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值