Linux C/C++开发环境和编译调试(一)
1.安装相应的软件
1.1 编译器/调试器
1.1 编译器/调试器
sudo:切换到root并执行某命令
sudo apt get:更新软件包的来源
安装编译器和调试器:
sudo apt install build-essential gab
使用如下命令来确认软件版本和是否安装成功:
gcc --version g++ --version gdb --version
1.2安装CMake
root@ziggy-virtual-machine:~# apt install cmake
GCC 编译器
gcc:C语言
g++:C++
2.1 编译过程
编译过程分为四步:
-
预处理,生程.i文件
g++ -E test.cpp -o test.i
-
编译生成汇编语言文件
g++ -S test.i -o test.s
-
汇编,将源代码比那一为机器语言的目标代码
g++ -c test.s -o test.o
-
连接
#产生可执行文件并指定文件名 g++ test.o -o test
编写简单的输出字符串的test.cpp文件
#使用g++ test.cpp -o test即可生成可执行文件test
2.2 编译参数
g++编译参数
-g:如果想要使用gdb调试,就必须使用-g产生可以被调试器使用的调试信息 g++ -g test.cpp -o test#带调试信息的test -O[n]#优化源代码,n:0-3 g++ test.cpp -O2 -o test #-l , -L指定库文件|指定库文件路径 -l用于指定程序要链接的库,-l紧跟库名 能够用-l直接连接的库:/lib,/usr/lib,/usr/local/lib中的库 g++ -lglog test.cpp -L #指定库文件所在的目录名(如果库文件不在三个目录中) #连接test2库,在/root/test下有libtest2.so g++ -L/root/test -ltest2 test.cpp -I#指定头文件搜索目录,如果在当前目录则使用-I. g++ -I/myinclude test.cpp -wall#打印gcc警告信息 -w#关闭警告信息 -std=c++11#设置编译标准 g++ -std=c++11 test.cpp -D#定义宏
2.3 例子
使用tree命令,查看建立好的文件目录结构
swap.cpp需要swap.h,但是swap.h并不在swap.cpp所在的目录中,main和其他两个文件也不在同一级目录
#可以将main.cpp和swap.cpp一同编译,但是由于swap.cpp用到了swap.h g++ main.cpp src/swap.cpp -Iinclude g++ main.cpp src/swap.cpp -Iinclude -o swap g++ main.cpp src/swap.cpp -Iinclude -o swap -Wall
2.4 生成库文件并编译
将2.3中的swap.cpp生成为静态库
#进入/src #首先生成swap.o文件 g++ swap.cpp -c -I../include #其次生成静态库libswap.a root@ziggy-virtual-machine:~/GCC_test/src# ar rs libSwap.a swap.o ar: 正在创建 libSwap.a root@ziggy-virtual-machine:~/GCC_test/src# ls libSwap.a swap.cpp swap.o #将main.cpp连接静态库 g++ main.cpp -lSwap -Lsrc -Iinclude -o static_main
生成动态库
g++ swap.cpp -U../include -fPIC -shared -o libSwap.so #相当于: gcc swap.cpp -I../include -c -fPIC gcc -shared -o libSwap.sp swap.o #生成可执行文件: g++ main.cpp -Iinclude -Lsrc -lSwap -o sharemain
静态库和动态库的区别:
静态库直接将libSwap.a包装进来
动态库是在运行时再将动态库文件引入
静态库生成的可执行文件>动态库
动态库的可执行文件执行时,如果动态库不在默认搜索路径下,则需要指定搜索路径
LD_LIBRARY_PATH=src ./sharemain
动态库和静态库在同一目录下时优先使用动态库
3. gdb调试
#常用命令
$(gdb)next(n) # 单步调试(逐过程,函数直接执行)
$(gdb)step(s) # 单步调试(逐语句:跳入自定义函数内部执行)
$(gdb)info(i) # 查看函数内部局部变量的数值
$(gdb)finish # 结束当前函数,返回到函数调用点
$(gdb)continue(c) # 继续运行
$(gdb)print(p) # 打印值及地址
$(gdb)quit(q) # 退出gdb
$(gdb)break+num(b) # 在第num行设置断点
$(gdb)$(gdb)help(h) # 查看命令帮助,具体命令查询在gdb中输入help + 命令delete breakpoints num(d) # 删除第num个断点
按回车执行上一次的命令
3.2 调试例子
#include
using namespace std;
int main(int argc,char **argv)
{
int N = 100;
int sum = 0;
int i = 1;
while (i <= N)
{
sum = sum + i;
i = i + 1;
}
cout << "sum = " << sum << endl;
cout << "The program is over." << endl;
return 0;
}
#includeusing namespace std; int main(int argc,char **argv) { int N = 100; int sum = 0; int i = 1; while (i <= N) { sum = sum + i; i = i + 1; } cout << "sum = " << sum << endl; cout << "The program is over." << endl; return 0; }



