交叉编译(二)

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

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

相关推荐
小白同学_C9 小时前
Lab4-Lab: traps && MIT6.1810操作系统工程【持续更新】 _
linux·c/c++·操作系统os
今天只学一颗糖9 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
不做无法实现的梦~11 小时前
ros2实现路径规划---nav2部分
linux·stm32·嵌入式硬件·机器人·自动驾驶
默|笙13 小时前
【Linux】fd_重定向本质
linux·运维·服务器
陈苏同学13 小时前
[已解决] Solving environment: failed with repodata from current_repodata.json (python其实已经被AutoDL装好了!)
linux·python·conda
“αβ”13 小时前
网络层协议 -- ICMP协议
linux·服务器·网络·网络协议·icmp·traceroute·ping
不爱学习的老登14 小时前
Windows客户端与Linux服务器配置ssh无密码登录
linux·服务器·windows
小王C语言15 小时前
进程状态和进程优先级
linux·运维·服务器
xlp666hub15 小时前
【字符设备驱动】:从基础到实战(下)
linux·面试
弹幕教练宇宙起源16 小时前
cmake文件介绍及用法
android·linux·c++