Linux C/C++开发环境和编译调试(一)
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 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 <iostream>
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;
}