關(guān)鍵字:Ubuntu瓜贾、WSL1祭芦、arm-oe-linux-gnueabi-gcc、交叉編譯龟劲、找不到該文件
1 前言
原先個(gè)人編譯程序都是在Virtual Box的Linux虛擬機(jī)上進(jìn)行編譯的昌跌,可是在使用一段時(shí)間后就會(huì)因?yàn)閮?nèi)存不夠的原因會(huì)變得十分的卡頓,并且卡頓后很容易迎來虛擬機(jī)系統(tǒng)的崩潰答恶,因?yàn)樵创a是直接放在Linux虛擬機(jī)上編輯的审胸,一旦虛擬機(jī)崩潰卸勺,自己的整個(gè)源代碼工程也就壞掉了,十分讓人煩惱碍庵,嚴(yán)重影響開發(fā)效率悟狱。
在接觸到微軟的WSL之后,自己便萌生了在WSL中進(jìn)行交叉編譯的想法苹享。查看任務(wù)管理器發(fā)現(xiàn)WSL占用的內(nèi)存資源也是比較小的浴麻,只要將需要編譯的代碼直接放Windows文件系統(tǒng)下的硬盤软免,然后Windows下編輯,WSL中編譯膏萧,一氣呵成,十分的方便蝌蹂。如前面的需求所述,這里采用WSL1進(jìn)行交叉編譯鏈的配置亩冬。
2 環(huán)境
- 交叉編譯器:arm-oe-linux-gnueabi-gcc(硬件模塊供應(yīng)商提供)
- 操作系統(tǒng):Microsoft Windows 11
- WSL:Ubuntu 20.04.2 LTS(使用WSL1)
- 系統(tǒng)工具:Windows Terminal
3 具體方法
3.1 解壓交叉編譯鏈
模塊供應(yīng)商所提供的交叉編譯鏈為oecore-x86_64.tar.bz2硅急,并提供了配置的指令佳遂。我自己這里是將之前虛擬機(jī)已配好的編譯鏈打包成了oecore-x86_64.zip,實(shí)際上只是對(duì)這個(gè)交叉編譯鏈解壓到相應(yīng)的目錄環(huán)境下:
# 供應(yīng)商提供的壓縮包
sudo tar xvjf oecore-x86_64.tar.bz2 -C /usr/local/
# 自己的oecore-x86_64.zip壓縮包使用unzip命令
sudo unzip oecore-x86_64.zip -d /usr/local/
3.2 配置交叉編譯鏈環(huán)境變量
交叉編譯鏈解壓完畢后荚板,要確認(rèn)里頭提供的編譯程序是否可用吩屹,就需要使用命令arm-oe-linux-gcc -v
,這時(shí)候發(fā)現(xiàn)找不到該命令:
veahow@VEAHOW-AMADEUS:~$ arm-oe-linux-gcc -v
arm-oe-linux-gcc: command not found
這個(gè)實(shí)際上是環(huán)境變量中沒有配置交叉編譯鏈所在的路徑免绿,進(jìn)入/usr/local/
中就能夠看到之前解壓交叉編譯鏈的oecore-x86_64文件夾:
veahow@VEAHOW-AMADEUS:~$ ls
veahow@VEAHOW-AMADEUS:~$ cd /usr/local/
veahow@VEAHOW-AMADEUS:/usr/local$ ls
bin etc games include lib man oecore-x86_64 sbin share src usr
veahow@VEAHOW-AMADEUS:/usr/local$ cd oecore-x86_64/
veahow@VEAHOW-AMADEUS:/usr/local/oecore-x86_64$ ls
environment-setup-armv7a-vfp-neon-oe-linux-gnueabi sysroots/
site-config-armv7a-vfp-neon-oe-linux-gnueabi version-armv7a-vfp-neon-oe-linux-gnueabi
進(jìn)入oecore-x86_64文件夾我們發(fā)現(xiàn)交叉編譯鏈提供了環(huán)境變量的相關(guān)配置指令嘲驾,這時(shí)候只需要使用該句就可以生效:
# 相對(duì)路徑下
source environment-setup-armv7a-vfp-neon-oe-linux-gnueabi
# 絕對(duì)路徑下
source /usr/local/oecore-x86_64/environment-setup-armv7a-vfp-neon-oe-linux-gnueabi
這時(shí)候我們就能夠得到這一編譯器的詳細(xì)版本信息:
veahow@VEAHOW-AMADEUS:~$ arm-oe-linux-gnueabi-gcc -v
Using built-in specs.
COLLECT_GCC=./arm-oe-linux-gcc
COLLECT_LTO_WRAPPER=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-linux/usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/4.9.3/lto-wrapper
Target: arm-oe-linux-gnueabi
Configured with: ...(此處省略)
Thread model: posix
gcc version 4.9.3 (GCC)
但是當(dāng)WSL終端關(guān)閉后辽故,新打開的WSL終端使用arm-oe-linux-gcc -v
指令時(shí)就會(huì)又提示找不到命令了腐碱,這時(shí)我們就需要在~/.bashrc
文件末尾加上一行前面的source /usr/local/oecore-x86_64/environment-setup-armv7a-vfp-neon-oe-linux-gnueabi
生效指令。這樣喂走,每次我們打開WSL終端的時(shí)候筒饰,都會(huì)去配置這一環(huán)境變量。
3.3 交叉編譯程序
我們直接來交叉編譯一個(gè)簡單的程序:
//test.c
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("hello world!\n");
return 0;
}
使用編譯命令arm-oe-linux-gnueabi-gcc test.c -o test.out
业栅,沒想到卻直接報(bào)錯(cuò):
veahow@VEAHOW-AMADEUS:/mnt/d/Project$ arm-oe-linux-gnueabi-gcc test.c -o test.out
test.c:1:19: fatal error: stdio.h: No such file or directory
#include <stdio.h>
^
compilation terminated.
這里直接提示沒有找到頭文件stdio.h
,這是因?yàn)槟J(rèn)配置是在/usr/include/
中來尋找文件的携取,經(jīng)過網(wǎng)上資料查閱帮孔,可以使用--sysroot
選項(xiàng)進(jìn)行指定。
arm-oe-linux-gnueabi-gcc --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-ne
on-oe-linux-gnueabi/ test.c -o test.out
編譯成功可以使用file
命令來查看文件的狀態(tài):
veahow@VEAHOW-AMADEUS:/mnt/d/Project$ file test.out
test.out: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=d982823a4dc093d3cddfef4ab15fe25236a0de01, not stripped
4 遇到的問題
4.1 路徑依賴
原本自己并不想將交叉編譯鏈安裝在/usr/local/
目錄下晤斩,而是想直接存放在硬盤某個(gè)專門的軟件包目錄里澳泵,不依賴WSL兼呵,例如放在/mnt/d/Software
文件夾下,也就是Windows下D盤的Software文件夾维苔,結(jié)果就出現(xiàn)了無法運(yùn)行交叉編譯鏈的問題懂昂,直接進(jìn)入到命令目錄下,使用如下命令也無法運(yùn)行:
./arm-oe-linux-gnueabi-gcc -v
無法運(yùn)行 -bash: ./arm-oe-linux-gnueabi-gcc: No such file or directory
實(shí)際上自己就在這個(gè)命令存放的目錄下潮尝,這樣都無法運(yùn)行讓我十分疑惑饿序,查閱資料有的說是64位操作系統(tǒng)無法運(yùn)行32位的指令羹蚣,但是供應(yīng)商提供的軟件包都很明顯是支持64位系統(tǒng)運(yùn)行的顽素,這讓我陷入了配置怪圈。最后使用file
命令查看型型,發(fā)現(xiàn)是依賴于特定路徑下的某個(gè)動(dòng)態(tài)庫導(dǎo)致實(shí)際運(yùn)行時(shí)找不到而報(bào)錯(cuò)全蝶。
file arm-oe-linux-gcc
arm-oe-linux-gcc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /usr/local/oecore-x86_64/sysroots/x86_64-oesdk-linux/lib/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=c607472f349b110298ad9907d7039dd05d914196, stripped
根據(jù)該句interpreter /usr/local/oecore-x86_64/sysroots/x86_64-oesdk-linux/lib/ld-linux-x86-64.so.2
寺枉,我們可以推斷這個(gè)交叉編譯鏈在生成的時(shí)候就指定了要依賴這個(gè)路徑/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-linux/lib/
下的動(dòng)態(tài)庫ld-linux-x86-64.so.2
姥闪,所以只能乖乖按照供應(yīng)商的要求解壓到/usr/local
下砌烁。實(shí)際在部署程序到板子上的時(shí)候,可能也會(huì)比較容易遇見這種問題避归。
4.2 直接編譯代碼工程提示popd: not found
這個(gè)和Ubuntu的特性有關(guān)系管呵,這里我使用的是Ubuntu 20.04 LTS,屬于高版本的Ubuntu顿天,其默認(rèn)的shell就是dash蔑担。可以使用ls -l /bin/sh
查看sh鏈接的是何種shell程序鸟缕,使用如下命令即可解決:
sudo ln -fs /bin/bash /bin/sh
有些shell腳本因?yàn)榭紤]到這個(gè)因素排抬,經(jīng)常會(huì)在文件頭部加上#!/bin/bash
來強(qiáng)制指定shell使用bash命令蹲蒲。
5 參考文章
- 比較 WSL 1 和 WSL 2 | Microsoft Docs
- gcc - cross compilation for ARM: error no such file or directory - Ask Ubuntu
- 解決Linux程序編譯鏈接動(dòng)態(tài)庫版本的相關(guān)問題Linux腳本之家 (jb51.net)
- gcc 運(yùn)行指定動(dòng)態(tài)庫的三種方法__kerneler的博客-CSDN博客_gcc 指定動(dòng)態(tài)庫
- gcc - Compiling problems: cannot find crt1.o - Stack Overflow
- 如何更改GCC的crti.o默認(rèn)搜索目錄? - Thinbug
- 交叉編譯遇到bin/ld: cannot find crt1.o: No such file or directory問題解決_fanchenxinok的專欄-CSDN博客
- gcc -l參數(shù)和-L參數(shù) - 郭振斌 - 博客園 (cnblogs.com)
- 如何配置gcc在特定位置搜索crt1.o和其他libc文件缘薛? - 技術(shù)翻譯 (jishufanyi.cn)