目录
1.编译器的使用
使用ubuntu安装c++编译器,安装g++,gcc,cmake,clang四个编译器都会有提示。
在ubuntu中创建一个文本使用 cat 命令,创建一个sample.txt文本
cat > sample.txt # 在这里会直接进入到sample文本进行编辑
ctrl+D # 按ctrl+D可以退出文本
g++编译c++文件
g++是可以直接编译c++文件的,如果没有指定名字会生成一个 a.out 的文件,使用 ./a.out可运行文件,使用 -o 参数可以指定命名。
gcc编译c++文件需要 -lstdc++ 参数,这是c++的标准库,生成和g++编译是一样的。
clang++可以直接编译c++文件
g++ sample.cpp # 编译c++源文件
./a.out # 运行编译出来的c++可运行文件
g++ sample.cpp -o hello # 指定命名
gcc sample.cpp -lstdc++ -o 命名
clang++ sample.cpp -o 命名
gcc编译常用选项:
选项 | 功能 |
---|---|
-c | 只激活预处理、编译和汇编.生成.o 目标代码文件 |
-s | 只激活预处理和编译,生成扩展名为.s 的汇编代码文件 |
-E | 只激活预处理,并将结果输出至标准输出 |
-g | 为调试程序(如 gdb)生成相关信息 |
-O | 等同-01.常用的编译优化选项 |
-Wall | 打开一些很有用的警告选项,建议编译时加此选项。 |
2.在linux下配置Samba服务器
Samba服务器可以把Linux系统下的文件共享到windows系统下可以直接,在Windows下直接编写
1.安装指令:
确认是否安装:dpkg -l | grep samba
安装指令:sudo apt-get install samba
2.配置 Samba服务器:
sudo vi /etc/samba/smb.conf
在文件最后添加:
[Share]
comment = This is samba dir
path = /home/用户名/
writable = yes
browseable = yes
3.增加Samba用户:
sudo smbpasswd -a haha1
4.启动和关闭:
启动 Samba 服务器:sudo service smbd start
关闭 Samba 服务器:sudo service smbd stop
3.静态库的创建和使用
需要创建 include 文件目录,lib 文件目录,include包含静态库的头文件,lib 包含静态库编译后的源文件
命名规则:libxxx.a
过程:首先把源代码.c .cpp文件生成.o文件,再将.o文件进行打包
以源文件为 a.c,b.c 为例
第一步:gcc a.c b.c -c //编译源文件,生成a.o,b.o文件
第二步:ar rcs lib.a(静态库的名字) a.o b.o //把 a.o,b.o 打包,生成lib.a的静态库
使用静态库:需要创建源程序,调用静态库的头文件和静态库源文件,使用 -I 指定头文件路径,使用 -L 指定库文件目录,使用 -l 指定静态库的名字,静态库名字需要去头去尾
以 源程序为main.c, 静态库头文件在include目录下, 静态库在lib目录下,静态库名字为 libmy.a 为例
使用静态库的命令:gcc main.c -I ./include/ -L ./lib/ -lmy -o app //会生成一个 app 可执行程序
4.动态库的创建和使用
所需要的文件目录和静态库是一样的
命名规则:libxxx.so
过程:首先把源文件 .c .cpp文件生成 .o 文件,再将文件进行打包
以 sub.c add.c 为源文件测试
第一步:gcc sub.c add.c -c -fpic //生成动态库需要的 sub.o add.o 文件
第二步:gcc -shared sub.o add.o -o libmy.so //打包, 生成 libmy.so 动态库
使用动态库:需要创建源程序,调用静态库的头文件和静态库源文件,使用 -I 指定头文件路径,使用 -L 指定库文件目录,使用 -l 指定静态库的名字,静态库名字需要去头去尾
以 源程序为main.c, 动态库头文件在include目录下, 动态库在lib目录下,静态库名字为 libmy.a 为例
使用静态库的命令:gcc main.c -I ./include/ -L ./lib/ -lmy -o app //会生成一个 app 可执行程序
解决动态库不能够执行的问题:
第一种,执行该命令:sudo cp lib/libmy.so /lib 该命令,也就是把lib/libmy.so放入到/lib目录下,也就是动态库所在的路径,app可执行程序才能够执行
第二种:配置环境变量
使用命令:echo $环境变量名,可以查看环境变量的路径
拼接环境变量的路径命令:export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH
配置用户级别的环境变量:vim ~/.bashrc,在该文件下添加环境变量,添加完需要重启服务器,或者执行 source ~/.bashrc
配置系统级别的环境变量:vim /etc/profile, 该路径是相对路径,需要在自己电脑找到profile文件,并且进行添加,这个只针对当前用户,添加完需要重启服务器,或者执行 source /tec/profile
- 使用命令:export LD_LIBRARY_PATH=./lib ,该命令会导入 LD_LIBRARY_PATH 变量到 ./lib目录下。这种导入方式是临时的,只要终端关闭都会被删除
5.makefile构建编译规则
makefile文件的作用:可以构建出编译的规则,方便生成可执行文件,如果不去构建makefile文件则需要用命令的方式去进行编译,在大程序中这样会非常麻烦
make是linux自带的构建器,可以构建出makefile的文件,使用make去编译makefile文件生成的是终极目标,如果make后面加上指定的目标会执行指定目标的编译规则
命名方式:makefile或者是Makefile
组成部分:目标,依赖,命令
简单使用(第一个版本):
app表示目标,冒号后面是需要编译的源程序,下一行写执行的命令,使用命令需要加上Tab,表示命令行
第二个版本:
第一行的目标作为终极目标,首先检查第一行app目标需要的依赖是否存在,不存在会向下搜索下边的规则,如果有规则是生成查找的依赖的,执行规则中的命令
当依赖存在,会检查依赖是否需要更新,更新条件是时间上的不同
上面makefile规则执行的顺序:
缺点:冗余比较多
第三个版本:
自定义变量:变量名 = 源文件名或者其它
变量的取值:变量名1 = $变量名
makefile自带的变量:都是大写的
自动变量:
$@:规则中的目标
$<:规则中的第一个依赖
$^:规则中所有的依赖
注意:只能在规则中的命令使用
模式匹配:%.o:%.c
相当于:main.o:main.c
gcc -c main.c -o main.o
缺点:可移植性差
第四个版本:
makefile文件中的函数:
在makefile中所有的函数都有返回值
- 函数 wildcard:查找指定目录下指定类型的文件
用法:src = $(wildcard ./*.c)
解释:在括号内包含了函数名,以及参数,第一个参数和函数名需要用空格分开,参数 ./ 表示目录, *. 表示文件名或者类型,这里是找到指定的文件赋值给src
- 函数 patsubst :匹配替换
用法:src = $(patsubst %.c,%.o,$(src))
解释:在括号内包含了函数名,以及需要的三个参数,参数1 %.c 指需要被替换的文件,参数2 %.o 指替换参数1的文件,参数3 $(src) 指获取到的值赋给参数1。整个执行过程就是参数3获取到内容,赋值给参数1,参数2替换成参数1
.PHONY:clean表示声明伪目标,防止在同级目录下出现与目标clean一样的名字,造成规则不能执行的问题
在命令前加 - :表示如果当前命令执行出错,会跳过该命令,继续执行其它的命令,否则会停止执行makefile文件
参数-f:表示强制执行
例子:在不同级的目录下编写makefile,执行下一级的源文件
6.gdb调试
要生成可调试的可执行程序需要在编译命令后加上 -g
例如:gcc a.c -o app -g
-g:会保留函数名和变量名
函数的传参:在可执行程序后直接加入参数的值
例如:./a.out 参数值
进入到gdb调试器中,查看代码的一些命令:
命令 | 作用 |
---|---|
r(run) | 表示执行程序 |
quit | 表示退出调试器 |
l(list) | 表示查看可执行程序的代码 l 行号n:查看第n行上下的代码 l 函数名:指定函数的代码 l 文件名:查看指定文件的名字 |
show listsize | 查看一次能够显示多少行代码 |
set listsize 数字 | 设置一次查看多少行带码 |
设置断点的一些命令:
命令 | 作用 |
---|---|
b 行号n b 行号n if 条件 b 函数名 b 文件名:行号 b 文件名:函数名 | 在第n行设置断点 设置条件断点 |
i(info) b | 查看断点信息 |
d(delete) 断点号n | 删除第n个断点 |
dis 断点号n | 把第n个断点设置成无效 |
ena(enable) 断点号 | 把第n个断点设置成有效 |
p i | 查看断点执行情况 |
调试的一些命令:
命令 | 作用 |
---|---|
start | 会停在第一个大括号 |
set var 变量条件 | 设置程序执行到符合变量条件才会停下 |
until | 跳出循环,循环中不能有断点 |
p(printf) 变量i | 在调试时输出变量i的内容 |
ptype 变量i | 在调试时输出变量i的类型 |
n(nest) s(step) | 表示向下执行一行,不会进入函数体内部 表示向下执行一行,会进入函数体内部,要跳出函数体需要使用finish命令,需要在无断点的情况下才有效 |
display 变量i | 向下执行一行,同时输出变量i的内容 |
i display | 查看被设置成可以输出内容的变量 |
undisplay | 取消被设置成输出内容的变量 |
c(continue) | 执行多行,也就是执行到下一个断点 |
7.杂乱的内容(不建议看)
cmake构建编译c++源文件
使用cmake去构建源文件需要编写一个CMakeLists.txt的文本文件,内容如下:
cmake_minimum_required(VERSION 3.22.1) //指定cmake的版本
project(Example) //指定生成可执行文件的名字
add_executable(Example main.cpp) // 指定编译的文件,main.cpp 为指定的源文件
在存放CMakeLists.txt文本文件的同级目录下执行 cmake . 的命令,生成Makefile文件:
再使用make命令生成可执行文件Example:
再使用命令 ./Example即可运行程序:
在不同级目录下编写CMakeLists.txt文件,使用cmake编译
先在hello1文件夹下编写CMakeLists.txt文件,内容如下:
cmake_minimum_required(VERSION 3.22.1) //指定cmake的版本
project(Example) //指定生成可执行文件的名字
add_subdirectory(src) //该语句指定了要编译的文件夹目录
在src文件夹中的所有c++源文件都会被编译,在src的目录下也需要编写CMakeLists.txt文本文件,内容是:add_executable(hello hello.cpp) ,在hello1文件夹下创建一个build文件夹,把编译好的所有文件放入,需要使用命令 cmake ..(.. 表示上一级目录),
在bulid文件夹下执行命令 cmake ..
编译好的所有文件都在build文件夹下:
再使用make命令生成可执行文件:
#CmakeLists.txt
cmake_minimum_required(VERSION 3.22.1) #指定cmake的版本
PROJECT(hello_project) #指定编译c++源文件后生成的可执行文件的文件名
add_subdirectory(src) #编译指定文件夹下的源文件,会生成包含程序源文件的目录
include_directories(./src) #包含指定文件夹下的所有源文件
aux_source_directory(./src SRCS) #把编译好的源文件赋值给SRCS变量
add_executable(hello ${SRCS}) #编译SRCS,生成可执行文件hello