linux系统编程入门(一)

免责声明:本栏主要是对牛客视频学习的记录,方便以后自己复习。

1.什么是GCC?

  • GCC 原名为 GNU C语言编译器(GNU C Compiler)
  • GCC(GNU Compiler Collection,GNU编译器套件)是由 GNU 开发的编程语言 译器。GNU 编译器套件包括C、C++、Objective-C、Java、Ada 和 Go 语言前 端,也包括了这些语言的库(如 libstdc++,libgcj等)
  • GCC 不仅支持 C 的许多“方言”,也可以区别不同的 C 语言标准;可以使用命令行 选项来控制编译器在翻译源代码时应该遵循哪个 C 标准。例如,当使用命令行参数 -std=c99 启动 GCC 时,编译器支持 C99 标准。

安装命令 sudo apt install gcc g++
查看版本 gcc/g++ -v/–version

GCC的工作流程

在这里插入图片描述

gcc 和 g++ 的区别

gcc 和 g++都是GNU(组织)的一个编译器。
误区一:gcc 只能编译 c 代码,g++ 只能编译 c++ 代码。两者都可以,请注意:

  • 后缀为 .c 的,gcc 把它当作是 C 程序,而 g++ 当作是 c++ 程序
  • 后缀为 .cpp 的,两者都会认为是 C++程序,C++ 的语法规则更加严谨一些
  • 编译阶段,g++ 会调用 gcc,对于 C++ 代码,两者是等价的,但是因为 gcc命令不能自动和 C++ 程序使用的库联接,所以通常用 g++ 来完成链接,为了统 一起见,干脆编译/链接统统用 g++了,这就给人一种错觉,好像 cpp 程序只 能用 g++ 似的

误区二:gcc 不会定义 __cplusplus 宏,而 g++ 会
实际上,这个宏只是标志着编译器将会把代码按 C 还是 C++ 语法来解释
如上所述,如果后缀为 .c,并且采用 gcc编译器,则该宏就是未定义的,否则, 就是已定义

误区三:编译只能用 gcc,链接只能用 g++
严格来说,这句话不算错误,但是它混淆了概念,应该这样说:编译可以用gcc/g++,而链接可以用 g++ 或者 gcc -lstdc++。
gcc 命令不能自动和C++程序使用的库联接,所以通常使用 g++ 来完成联接。但在编译阶段,g++ 会自动调用 gcc,二者等价

GCC常用参数选项

在这里插入图片描述
在这里插入图片描述

2.静态库的制作与使用

  • 库文件是计算机上的一类文件,可以简单的把库文件看成一种代码仓库,它提供给使用 者一些可以直接拿来用的变量、函数或类。
  • 库是特殊的一种程序,编写库的程序和编写一般的程序区别不大,只是库不能单独运行。
  • 库文件有两种,静态库和动态库(共享库),区别是:静态库在程序的链接阶段被复制到了程序中;动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加 载到内存中供程序调用。
  • 库的好处:1.代码保密 2.方便部署和分发

命名规则

        Linux : libxxx.a

                lib : 前缀(固定)

                xxx : 库的名字,自己起

                .a : 后缀(固定)

         Windows : libxxx.lib

静态库的制作

        gcc 获得 .o 文件

        将 .o 文件打包,使用 ar 工具(archive)

                ar rcs libxxx.a xxx.o xxx.o

                        r – 将文件插入备存文件中

                        c – 建立备存文件

                        s – 索引

2.1实战制作

1.首先创建需要编为库的代码文件

2.生成这些文件的.o文件

gcc -c add.c div.c mult.c sub.c

 3.创建静态库文件

ar rcs libcalc.a add.o sub.o mult.o div.o

libcalc是自己起的静态库名字

 2.2静态库使用

准备:根据上面操作创建如下目录

 mian.c内容

 2.使用  gcc main.c -o test -I ./include/ -l calc -L ./lib/

-I指定头文件地址;    -l包含该名字库文件;   -L 指定库文件路径

 由此生成了可执行文件test

3.动态库的制作和使用

3.1动态库制作

命名规则:

        Linux : libxxx.so

                lib : 前缀(固定)

                xxx : 库的名字,自己起

                .so : 后缀(固定) 在Linux下是一个可执行文件

        Windows : libxxx.dll

动态库的制作:

        gcc 得到 .o 文件,得到和位置无关的代码

                gcc -c –fpic/-fPIC a.c b.c

        gcc 得到动态库

                gcc -shared a.o b.o -o libcalc.so

3.2动态库工作原理

  • 静态库:GCC 进行链接时,会把静态库中代码打包到可执行程序中
  • 动态库:GCC 进行链接时,动态库的代码不会被打包到可执行程序中
  • 程序启动之后,动态库会被动态加载到内存中,通过 ldd (list dynamic dependencies)命令检查动态库依赖关系
  • 如何定位共享库文件呢?

        当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路 径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是 由ld-linux.so来完成的,它先后搜索elf文件的 DT_RPATH段 ——> 环境变量 LD_LIBRARY_PATH ——> /etc/ld.so.cache文件列表 ——> /lib/,/usr/lib 目录找到库文件后将其载入内存。

3.3制作实战

1.首先准备如下目录文件

2.生成目标源代码对应.o文件

gcc -c -fpic add.c div.c mult.c sub.c -I ../include

制作动态库一定要加上 -fpic  参数

 3.生成动态库.so文件

gcc -shared add.o sub.o mult.o div.o -o ../lib/libcalc.so

 4.使用.so文件

如下是一个错误示范,仅仅在编译时使用参数-l指定动态库路径是无效的!!!

 正确示范:

方法一:导入动态库.so文件路径(这只是临时的,终端关闭重启需要重新配置)

 方法二:更改用户目录下的  ~/.bashrc 文件(用户级别)

vim .bashrc   跳到bashrc文件最后一行加入

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/whq/linuxProgram/lession06/library/lib

再使配置起作用: source .bashrc

方法三:更改系统目录下的 vim /etc/profile

步骤如方法二一样

4.静态库与动态库区别

静态库

优点:1.静态库被打包到应用程序中加载速度快。 2.发布程序无需提供静态库,移植方便

缺点:1.消耗系统资源,浪费内存。 2.更新、部署、发布麻烦

动态库

优点:1.可以实现进程间资源共享(共享库) 2.更新、部署、发布简单。 3.可以控制何时加载动态库

缺点:1.加载速度比静态库慢。 2.发布程序时需要提供依赖的动态库

猜你喜欢

转载自blog.csdn.net/m0_67505927/article/details/131110959