Linux WebServer开发学习(一)

GCC工作流程及编译选项

image.png

GCC工作流程
gcc编译选项 说明
-E 预处理指定的源文件,不进行编译
-S 编译指定的源文件,不进行汇编
-c 编译、汇编指定的源文件,不进行链接
-o [file1] [file2] / [file1] -o [file2] 将文件file2编译成可执行文件file1
-I [directory] 指定include文件的搜索目录
-g 在编译的时候,生成调试信息,该程序可以被调试器调试
-D 在程序编译的时候,指定一个宏
-w 不生成任何警告信息
-Wall 生成所有的警告信息
-On n取值0~3,为优化等级,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-l 在程序编译的时候,指定使用的库
-L 指定编译的时候,搜索库的路径
-fpic/fPIC 生成与位置无关的代码
-shared 生成共享目标文件,通常用在建立共享库时
-std 指定编译标准,如-std=c++20

静态库制作和使用

命名规则

  • Linux:libxxx.a

    1
    2
    3
    lib:固定前缀
    xxx:库名
    .a:固定后缀
  • Windows:libxxx.lib

静态库的制作

  1. gcc设置编译选项-c获得.o文件
  2. 将.o文件打包,使用ar工具(archive)
    1
    2
    3
    4
    ar rcs libxxx.a xxx.o xxx.o
    r - 将文件插入备存文件中
    c - 建立备存文件
    s - 索引

静态库的使用

编译时设置编译选项 -l [库名] 指定使用的静态库,-L [路径] 指定静态库查找路径。

动态库的制作和使用

命名规则

  • Linux:libxxx.so

    1
    2
    3
    4
    lib:固定前缀
    xxx:库名
    .so:固定后缀
    在Linux下动态库是可执行文件
  • Windows:libxxx.dll

动态库的制作

  1. gcc得到.o文件,要设置与位置无关

    1
    gcc -c -fpic/fPIC file1.c file2.c
  2. gcc得到动态库

    1
    gcc -shared file1.o file2.o -o libcalc.so

动态库的使用

与静态库不同,动态库不会将库中的代码打包到可执行文件中,而是保存动态库的相关信息,在程序运行时将动态库加载到内存里。
系统加载可执行代码的时候能够知道依赖的库名,但还需要知道绝对路径,该路径需要从系统的动态载入器获取。对于elf格式的可执行程序,是由ld-linux.so来完成的,搜索顺序为 DT_RPATH段$\to$环境变量LD_LIBRARY_PATH$\to$/etc/ld.so.cache文件列表$\to$/lib/,/usr/lib/,找到库文件后将其载入内存。

添加环境变量的命令为

1
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库所在的绝对路径

临时添加环境变量只需在终端中输入命令,用户级永久化需要在根目录下.bashrc文件最后添加以上命令,然后输入以下指令以启用配置。

1
2
3
source .bashrc

. .bashrc

Makefile文件命名和规则

文件命名

makefile或者Makefile

Makefile规则

  • 一个Makefile文件中可以有一个或者多个规则

    • 目标:最终要生成的文件(伪目标除外)
    • 依赖:生成目标所需要的文件或目标
    • 命令:通过执行命令对依赖操作生成目标(命令前必须Tab缩进)
      1
      2
      3
      目标 ...: 依赖 ...
      命令(Shell 命令)
      ...
  • Makefile中的其它规则一般都是为第一条规则服务的

  • 命令在执行前,需要先检查规则中的依赖是否存在
    • 如果存在,执行命令
    • 如果不存在,向下检查其他规则,检查有没有一个规则是用来生成该依赖的,如果找到了,则执行该规则中的命令
  • 检测更新,在执行规则中的命令时,会比较目标和依赖文件的时间

    • 如果依赖的时间比目标的时间晚,需要重新生成目标
    • 如果依赖的时间比目标的时间早,目标不需要更新,对应规则中的命令不需要被执行
  • 自定义变量
    变量名=变量值

  • 预定义变量(只能在规则的命令中使用)
    AR:归档维护程序的名称,默认值为ar
    CC:C编译器的名称,默认值为cc
    CXX:C++编译器的名称,默认值为g++
    \$@:目标的完整名称
    \$<:第一个依赖文件的名称
    \$^:所有的依赖文件
  • 获取变量的值
    $(变量名)
  • 模式匹配
    对于目标和依赖,使用%通配符表示一个字符串,如%.o:%.c
  • 伪目标
    1
    2
    .PHONY:目标
    声明目标为伪目标

函数

  • $(wildcard PATTERN…)

    • 功能:获取指定目录下指定类型的文件列表
    • 参数:PATTERN指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔
    • 返回:得到的若干个文件的文件列表,文件名之间使用空格间隔
    • 示例:
      1
      2
      $(wildcard *.c ./sub/*.c)
      返回值格式:a.c b.c c.c
  • $(patsubst \,\,\)

    • 功能:查找\中的单词(单词以“空格”、“Tab”、“回车”或“换行”分隔)是否符合模式\,如果匹配的话,则以\替换
    • \可以包括通配符%,表示任意长度的字符串。如果\中也包含%,那么两个%的值将相同。
    • 返回:函数返回被替换过后的字符串
    • 示例:
      1
      2
      $(patsubst %.c, %.o, x.c bar.c)
      返回值格式:x.o bar.o