Ubuntu中用VSCode交叉编译程序放到从机上运行

前言:

这篇博客是以树莓派CM4为例子进行阐述,其他的arm架构等开发板也可以采用这样的方式进行交叉编译

近期在交叉编译上踩坑颇多,这里针对近期做好的效果进行记录。
本文是的配置环境是:
树莓派CM4核心板+CM4拓展板
VMware下的Ubuntu18.04.6虚拟机
VSCode linux版本


1. 前期准备:

1.1 树莓派系统烧录与虚拟机创建

树莓派烧录系统参考我写的烧录博客
Ubuntu系统如何烧录到vmware参考我写的另一篇博客
VSCode在linux的下载教程参考:linux下载vscode

1.2 VSCode拓展下载

交叉编译前我们还需要下载一些拓展。
在这里插入图片描述
拓展插件大致如下:

(1)、C/C++,C 和 C++的编译环境(必须)
(2)、C/C++ Snippets,即 C/C++重用代码块。(必须)
(3)、C/C++ Advanced Lint,即 C/C++静态检测 。(必须)
(4)、Code Runner,即代码运行。(必须)
(5)、Include AutoComplete,即自动头文件包含。(高效)
(6)、Rainbow Brackets,彩虹花括号,有助于阅读代码。
(7)、One Dark Pro,VSCode 的主题。(非必须)
(8)、GBKtoUTF8,将 GBK 转换为 UTF8。
(9)、ARM,即支持 ARM 汇编语法高亮显示(非必须,但方便)
(10)、Chinese(Simplified),即中文环境。(看个人水平)
(11)、vscode-icons,VSCode 图标插件,主要是资源管理器下各个文件夹的图标。(美观)
(12)、compareit,比较插件,可以用于比较两个文件的差异。
(13)、DeviceTree,设备树语法插件。(非必须)
(14)、TabNine, AI 自动补全插件(高效)

2. 树莓派交叉编译链查询与下载

2.1 交叉编译链如何判断下哪一个

树莓派的交叉编译链工具根据个人所下载的树莓派系统有关,我这里下载的是树莓派lite64位版本。
如果忘了自己的树莓派系统是什么版本,可以在树莓派控制端输入指令:uname -a显示树莓派的系统的一些信息。
比如我的是:
Linux raspberrypi 5.15.84-v8+ #1613SMP PREEMPT Thu Jan 512.03.08 GMT 2023 aarch64 GNU/Linux
这里解释一下个字段含义,顺便给自己做个备忘。
系统名称:Linux
用户名:raspberrypi
操作系统的发行版号:5.15.84-v8+
内核版本:#1613SMP PREEMPT Thu Jan 512.03.08 GMT 2023
机器硬件(CPU名称):aarch64
操作系统名:GNU/Linux

通过上面的信息,我们可以知道我们队树莓派进行交叉编译的交叉编译工具链应该是aarch64-linux-gnu系列的,因此我们官网下载工具链->下载链接
在这里插入图片描述
在windows下载后,可以通过共享文件夹/U盘/SSH把交叉编译工具链放到linux的目录中,这里的目录后面会用到。我下面用到的目录是我自己放置交叉编译链的地方,大家可以自行设定。

2.2 交叉编译链各种版本含义

有的读者可能和我之前一样,不知道各种交叉编译链对应的意思,这里可以参考我转载的记录文章:
交叉编译详解


3. 开始操作

这个小节开始,开始详细记录整个交叉编译的流程。

3.1 创建helloworld程序

首先在虚拟机的主文件夹下创建Hello文件夹

在这里插入图片描述

打开VSCode选择打开文件夹,选择刚才的路径

在这里插入图片描述

在这里插入图片描述
创建hello.c文件
在这里插入图片描述这里可能会出现无法输入的情况,因为左下角这里不是insert模式,需要我们按一下a
在这里插入图片描述

输入测试代码:

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

3.2 配置交差编译链

在这里插入图片描述
这里的环境和配置都先选第一个,接着会改。

在这里插入图片描述
在这里插入图片描述
选择后,点击1所在位置,接着看2,针对我们的2框,下面做详细解释。
在这里插入图片描述

3.3 json文件说明与配置

VSCode最劝退人的一步大概率就是这个json文件的配置了,关于json文件的说明如下:
task.json是gcc编译产生可执行文件的配置文件。
launch.json是gdb调试使用的配置文件。
我们分别对两个自动生成的json文件进行阐述。

3.3.1 task.json

这里我们着重关注以下三个标识:
label:任务名称
command:对应使用gcc的具体路径
args:gcc对应的参数


我们手动编译的时候,其实类似于gcc -g hello.c -o hello这样的指令
那么在task.json中,实现这样的指令用到的就是command args

下面的代码中,command指定了树莓派交叉编译工具链中gcc的位置,args则表明了执行的可选项。
其中${fileDirname}和下面参数cwd(current work directory)对应,表示当前工作目录。
那么-o后面紧跟着的参数其实就是生成的可执行文件输出的位置。

其实也可以输出到特定文件夹,通过相对路径和绝对路径进行书写。

这里面detail标识其实就类似于一个注释,我这里写了gcc路径,其实可以根据自己需求自定义。

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "RaspiGCC",
            "command": "/home/fpga/Raspi/RaspiToolChain/bin/aarch64-linux-gnu-gcc",
            "args": [
                "-g",
                "hello.c",
                "-o",
                "${fileDirname}/Test"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "gccPath:/home/fpga/Raspi/RaspiToolChain/bin/aarch64-linux-gnu-gcc"
        }
    ],
    "version": "2.0.0"
}

当然,具体运用的时候可能不止编译一个.c文件,对于多个文件我们这样写。生成的可执行文件保存到当前路径下的out目录中,
这里${fileBasenameNoExtension}见文知意,生成的文件名为.c文件没有后缀的执行性文件。

"args": [
			"-g",
			"${fileDirname}/*.c",
			"-o",
			"${fileDirname}/out/${fileBasenameNoExtension}"
			],

上面是针对很多.c文件的方式,如果就那么几个,我们还可以单独列出来写。
现在假设hello.c和world.c在同一个文件夹,这里两种写法其实一个意思。如果我们在选择源文件的时候不给路径,默认是从当前路径下进行操作。
如果不同文件夹下的不同源文件进行编译,那其实只需要说明路径即可。
例如:用/home/user/world/world.c代替world.c

"args": [
			"-g",
			"${fileDirname}/hello.c",
			"world.c"
			"-o",
			"${fileDirname}/out/${fileBasenameNoExtension}"
			],

3.3.2 launch.json

launch.json是debug用的,我们其实可以通过看type标签知道。

在debug之前要有可执行文件才能debug,所以就需要前置条件。
我们看到preLaunchTask,这里说明的是在执行launch.json配置文件之前所要执行的任务。
这里和task.json中的Label标签的值对应,我这里都设置为RaspiGCC,是我自己为了方便知道这个json是给什么用的。如果图省事其实可以选择默认的C/C++: gcc 生成活动文件,只要保持两个文件的字段保持一致就可以了。

gcc指定了对应的交叉编译链工具位置,gdb也需要指定。
miDebuggerPath中的字段即为自己安装交差编译链中gdb所在的地方。

那调试程序还需要知道调试的是什么程序,我们可以通过program字段来确定。
字段的值要对应刚才生产的可执行文件的名称。
因为刚才的task.json选择生成的可执行文件是在当前目录下,名为Test的可执行文件,所以我们在设置program字段的时候,也要进行对应。

{
"version": "0.2.0",
    "configurations": [

        {
            "name": "(gdb)start",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/Test",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "RaspiGCC",
            "miDebuggerPath": "/home/fpga/Raspi/RaspiToolChain/bin/aarch64-linux-gnu-gdb"
        }
    ]
}

3.3 编译与调试

编译的时候我们得切换到.c文件才可以选择编译和调试
在这里插入图片描述

在这里插入图片描述编译成功后,会生成可执行文件,可执行文件的位置是自己定的。但是我自己演示的始发现无法调试。
出现下面情况

后来才意识到我是基于树莓派的交差编译链,这和Ubuntu中的环境不一样。所以调试的话得远程调试,虚拟机的VSCode并不支持调试这个交差编译链生成的可执行文件。
至于VSCode远程调试树莓派的话,参考VScode远程linux,这篇博客里面也有各个字段的详细解释。

把可执行文件放到树莓派运行,结果可行,表明博客所写均验证。
在这里插入图片描述


总结:这篇博客写的时间比较长,也是近期踩坑以及探索过程的一个总结。
详细记录了自己交叉编译过程,为后面嵌入式等交叉编译都打了个基础。
对VSCode的json文件有了更深的理解,感觉自己功力又大进了一步哈哈哈哈。


澄澈i
用简单的语言记录自己走过的技术路

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

澄澈i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值