linux simple command
-
ls可以使用ls+选项+路径
ls -l -a -h /home ls -lah home alias ls="ls -ahl --color=auto" # 使用alias自定义命令 -
mkdir创建多层目录-p,和多个目录
mkdir -p a/b/c tree a/ # 递归查看(需要安装) mkdir a/ b/ c/ -
touch创建文件
touch a.txt touch path/a.txt touch -m a.txt # 更新一下修改时间 -
rm删除目录和文件
rm [-rf] path/a.txt # r:recursive f:force rm -rf path/folder rm *.txt # 删除所有的txt文件 -
cp复制文件或文件夹到指定路径
cp /home/a.txt /home cp -r /home /home/folder -
mv(rename)移动和重命名
mv a.txt b.txt mv a.txt /home/a.txt -
man/help获取命令手册(Q退出)
man ls -
reboot重启和shutdown关机
reboot shutdown -h now # 立即关闭 -
vim简单使用
vim a.txt i -> esc -> :w -> :q(:wq)(:q!) # i:insert,esc:退出insert,:w:保存改写内容,:q:退出,:q!强制退出 :set nq # 设置显示行号 -
路径 开头不加/指的是相对路径,加/指的是绝对路径
-
crtl+l清屏
gcc and cmake apt
-
安装gcc,gdb
sudo apt update # 更新安装软件包来源,安装每个软件前需要执行 sudo apt install build-essential gdb # 安装编译器和调试器检测是否安装成功,查看版本号
gcc --version g++ --version gdb --version -
安装cmake
sudo apt install cmake cmake --version -
安装时可能会遇到一些问题
# linux下载软件安装包时没有镜像下载慢,若异常退出下载则下次使用缓存会上锁 sudo rm /var/lib/dpkg/lock-frontend sudo rm /var/cache/apt/archives/lock sudo rm /var/lib/dpkg/lock
GCC编译器编译c/c++
-
使用gcc编译c,g++编译c++
-
编译过程
-
预处理pre-processing
g++ -E a.cpp -o a.i # -E对输入文件预处理,生成.i文件 -
编译compiling
g++ -S a.i -o a.s # -S指产生汇编文件.s后停止编译 -
汇编assembling
g++ -c a.s -o a.o # -c(小写)生成机器语言文件.o -
链接linking
g++ a.o -o a # -o为产生的可执行文件指定文件名(bin文件)
-
整个过程完全等同于g++ a.cpp -o a
-
g++编译参数
-
-g 编译带调试信息的可执行文件(告诉GCC产生能被GNU调试器GDB使用的调试信息)
-O[n] 优化源代码,告诉g++对源代码基本优化,缩减代码量,提高可执行文件的运行效率
- -O/-O1 默认优化,同时减小代码长度和执行时间
- -O0 不做优化
- -O2 -O1的基础上进行额外的调整工作如指令调整(一般使用)
- -O3 包括循环展开和一些其他处理特性相关的优化
g++ -g a.cpp -o a # 产生(带调试信息)的可执行文件a,不加则不带调试信息,方便使用GDB调试 g++ -O2 a.cpp -o a # 优化源代码输出可执行文件(常用) time ./a # 可看到执行文件的执行时间[补充]Linux性能分析工具perf
gcc a.c -g -o a # 用-g使perf可以获取函数信息 sudo perf record -g ./a sleep 10 # 用perf的record命令记录程序运行情况(生成perf.data文件记录运行数据) perf report -g # 用perf的report命令分析程序运行情况-l和-L -l用来指定程序需要链接的库文件,-l参数后紧跟库名,-L指定库文件目录
# 若库在/lib和/usr/lib和/usr/local/lib中,用-l g++ -gglog a.cpp # 链接glog库 # 若不在三个位置,需要用-L指定库文件目录 g++ -L/path -ltest a.cpp # 链接path下的test库-I 指定头文件的目录,/usr/include不需要指定
g++ -I/path a.cpp # -I也可以依据当前目录使用相对路径-Wall 打印gcc给出的警告信息(常用)
-w 关闭警告信息
g++ -Wall a.cpp # 打印警告 g++ -w a.cpp # 关闭警告-std=c++11 设置编译标准(重要)
g++ -std=c++11 a.cpp # 使用c++11标准编译-o 指定输出文件名,不加默认为a.out可执行文件(不是文件名的a)
g++ a.cpp -o a-D 定义宏
# 使用gcc/g++编译时定义宏 # -DDEBUG 定义DEBUG宏,控制文件中DEBUG宏的相关开关 g++ -DDEBUG a.cpp#ifdef DEBUG printf("1"); #endif printf("2"); // 则会执行ifdef
-
-
g++命令行编译
-
直接编译运行
g++ path/main.cpp path1/b.cpp -Ipathinclude -o a # cpp文件和头文件编译为可执行文件,最常用,main和辅助的cpp只需include .h,include:头文件目录,src:源码目录,main:程序入口 -
增加参数编译
g++ main.cpp b.cpp -std=c++11 -O2 -Wall -o a # 编译标准,优化,打印警告,命名 -
生成库文件并进行编译(静态库会集成到可执行文件中,动态库运行时才会引入)
-
链接静态库生成可执行文件
# b.cpp在src下,pathinclude为头文件目录 g++ b.cpp -c -Ipathinclude # 包含头文件,汇编生成b.o文件[src目录] ar rs libb.a b.o # 归档二进制文件生成静态库libb.a[src目录] g++ main.cpp -Ipathinclude -Lsrc -lb -o b # 链接生成可执行文件b,头文件地址,库文件目录,库文件,命名 -
链接动态库生成可执行文件
g++ b.cpp -Ipathinclude -fPIC -shared -o libb.so # 生成动态库文件libb.so,fpic表示与路径无关,shared表示生成动态库文件 g++ main.cpp -I[pathinclude] -L[src] -l[b] -o b # 链接动态库和头生成可执行文件 # 生成的可执行文件运行时需要加载.so动态库文件 LD_LIBRARY_PATH=[src] ./b # 指定.so文件位置,若在同级目录下可不需要
-
-
GDB调试器
GNU Debugger是用来调试c/c++的调试器,可以用来跟踪程序错误,VS code就是调用GDB实现c/c++调试。需要加-g,回车键可以重复上一指令。
| GDB主要功能 |
|---|
| 设置断点(断点可以是条件表达式),使程序在指定的代码行暂停执行 |
| 单步执行程序,查看程序中的变量值的变化 |
| 动态改变程序的执行环境 |
| 分析崩溃程序产生的core程序 |
-
调试常用命令参数
gdb [exefile] # 进入GDB调试程序 gdb help[h] # 查看帮助 gdb run[r] # 重新开始运行文件run-text:加载文本文件,run-bin:加载二进制文件 gdb break[b]i # 在第i行设置断点 gdb start # 单步执行运行程序,并在第一行停止 gdb list[l] # 查看源代码,list-n:从第n行开始查看代码,list [函数名]查看函数 gdb set # 设置变量的值 gdb next[n] # 单步调试,过程(函数跳过) gdb step[s] # 单步调试,语句(函数进入) gdb info[i] # 查看函数内局部变量的数值 gdb info breakpints # 查看断点 gdb finish # 结束当前函数,返回到函数调用点 gdb continue[c] # 继续执行 gdb print[p] i # 打印变量i的值及地址,只打印一遍[display] gdb quit[q] # 退出GDB -
其他调试参数
gdb backtrace[bt] # 查看函数的调用栈帧和层级关系 gdb frame[f] # 切换函数的栈帧 gdb info breakpoints # 查看所有断点 gdb delete[d] breakpoints i # 删除第i个的断点?行/个 gdb display # 追踪查看具体变量值,执行中一直打印 gdb undisplay # 取消追踪观察变量 gdb watch # 被设置的断点发生修改时,打印提示 gdb i watch # 显示观察点info watch gdb enable breakpoints # 启用断点 gdb disable breakpoints # 禁用断点 gdb x # 查看内存x/20xw显示20个单元,16进制,4字节每单元 gdb run argv[1] argv[2] # 调试时命令行传参 gdb set follow-fork-mode child # Makefile项目管理,选择跟踪父子进程fork() -
使用流程
# -g编译获得可执行文件a gdb a run # 运行 break 13 # 在i行设断点 info breakpoints # 查看断点 delete i # 删除第i个断点 r # 用设置的断点运行,遇到断点会停止 list # 查看断点周围代码 print i # 打印变量i的值(一次) display i # 一直显示变量i的值 continue # 继续下次断点
VS code
-
快捷键
Ctrl+Alt+Shift # linux打开terminal code . # 用vscode打开当前文件夹 Alt+up/dowm # 将当前代码上移/下移 Ctrl+Shift+P # 打开code命令面板 Ctrl+P # 转到文件/其他常用操作 Ctrl+W # 关闭当前文件 Ctrl+B # 关闭侧边栏 Ctrl+` #打开终端 F2 # 变量统一命名 F12 # 转到定义处 Ctrl+Shift+N # 打开新窗口 Ctrl+N # 新建文件 Ctrl+Tab # 文件切换 Ctrl+[/] # 代码行缩进 Ctrl+Enter/[Shift+Enter] # 下插一行,上插一行 Ctrl+H # 查找替换 [Fn]+F11 # 全屏 Ctrl+Shift+I # 格式化代码 CRLF=\r\n # windows下换行 LF=\n # linux下换行
CMake:跨平台的安装编译工具
在工程里额外添加cpp文件时只需添加到cmakelist文件中
-
语法特性与常用指令
# 指令(参数 参数) # 指令不分大小写,参数中间用空格或分号,变量使用${}方式取值(IF直接变量名){IF(Var)} set(Var a.cpp) # 设置变量Var指代a.cpp add_executable(a main.cpp ${Var})=(a main.cpp a.cpp)-
cmake_minimum_required-指定最小版本要求cmake_minimum_required(VERSION 2.8.2) # 最低版本要求 -
project-命名工程、指定使用语言project(a Java) # 工程名为a,使用Java语言 -
set-定义变量set(Var a.cpp b.cpp) # 定义Var变量 -
include_directories-添加头文件路径=[-i]link_directories-添加库文件路径=[-L]add_library-生成库文件include_directories(/path) # 头文件路径 link_directories(/path /path1) # 链接库文件路径 add_library(a SHARED/STATIC ${Var}) # 通过变量生成动态/静态库 -
add_compile_options-添加编译参数add_executable-生成可执行文件target_link_libraries-链接动态(shared)库add_compile_options(-wall -std=c++ 20 -o2) # 编译参数 add_executable(a a.cpp) # 生成可执行文件 add_link_libraries(a a_lib) # 将动态库a_lib连接到可执行文件a上 -
add_subdirectory-存放文件目录aux_source_directory-将目录下的源代码文件列表存储到变量中add_subdirectory(scr) # 添加scr子目录,其中一定要有一个CMakeLists.txt文件 aux_source_directory(. Var) # 定义Var变量为当前目录下的所有源代码文件 # 使用场景 add_executable(main ${Var}) # 生成main可执行文件 -
常用变量
CMAKE_C_FLAGS-gcc编译选项CMAKE_CXX_FLAGS-g++编译选项CAMKE_BUILD_TYPE-编译类型CMAKE_C/CXX_COMPILER-指定c编译器EXECUTABLE_OUTPUT_PATH-可执行文件的输出存放路径LIBRARY_OUTPUT_PATH-库文件输出存放路径set(CMAKE_CXX_FLAGS "${CAMKE_CXX_FLAGS} -std=c++20") # g++编译选项后追加-std=c++20 set(CMAKE_BUILD_TYPE Debug) # 变异类型Debug,调试时选择debug set(CMAKE_BUILD_TYPE Release) # 变异类型Release,发布时选择release
-
-
Cmake编译工程
-
目录结构(顶层目录有CMakeLists.txt文件)编译规则
- 源文件同级目录(子)有CMakeLists.txt文件,顶层目录的CMakeLists.txt通过
add_subdirectory将子目录添加进来。 - 源文件同级目录(子)无CMakeList.txt文件,子目录的编译规则体现在顶层目录的CMakeLists.txt中。
- 源文件同级目录(子)有CMakeLists.txt文件,顶层目录的CMakeLists.txt通过
-
流程
- 手动编写CMakeLists.txt,cmake指令
- 执行
cmake PATH命令生成Makefile,PATH为txt所在目录(. ./为当前目录,.. ../为上级目录) - 执行
make命令编译
-
构建方式
-
内部构建:直接读当前目录的CMakeLists.txt,产生很多中间文件,
cmake . # 当前目录编译CmakeLists.txt生成makefile等中间文件 make # make命令编译 -
外部构建(推荐):在新目录下读上级目录的CMakeLists.txt,中间文件保存在新目录下。
# 创建并进入新目录 mkdir newbulid cd newbulid # 编译 cmake .. # 编译上级目录中的CMakeList.txt,生成makefile和其他文件在newbuild中 make
-
-
编译示例
CMakeLists.txt(vs code中需要设置cmake tool的设置cmake路径才能会自动填充) # 指定最小版本要求 cmake_minimum_required(VERSION 3.0) # 指定项目名称 project(hello_test) # 添加头文件路径 include_directories(include) # -I头文件路径 # 存放文件目录,源文件目录存入变量DIR_SRC中 add_subdirectory(src DIR_SRC) # 生成可执行文件exe add_executable(exe main.cpp src/a.cpp) ==g++ main.cpp src/a.cpp -Iiclude -o2 exe 内部构建(文件杂乱) cmake . # 编译CMakeLists.txt生成makefile make # 生成可执行文件,add_executabe中指定的名称 外部构建 mkdir build cd build cmake .. make
-
综合设计
-
调试配置
-
launch.json
"program" : 调试的可执行程序路径(${workspaceFolder}/)
"preLaunchTask" : 调试前预处理指令
-
tasks.json
"label" : 任务名
"command" : 命令
"dependsOn"
-
-
目录设计
include:存储头文件,头文件要有#pragma once,函数定义src:源文件,函数实现build:编译构建文件${CMAKE_SOURCE_DIR}:顶级目录路径set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall ") # 追加编译选项 set(CMAKE_BUILD_TYPE Debug) # 生成可调试的文件