需求
虽然 CMAKE
是 "跨平台" 的,但是这实际上说的是 API 的问题,我这里的需求不涉及多套 API 的问题,我只会使用 "跨开发平台" 这一点。也即是交叉编译,在 Windows
下开发 Linux
软件(build
平台不同,但 host
平台一致)
很多时候我们在开发 Linux
软件的时候都有一个问题,那就是调试,Windows
无论是 Visual Studio
或者 Visual Studio Code
都提供了很友好的单步调试功能。所以很需要一个能在 Windows
下开发 Linux
软件的办法
一段开发时间下来,我自己觉得比较顺手的是 WSL2 + Visual Studio 远程 + CMake
这套工具链。Visual Studio Code
我也用过,且不说各种 json
文件的配置,就直接是单步调试其实也稍微逊色于 Visual Studio
,后者调试的时候查看内存非常方便,前者要依赖插件。本质上还是 IDE 和编辑器的区别,但无论选择哪个,都是一个工具,自己用得顺手就行了
环境介绍
WSL2
环境:
# 内核版本
[root@xxx]# uname -a
Linux xxx 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
# 发行版版本
[root@xxx]# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.4 LTS
Release: 20.04
Codename: focal
由于是使用远程的 API,所以 Windows SDK
版本就没意义了,这里就只提供 Visual Studio
版本了:
Microsoft Visual Studio Community 2022 (64-bit) - Current Version 17.2.6
这里才是远程(也即 WSL2
)的开发环境,首先应该参考 微软官方的交叉编译工具链要求
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
GNU gdb (Ubuntu 10.2-0ubuntu1~20.04~1) 10.2
GNU Make 4.2.1
ninja 1.10.0
rsync version 3.1.3
Zip 3.0
cmake version 3.23.2
环境部署记录
以下是文件夹组织,只有一个源文件和一个 CMakeLists.txt
:
按照微软文档的说法,但凡有一个 CMakeLists.txt
的文件夹就可以被 Visual Studio
识别出来,所以下面就打开 Visual Studio
选择刚才的文件夹路径
稍等片刻会显式如下页面,红框圈出的地方是待会配置 CMake
配置的时候会用上的
现在先来关注左下角的红框框,这里的输出日志大概是说 Visual Studio
检测到这是一个 CMake
项目,所以默认生成了 CMakePreset.json
文件(这是 CMake
的预设文件)。但其实这个 "默认" 配置不是我们交叉编译需要的,因为这是 Windows
下的配置。
但是在修改配置文件之前,先补充一个内容。那就是 CMakePreset.json
,这是在 Visual Studio 2019
之后才引入的,以前版本是 CMakeSettings.json
,这都是一个东西。既然现在我们用着 Visual Studio 2022
,所以就直接用 CMakePreset.json
,这也需要修改,点击 [工具] -> [选项]:
找到 [CMake] -> [常规] 选项卡,在 [配置文件] 一栏勾选总是使用 CMakePreset.json
:
那么现在点击中间的红框框,就会进入 CMakePreset.json
的配置了;否则,你不修改,会使用 CMakeSettings.json
文件:
默认打开是这样的,在 "configuration" 键下有很多个配置:
我这里都不需要,全部删掉,只保留以下两个配置,一个 Debug
一个 Release
。至于这些配置键值对是什么意思,可以参考 CMake 官方配置文档:
{
"version": 3,
"configurePresets": [
{
"name": "linux-debug",
"displayName": "Linux Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" },
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
}
},
{
"name": "linux-release",
"displayName": "Linux Release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" },
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
}
}
]
}
当你修改完,按下 "Ctrl S" 那一刻,左下角的 CMake
输出窗口也会更新:
但注意此时工具栏显示的配置文件还是 x64 Debug
,这说明还没有让 Visual Studio
来使用这份配置,你需要将本地机器修改为远端的 WSL2
,点击上端的红框框:
之后这两个地方会马上发生变化:
再之后等 CMake
输出窗口告诉你 CMake generation finished.
你就会发现配置文件是你刚才配置的 CMakePreset.json
了:
现在为止,CMake
构建系统已经部署完成了,这体现在什么方面呢?
第一,在你的 Visual Studio
会多了个 out
目录,这是和你的 CMakePreset.json
配置有关(至于为什么 out
目录下有个负数命名的文件夹,我目前所知的只是这和连接远端有关,如果你是本地开发不会有这个名字的文件夹)(但是,实际上,Visual Studio
调用远端开发环境的办法是 rsync
同步,所以是在你远端 WSL2
的环境下某个目录里面会多一个副本)
第二,点击 "目标视图",你会发现生成了一个目标文件:
出现这两个现象的时候,说明 CMake
构建系统生效了
但是还不够,我们还需要用来调试,所以还需要写一个配置文件
首先,右击 "目标视图" 的目标文件:
选择增加一个 Debug
配置文件,之后会打开一个窗口,里面是 launch.vs.json
配置文件,具体的键值对可以参考 微软手册 看看都是什么意思,不过简单改改默认的配置就行了:
{
"version": "0.2.1",
"defaults": {},
"configurations": [
{
"type": "cppgdb",
"name": "test",
"project": "CMakeLists.txt",
"projectTarget": "test",
"debuggerConfiguration": "gdb",
"args": [],
"env": {}
}
]
}
那么现在按 "F5" 就可以快乐地调试了:
补充一句,如果想使用 std::cin
输入,只需要在上面红框框的地方输入,然后按回车即可
另外,如果按下 "F5" 以后报错,比如什么无法连接远程服务器之类的,很有可能是你远端的 WSL2
环境没设置好,比如缺少其他依赖,请检查远端开发环境