交叉编译(二)

1. 交叉编译工具链配置

1.1 关于编译

• 编译是指将源代码文件(如C/C++文件)经过预处理、编译、汇编和链接 等步骤,转换为可执行文件的过程。将源代码转换成机器代码的过程称为编译(Compile),编译的工作需要编译器(Complier)来完成。
• 如图:

1.2 本地编译

• 本地编译是指在当前的编译平台上编译,生成能在当前平台上运行的可执行文件。例如,在x86平台上,使用x86平台上的工具,开发针对x86平台本身的可执行程序,这个编译过程称为本地编译。

1.3 交叉编译

• 交叉编译是指在当前的编译平台上编译,生成能在另一种目标平台上可以运行的可执行文件(编译平台和目标平台的体系结构是不同的)。例如,在x86平台上,使用ARM平台的工具,开发针对ARM平台的可执行程序,这个编译过程称为交叉编译。

1.3.1 例子

cpp 复制代码
#include <stdio.h>

int main()
{
    printf("Hello, world!\n");
    return 0;
}

• 想要在x86平台上进行交叉编译,并在ARM平台上运行这个程序。首先需要在家目录下的**.bashrc**最后配置添加交叉编译工具链,最后面添加

cpp 复制代码
export PATH=$PATH:/home/$(whoami)/orangepi-build/toolchains/gcc-arm-9.2-2019.12-
x86_64-aarch64-none-linux-gnu/bin

• 然后断开重连桌重新登陆后, 执行export指令,即可看到最新导入的PATH环境变量:

cpp 复制代码
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/bzy/orangepi-build/orangepi-build/toolchains/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin"

• 同时执行aarch64-none-linux-gnu-gcc --version可以看到对应的版本号:

cpp 复制代码
aarch64-none-linux-gnu-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025
Copyright © 2019 Free Software Foundation, Inc.

• 在x86平台上进行交叉编译,可以使用以下命令:

cpp 复制代码
aarch64-none-linux-gnu-gcc -o hello hello.c

• 利用file命令可以看到编译出来的程序是ARM aarch64的二进制程序 :file hello
• 这时候需要将该文件拷贝到比如香橙派等ARM开发板上运行, 在X86宿主机上是无法正常运行的。用scp hello orangepi@地址:/home/orangepi

2. 交叉编译wiringPi库

• 步骤:

2.1 修改build.sh脚本,在echo "WiringPi Library" 之前添加:

cpp 复制代码
mkdir $PWD/_INSTALL/usr/local/bin -p
mkdir $PWD/_INSTALL/usr/local/include -p
mkdir $PWD/_INSTALL/usr/local/lib -p

2.2 修改devLib/Makefile、gpio/Makefile、wiringPiD/Makefile

cpp 复制代码
将所有Makefile中的CC := gcc 改成 CC := aarch64-none-linux-gnu-gcc

2.3 修改devLib/Makefile、gpio/Makefile、wiringPiD/Makefile 、wiringPi/Makefile

cpp 复制代码
修改DESTDIR?=/usr 替换为DESTDIR?= $(shell pwd)/../_INSTALL/usr

2.4 修改wiringPi/Makefile,修改devLib/Makefile

cpp 复制代码
1、将$Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION)
$(DESTDIR)/lib/libwiringPi.so修改为:$Q ln -sf
$(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION)
$(DESTDIR)$(PREFIX)/lib/libwiringPi.so
cpp 复制代码
将$Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION)
$(DESTDIR)/lib/libwiringPiDev.so修改为:$Q ln -sf
$(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION)
$(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so

2.5. devLib/Makefile

cpp 复制代码
INCLUDE = -I. 修改为INCLUDE = -I. -I$(DESTDIR)$(PREFIX)/include

2.6 然后执行

cpp 复制代码
/build

后面我们就可以把_INSTALL里的内容拷贝到香橙派的根目录下,然后执行:sudo ldconfig
就可以使用该库了,可以使用:sudo gpio readall ,测试库是否链接正常。

3. 交叉编译垃圾识别

• 增加3rd目录,用于存放wiringOP和python3.10等第三方依赖库和头文件。
• 目录:

3.1 Makefile

cpp 复制代码
# 编译器
# CC := aarch64-none-linux-gnu-gcc # 版本太老了
CC := aarch64-linux-gnu-gcc
# 源文件
SRC := $(shell find src -name *.c)
# 头文件路径
INC := ./inc \
		./3rd/usr/local/include \
		./3rd/usr/include/ \
		./3rd/usr/include/python3.10 \
		./3rd/usr/include/aarch64-linux-gnu \
		./3rd/usr/include/aarch64-linux-gnu/python3.10

# 库路径
LIBS_PATH := ./3rd/lib/aarch64-linux-gnu \
			 ./3rd/usr/lib/python3.10/config-3.10-aarch64-linux-gnu \
			 ./3rd/usr/lib/aarch64-linux-gnu \
			 ./3rd/usr/local/lib \


# 将头文件链接
CFLAGS := $(foreach item,$(INC),-I$(item)) # -I./inc -I./3rd/usr/local/include

# 链接库路径
LDFLAGS := $(foreach item,$(LIBS_PATH),-L$(item)) # -L./3rd/usr/local/libs

# 链接库
LIBS := -lwiringPi -lpython3.10 -lpthread -lexpat -lz -lcrypt

# 将SRC里面的.c替换成.o并放在obj文件夹
OBJ := $(subst src/,obj/,$(SRC:.c=.o))

# 目标
TARGET := obj/garbage

# 编译.c文件为.o文件,并放到obj这个文件夹
# mkdir -p obj保证obj目录一直在
obj/%.o:src/%.c
	mkdir -p obj
	$(CC) -o $@ -c $< $(CFLAGS)

# 生成garbage目标
$(TARGET) : $(OBJ)
	$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)

compile:$(TARGET)
clean : 
	rm $(TARGET) obj $(OBJ) -rf

.POTHY:compile clean debug

debug:
	echo $(CC)
	echo $(SRC)
	echo $(INC)
	echo $(LIBS_PATH)
	echo $(CFLAGS)
	echo $(LDFLAGS)
	echo $(LIBS)
	echo $(OBJ)


# dekg的时候,不会帮助我们创建软链接,需要自己去手动创建
# 需要加上这三条
ln -s libz.so.1.2.11 libz.so
ln -s libcrypt.so.1.1.0 libcrypt.so
ln -s libexpat.so.1.8.7 libexpat.so

• 如图,到对应的目录去手动创建软连接:

相关推荐
xlq223227 分钟前
43.线程同步
大数据·linux
charlie1145141919 分钟前
嵌入式Linux驱动开发指南02——内核空间基础与硬件访问
linux·运维·c语言·驱动开发·嵌入式硬件
zzzsde26 分钟前
【Linux】进程信号(1)理解信号及信号产生的方式
linux·运维·服务器·算法
DBA大董34 分钟前
TDengine3.x 数据文件详解
大数据·linux·时序数据库·dba·tdengine
生万千欢喜心1 小时前
Linux 安装金蝶天燕中间件 AAS-V9.0.zip
java·linux
aq55356001 小时前
三大Linux系统终极对决
linux·运维·服务器
sssjjww2 小时前
服务器不同路径下找conda
linux·运维·服务器
思麟呀2 小时前
网络层IP协议
linux·服务器·网络·网络协议·tcp/ip·计算机网络
执笔画流年呀2 小时前
计算机是如何⼯作的
linux·开发语言·python
keyipatience3 小时前
4.5 Linux指令和权限
linux·运维·服务器