Linux学习笔记:使用GCC编译器

文章目录

  • 前言
  • 1. 编译过程
    • 1.1 预处理 - Pre-Processing --->产生 .i文件
    • 1.2 编译 - Compiling --->产生.s文件
    • 1.3 汇编 - Assembling --->产生.o文件
    • 1.4 链接 - Linking --->产生bin文件
  • 2. 常用编译选项
    • 2.1 -g:编译带调试信息的可执行文件
    • 2.2 -O[n] :优化源代码
    • 2.3 -l 和 -L:指定库文件 | 指定库文件路径
    • 2.4 -I:指定头文件搜索目录
    • 2.5 -Wall:打印警告信息
    • 2.6 -w:关闭警告信息
    • 2.7 -std=c++11:设置编译标准
    • 2.8 -o:指定输出文件名
    • 2.9 -D:定义宏
  • 3. GCC编译工程项目
    • 3.1 直接编译
    • 3.2 生成静态库文件并编译
    • 3.3 生成动态库文件并编译


前言

  1. GCC编译器编译过程。
  2. GCC编译器常用编译选项。
  3. 使用GCC编译器对工程进行直接编译、生成静态库编译、生成动态库编译。

1. 编译过程

GCC 编译器支持编译 Go、Objective-C,Objective-C ++,Fortran,Ada,D 和 BRIG(HSAIL)等程序,而VSCode就是通过调用GCC编译器来实现C/C++的编译。

  • gcc 指令用于编译 C 代码
  • g++ 指令用于编译 C++ 代码

1.1 预处理 - Pre-Processing —>产生 .i文件

# -E 选项指示编译器仅对输入文件进行预处理
g++ -E test.cpp -o test.i

1.2 编译 - Compiling —>产生.s文件

# -S 编译选项告诉 g++ 在为 C++ 代码产生了汇编语言文件后停止编译
#  g++ 产生的汇编语言文件的缺省扩展名是 .s 
g++ -S test.i -o test.s

1.3 汇编 - Assembling —>产生.o文件

# -c 选项告诉 g++ 仅把源代码编译为机器语言的目标代码
# 缺省时 g++ 建立的目标代码文件有一个 .o 的扩展名。
g++ -c test.s -o test.o

1.4 链接 - Linking —>产生bin文件

# -o 编译选项来为将产生的可执行文件用指定的文件名
g++ test.o -o test

2. 常用编译选项

2.1 -g:编译带调试信息的可执行文件

# 产生带调试信息的可执行文件test
g++ -g test.cpp -o test

2.2 -O[n] :优化源代码

# -O 选项告诉 g++ 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快。 -O2 选项告诉 g++ 产生尽可能小和尽可能快的代码。 如-O2,-O3,-On(n 常为0–3)
# -O 同时减小代码的长度和执行时间,其效果等价于-O1
# -O0 表示不做优化
# -O1 为默认优化
# -O2 除了完成-O1的优化之外,还进行一些额外的调整工作,如指令调整等。
# -O3 则包括循环展开和其他一些与处理特性相关的优化工作。
# 选项将使编译的速度比使用 -O 时慢, 但通常产生的代码执行速度会更快。
# 使用 -O2优化源代码,并输出可执行文件
g++ -O2 test.cpp -o test
  • 查看程序运行时间命令 time
time ./test

2.3 -l 和 -L:指定库文件 | 指定库文件路径

# -l参数(小写)就是用来指定程序要链接的库,-l参数紧接着就是库名
# 在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接
# 链接glog库
g++ -lglog test.cpp

# 如果库文件没放在上面三个目录里,需要使用-L参数(大写)指定库文件所在目录
# -L参数跟着的是库文件所在的目录名
# 链接mytest库,libmytest.so在/home/bing/mytestlibfolder目录下
g++ -L/home/bing/mytestlibfolder -lmytest test.cpp
  • 注:文件名为libmytest.so的动态链接库的库名为mytest

2.4 -I:指定头文件搜索目录

# -I 
# /usr/include目录一般是不用指定的,g++知道去那里找。
#如果头文件不在/usr/icnclude里我们就要用-I参数指定了,比如头文件放在/myinclude目录里,那编译命令行就要加上-I/myinclude参数了。如果不加你会得到一个”xxxx.h: No such file or directory”的错误。
# -I参数可以用相对路径,比如头文件在当前目录,可以用-I.来指定。
g++ -I/myinclude test.cpp

2.5 -Wall:打印警告信息

# 打印出g++提供的警告信息
g++ -Wall test.cpp

2.6 -w:关闭警告信息

# 关闭所有警告信息
g++ -w test.cpp

2.7 -std=c++11:设置编译标准

# 使用 c++11 标准编译 test.cpp
g++ -std=c++11 test.cpp

2.8 -o:指定输出文件名

# 指定即将产生的文件名
# 指定输出可执行文件名为test
g++ test.cpp -o test

2.9 -D:定义宏

# 在使用gcc/g++编译的时候定义宏
# 常用场景:
# -DDEBUG 定义DEBUG宏,可能文件中有DEBUG宏部分的相关信息,用个DDEBUG来选择开启或关闭DEBUG
g++ -DDEBUG main.cpp

示例代码:

// -Dname 定义宏name,默认定义内容为字符串“1”
#include 
using namespace std;
int main()
{
    #ifdef DEBUG
        cout << "DEBUG LOG";
    #endif
        cout << "in";
}

// 1. 在编译的时候,使用g++ -DDEBUG main.cpp
// 2. 第七行代码可以被执行
  • 注:使用 man gcc命令可以查看gcc英文使用手册

3. GCC编译工程项目

  • 文件目录
.
├── include
│   └── swap.h
├── main.cpp
└── src
    └── swap.cpp

2 directories, 3 files

3.1 直接编译

# 将 main.cpp src/swap.cpp 编译为可执行文件 附带相关参数
g++ main.cpp src/swap.cpp -Iinclude -std=c++11 -O2 -Wall -o main
# 运行 main
./main

运行结果:

$ ./main
m_val1=3
m_val2=4
m_val1=4
m_val2=3
$ tree .
.
├── include
│   └── swap.h
├── main
├── main.cpp
└── src
    └── swap.cpp

2 directories, 4 files

3.2 生成静态库文件并编译

  • 生成静态库文件
# 进入src目录下
$cd src
# 汇编,生成Swap.o文件
$ g++ swap.cpp -c -I../include
$ ls
swap.cpp  swap.o
# 生成静态库libSwap.a
$ ar rs libSwap.a swap.o
ar: 正在创建 libSwap.a
$ ls
libSwap.a  swap.cpp  swap.o
  • 链接静态库生成可执行文件
# 返回上级目录
$ cd ..
# 链接静态库文件并生成可执行文件
$ g++ main.cpp -Iinclude -Lsrc -lSwap -o main_staticlib
$ ./main_staticlib 
m_val1=3
m_val2=4
m_val1=4
m_val2=3
$ tree .
.
├── include
│   └── swap.h
├── main.cpp
├── main_staticlib
└── src
    ├── libSwap.a
    ├── swap.cpp
    └── swap.o

2 directories, 6 files

3.3 生成动态库文件并编译

  • 生成动态库文件
# 进入src目录下
$cd src
# 生成动态库libSwap.so
$ g++ swap.cpp -I../include -fPIC -shared -o libSwap.so
$ ls
libSwap.so  swap.cpp
  • 链接动态库生成可执行文件
# 返回上级目录
$ cd ..
# 链接动态库文件并生成可执行文件
$ g++ main.cpp -Iinclude -Lsrc -lSwap -o main_share
# 因为动态库文件并不在系统默认搜索的路径下,所以无法直接运行
$ ./main_share 
./main_share: error while loading shared libraries: libSwap.so: cannot open shared object file: No such file or directory
# 添加动态库搜索路径命令 LD_LIBRARY_PATH=src
$ LD_LIBRARY_PATH=src ./main_share 
m_val1=3
m_val2=4
m_val1=4
m_val2=3
$ tree .
.
├── include
│   └── swap.h
├── main.cpp
├── main_share
└── src
    ├── libSwap.so
    └── swap.cpp

2 directories, 5 files

参考文章:

  1. https://www.bilibili.com/video/BV1fy4y1b7TC?p=9&spm_id_from=pageDriver&vd_source=ddbb3853dd3f85f9eaea0ada286f7007

你可能感兴趣的:(Linux学习笔记,linux,学习,bash)