Linux C/C++开发环境和编译调试(一)

Linux C/C++开发环境和编译调试(一)

1.安装相应的软件

1.1 编译器/调试器

sudo:切换到root并执行某命令

sudo apt get:更新软件包的来源

安装编译器和调试器:

sudo apt install build-essential gab

使用如下命令来确认软件版本和是否安装成功:

gcc --version
g++ --version
gdb --version

image

1.2安装CMake

root@ziggy-virtual-machine:~# apt install cmake

GCC 编译器

gcc:C语言

g++:C++

2.1 编译过程

编译过程分为四步:

  1. 预处理,生程.i文件

    g++ -E test.cpp -o test.i
    
  2. 编译生成汇编语言文件

    g++ -S test.i -o test.s
    
  3. 汇编,将源代码比那一为机器语言的目标代码

    g++ -c test.s -o test.o
    
  4. 连接

    #产生可执行文件并指定文件名
    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

image

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

image

静态库和动态库的区别:
静态库直接将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;
}

image

image

image

posted @ 2021-09-15 20:53  ziggystardust  阅读(545)  评论(0编辑  收藏  举报