Linux系统编程学习笔记-gcc/g++

  • gcc编译器

gcc编译器的安装

sudo apt install gcc

gcc工作流程:首先对源代码进行预编译,预编译阶段主要处理#define、#include等编译预处理命令,将宏定义转换成数值加入到代码中,然后过滤掉代码注释等,生成.i文件;下一步就是编译,编译器对.i文件进行编译生成.s汇编代码;下一步是汇编器对汇编代码进行汇编生成.o文件;最后一步就是链接,将编译的目标代码和启动代码、动态库、静态库等进行链接,最终生成可执行文件,linux下可执行文件为.out后缀,windows下为.exe文件。

Linux系统编程学习笔记-gcc/g++_第1张图片

gcc与g++的一些理解:后缀名为.c的源文件,gcc编译器按c程序编译,g++按c++编译;后缀名为.cpp的源文件,两个编译器都会按c++进行编译,编译过程中gcc由于不能自动和c++的库链接所以会通过调用g++来完成链接。所以gcc和g++都能编译cpp文件,只不过gcc在编译时需要在命令行加入-lstdc++

wjy@wjyUbuntu18:~/Linux/lesson02$ gcc test.c
wjy@wjyUbuntu18:~/Linux/lesson02$ ls
a.out  test.c
  • 静态库

 静态库的制作:Linux环境下静态库的命名规则为libxxx.a,xxx为自己设定的库名称,其他的固定不可变。静态库的制作包括两步,第一步就是将源文件进行编译但不链接生成.o文件,第二步将生成的.o文件进行打包生成.a库文件。

wjy@wjyUbuntu18:~/Linux/lesson03/calc$ gcc -c add.c div.c mult.c sub.c
wjy@wjyUbuntu18:~/Linux/lesson03/calc$ ls
add.c  add.o  div.c  div.o  head.h  main.c  mult.c  mult.o  sub.c  sub.o
wjy@wjyUbuntu18:~/Linux/lesson03/calc$ tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

0 directories, 10 files
wjy@wjyUbuntu18:~/Linux/lesson03/calc$ ar rcs libcalc.a add.o div.o mult.o sub.o
wjy@wjyUbuntu18:~/Linux/lesson03/calc$ ls
add.c  add.o  div.c  div.o  head.h  libcalc.a  main.c  mult.c  mult.o  sub.c  sub.o

静态库的使用:-I为main文件包含库目录头文件的位置,-l 为使用的库目录名称,-L为库目录位置

wjy@wjyUbuntu18:~/Linux/lesson03$ gcc ./library/main.c -o main -I ./library/include/ -l calc -L ./library/lib/
wjy@wjyUbuntu18:~/Linux/lesson03$ tree
.
├── calc
│   ├── add.c
│   ├── div.c
│   ├── head.h
│   ├── main.c
│   ├── mult.c
│   └── sub.c
├── library
│   ├── include
│   │   └── head.h
│   ├── lib
│   │   └── libcalc.a
│   ├── main.c
│   └── src
│       ├── add.c
│       ├── div.c
│       ├── mult.c
│       └── sub.c
└── main

5 directories, 14 files
wjy@wjyUbuntu18:~/Linux/lesson03$ ./main
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667
  • 动态库

动态库的制作:Linux下动态库的命名规则为libxxx.so,xxx为自定义的库名其他固定不变,动态库的制作同样也分两步,第一步是将源文件编译但不链接成.o文件,第二步就是将.o文件打包成动态库,命令上与静态库的制作稍有不同。

wjy@wjyUbuntu18:~/Linux/lesson06/calc$ gcc -c -fpic add.c div.c mult.c sub.c
wjy@wjyUbuntu18:~/Linux/lesson06/calc$ ls
add.c  add.o  div.c  div.o  head.h  main.c  mult.c  mult.o  sub.c  sub.o
wjy@wjyUbuntu18:~/Linux/lesson06/calc$ gcc -shared add.o div.o mult.o sub.o -o libcalc.so
wjy@wjyUbuntu18:~/Linux/lesson06/calc$ ls
add.c  add.o  div.c  div.o  head.h  libcalc.so  main.c  mult.c  mult.o  sub.c  sub.o

动态库的使用:动态库的使用比静态库麻烦一些,动态库在生成之后,需要配置环境变量,因为在源文件编译的时候链接过程中没有像静态库一样将库代码打包到可执行文件上,而是仅将动态库名称等一些关键信息加入到执行文件里,所以在程序运行的过程中需要动态的查找这些动态库。配置环境变量的方法有很多种,下面介绍其中一种。首先需要复制动态库存放的绝对路径,其次修改/etc/ld.so.conf文件,将路径复制进去,保存好之后再使用ldconfig指令对该文件进行更新,另外这些操作需要在管理员权限下完成,可以使用sudo指令也可以直接su切换到管理员用户进行操作。这样就可以使用动态库了。

wjy@wjyUbuntu18:~/Linux/lesson06/library$ gcc main.c -o main -I ./include/ -l calc -L ./lib/
wjy@wjyUbuntu18:~/Linux/lesson06/library$ ls
include  lib  main  main.c  src
wjy@wjyUbuntu18:~/Linux/lesson06/library$ tree
.
├── include
│   └── head.h
├── lib
│   └── libcalc.so
├── main
├── main.c
└── src
    ├── add.c
    ├── div.c
    ├── mult.c
    └── sub.c

3 directories, 8 files
wjy@wjyUbuntu18:~/Linux/lesson06/library$ ./main
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667
  • 动态库和静态库的对比

静态库由于在链接阶段就已经把代码打包到可执行文件中了,所以在程序运行阶段就不需要再去查找库文件,加载速度更快了,另外在项目发布的时候不需要另外提供静态库文件。但是这样导致的问题就是可执行文件很庞大,消耗过多的系统内存资源,另外在项目更新时就比较麻烦。

动态库在链接过程中只打包了库的一些关键信息,并没有复制所有的代码。当程序使用到动态库时将动态库加载到内存中,其他进程可以共享内存中的动态库,另外在发布和更行的时候只需要对库文件进行更新即可,不需要对源文件进行重新编译部署。带来的问题就是程序运行过程中需要动态加载库文件影响运行速度,并且在部署的过程中需要提供依赖的动态库。

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