

RoboMaster 视觉组第二次培训
关于 SSH 以及 CMake 的基础讲解。
前言#
本部分的博客是 RoboMaster 机甲大师视觉组培训的第二期内容,主要讲解一些计算机的基本技能,包括使用 Markdown/Linux/SSH/CMake,其中主要讲解的是包括 SSH 以及 CMake 在内的内容,这些内容是将来使用 Linux 进行编程的重要组件。
Markdown#
对于没有使用过 Markdown 的同学来说,大多数时候,我们均使用 Word 来进行文档的编辑工作,但是 Word 往往具有一定的缺点,这包括:
- 需要使用 Word 软件进行打开,而 Word 软件是闭源的。
- 无法进行实时渲染。
- 打开的过程中过于耗时。
- 排版并不直观(对于 Geek 来说,在生成更富文本内容时,一般选择使用 以替代 Markdown)
这些内容对于正常的办公人士来说是可以忍受的,但是对于追求性能的人来说,可以说是弊端十足,此时 Markdown 是满足这些需求的最佳选项。
一方面,Markdown 可以很快捷的编译为 html,而同时又不同于 txt,其本身具备一定的排版系统,可以实现对于大多数文档的必要编写需求。
Markdown 的文件格式为 .md
,使用此后缀名便可以较为轻松的将内容标记为 Markdown,并在大多数的代码工具中被直接渲染。而专业的 Markdown 编辑器,如 typora/obsidian/VSCode Markdown 插件,读者均可以自行进行探索。
Markdown 的详细语法见 Markdown 官网文档 ↗,在这里不进行重复的说明,因为在占用篇幅的同时,这是多余的。
安装 VSCode#
通过Ubuntu自带的火狐浏览器找到熟悉的 VSCode 的官网 ↗,并且进行安装。
选择 .deb
进行下载,下载完毕之后进入下载文件夹,应该可以看到下载的 deb 包,右键在终端中打开,输入:
sudo dpkg -i code_your_version.deb
bash其中 code_your_version.deb
为你的 deb 包的名字,在命令行中可以使用 TAB 进行自动补全,这样你就只需要输入一个 code,之后进行自动补全即可。
输入密码,其中密码的输入是不可见的,输入之后终端没有反应并非你没有输入,输入之后按下回车即可。
稍等片刻,等命令行又一次可以输入的时候,在命令行中输入 code,回车,进入 VSCode。
SSH#
在这里简短的介绍 SSH 语法,一般来说 SSH 安装在每一个系统中,无需额外的安装,在这里推荐使用 VSCode 的 SSH 插件
通过在 VSCode 的拓展栏进行搜索,可以很轻易地找到 VSCode 的 SSH 插件:
启用插件之后,点击左下角的打开远程窗口,选择连接到主机即可:
在服务器的租用界面中,一般会提供 SSH 的指令,其格式为 ssh -p port user@address
,之后按照提升输入密码即可。
Linux#
使用 SSH 后,我们会进入正式的 Linux 系统中,同时,由于使用 SSH,此时的 Linux 并没有提供图形化界面(这也是 Linux 最原始的形态),因此在本章节中,我们会首先讲解一些基础的 Linux 指令,以便读者可以进行接下来的操作:
ls
:可以展示当前目录下的文件内容,其中显示隐藏内容需要使用ls -a
。cd
:用法为cd folder
,可以前往指定的文件夹中,需要注明的是,..
为上级目录,如想要前往上级,使用cd ..
,上级的上级,以此类推cd ../..
。
文档的编辑操作需要使用 vim,这一技巧具备一定的难度,读者请勿尝试指令 vim filename
,若无法退出,请狂点 esc
之后依次按下 :
, w
, q
, !
, Enter
以保存并退出,若不希望保存,无需按下 w
。
配置 C++ 开发环境#
安装 build-essential 包,其中包括 gcc, g++, cmake 在内所需要的大多数包:
sudo apt install build-essential
bash如果希望使用 clang 而非 gcc,可以安装:
sudo apt install clang-15 clangd-15 clang-format-15
bashClang 可以简单理解为等价于 gcc 的 C++ 编译器,但是可以提供一些更好的开发体验,不过从结果上并无本质区别。
之后建立软链接:
sudo rm /usr/bin/clang /usr/bin/clang++ /usr/bin/clangd /usr/bin/clang-format
sudo ln -s /usr/bin/clang-15 /usr/bin/clang
sudo ln -s /usr/bin/clang++-15 /usr/bin/clang++
sudo ln -s /usr/bin/clangd-15 /usr/bin/clangd
sudo ln -s /usr/bin/clang-format-15 /usr/bin/clang-format
plaintext对于 Ubuntu20.04 的读者来说,以上全部的 15 改为 12,输出没有找到xxx是正常现象,因为 Ubuntu 20 并不支持 15 的 clang。
在终端分别输入clang以及clangd得到以下输出:
$ clang
clang: error: no input files
$ clangd
clangd is a language server that provides IDE-like features to editors.
It should be used via an editor plugin rather than invoked directly. For more information, see:
https://clangd.llvm.org/
https://microsoft.github.io/language-server-protocol/
clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment variable.
I[18:10:45.783] Ubuntu clangd version 15.0.7
I[18:10:45.783] Features: linux+grpc
I[18:10:45.783] PID: 3507769
I[18:10:45.783] Working directory: /home/gaoning
I[18:10:45.783] argv[0]: clangd
I[18:10:45.783] Starting LSP over stdin/stdout
plaintext则安装成功。
之后安装 VSCode 插件,包括 CMake、CMake Tools 以及 C/C++。
新建文件夹并且进入,ctrl shift p
,选择 CMake 快速入门,之后按照提示进行:
- 输入项目名称,如 mytest。
- 创建 C++ 项目
- 创建可执行文件
之后依然是点击下方栏的生成(编译),或者直接点击三角形按钮(编译并运行),得到了喜闻乐见的 Hello。
配置 Clang 环境#
在VSCode安装 clangd 以及 Clang-Format,其中 Clang-Format 如下图:
点击齿轮图表-拓展设置,找到 Clang-format: Executable
设置为 /usr/bin/clang-format
。
打开终端(ctrl alt t),创建 .clang-format
作为格式化代码的配置文件:
touch .clang-format
gedit .clang-format
bash并且向其中输入配置内容:
{ BasedOnStyle: LLVM, UseTab: Never, IndentWidth: 4, TabWidth: 4, BreakBeforeBraces: Allman,
AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false, ColumnLimit: 0,
AccessModifierOffset: -4, NamespaceIndentation: All, FixNamespaceComments: false }
json保存并退出。
打开某一代码文件,右键选择格式化文档(快捷键为ctrl shift i),并且在弹窗中选择clang-format,可以发现代码变得十分的工整。但是有的时候一些代码会用红线,说一些内容未找到(如 iostream
),但是编译可以正常进行,输入以下命令解决这一问题。
sudo apt install libstdc++-12-dev
bashCMake & CMakeList#
在 C++ 的编译过程中,我们面临这样一个需求:我们有一个 C++ 编译器,一些 C++ 程序文件(它们彼此之间有依赖关系),一些 C++ 库(它们被正常的安装),并希望生成一个 C++ 编译的二进制文件,如何进行?
一个基础的想法是,通过某些语法,声明他们之间的关联,并通过某种工具通知编译器,进行编译,CMake 和 CMakeList.txt 可以很好的完成这一内容。
你需要进行的只是在一个程序的文件夹中的根目录下创建一个名为 CMakeList.txt
的文件,并且在其中按照一定的语法,关联你的项目,之后在当前根目录下运行下述程序即可:
mkdir build
cd build
cmake ..
make -j8
bash其中 -j8
为调用八个核进行编译工作,这个数字是可调节的,或者直接 -j
进行自动调节也可以。
一般来说项目具有两种不同的结构可以选择,一种是直接将 include 和 src 文件夹分开放置在项目的根目录下,之后主程序在根目录下。一种则是将功能包放在项目的根目录下,功能包中包含 include 和 src 文件夹。在这里推荐并且讲解后者,因为可以便于项目的管理,比如说一位同学写了一个功能包,想要加入整个项目之中,只需要把功能包拷贝进来并且稍加改变 CMakeLists.txt 就可以直接使用,十分的方便。
对于功能包中的 CMakeLists.txt 写法如下:
cmake_minimum_required(VERSION 3.0.0)
project(test VERSION 0.1.0)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -pthread")
aux_source_directory(./src ALL_SRCS)
add_library(test STATIC ${ALL_SRCS})
cmake此处即声明了一个名为 test 的功能包。
同时在主CMakeLists.txt
中各项中添加:
include_directories(
test/include
)
add_subdirectory(test)
target_link_libraries(infantry_new
test
)
cmake即可完成 CMakeList.txt 的更新。
此时的结构如下:
.
├── test
│ ├── CMakeLists.txt
│ ├── include
│ │ ├── test1.hpp
│ │ └── test2.hpp
│ └── src
│ ├── test1.cpp
│ └── test2.cpp
├── build
├── CMakeLists.txt
└── main.cpp
txt一个基础的 CMakeList.txt 仅包括以下内容:
# 声明 CMake 版本需求
cmake_minimum_required(VERSION 3.0.0)
# 声明项目与版本/语言等信息
project(cpp VERSION 0.1.0 LANGUAGES C CXX)
# 将 main.cpp 编译为名为 cpp 的二进制文件
add_executable(cpp main.cpp)
cmake以下给出一个健全的 CMakeList.txt:
# 声明 CMake 版本
cmake_minimum_required(VERSION 3.0.0)
# 声明 C++ 版本
set(CMAKE_CXX_STANDARD 17)
# 设置 TARGET_NAME 变量的值为 infantry_new
set(TARGET_NAME infantry_new)
# 设置项目为 TARGET_NAME 变量的值
project(${TARGET_NAME})
# 开启 CMAKE_EXPORT_COMPILE_COMMANDS
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# 开启多线程
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -pthread")
SET(CMAKE_CXX_FLAGS_RELEASE "-std=c++17 -pthread")
# 设置 OpenCV 路径,当系统中存在多个 OpenCV 时尤为重要
set(OpenCV_DIR /usr/local/lib/cmake/opencv4)
# 找库的依赖
find_package(OpenVINO REQUIRED COMPONENTS Runtime)
find_package(Ceres REQUIRED)
find_package(OpenCV REQUIRED)
# 设置宏定义
add_definitions(-DDEBUGMODE)
# 引用库与功能包
include_directories(
/opt/MVS/include
armor/include
${CERES_INCLUDE_DIRS}
)
# 链接一些库
link_directories(
/opt/MVS/lib/64
/opt/MVS/lib/32
/usr/local/lib
)
# 添加子路径,为功能包
add_subdirectory(armor)
# 编译 main.cpp 为 infantry_new
add_executable(infantry_new main.cpp)
# 设置动态链接库
target_link_libraries(infantry_new
armor
${CERES_LIBRARIES}
)
# 一些常规设置
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
cmake不难发现,十分的简单,不懂的地方可以咨询 ChatGPT。
同时需要额外教学的是,对于一些需要人工编译安装的 C++ 库来说,同样需要使用 CMake,其特征为根目录下有 CMakeList.txt,语法为:
mkdir build
cd build
cmake ..
make -j
sudo make install
bash以上,全部内容,多谢惠顾。