gcc 对 c/c++ 编译的控制

    预处理(Preprocessing)

    编译(Compilation)

    汇编(Assembly)

    链接(Linking)

1.参数
  语法格式:

$ gcc [option] 
选 项
功 能
-c
只编译,不链接
-E
预编译
-g
生成调试信息,可以被gdb使用
-I
指定头文件路径
-l
指定库文件名称
-L
指定库文件路径
-o
指定结果文件的文件名,默认为a.out
-shared
强制 动态链接(*默认
-static
强制静态链接(gcc默认链接的是动态库
-S
只编译,不汇编
-w
禁止输出警告信息
-Wall
显示所有警告信息
-v
查看版本信息

  编译程序的四个过程

# 预处理
$ gcc -E main.c -o main.i    # 预处理是编译C语言程序的第一步,主要有三个工作内容。
                             # 包括:过滤注释、包含文件、展开宏
# 编译
$ gcc -S hello.i -o hello.s    # 只编译不汇编,仅仅生成汇编代码。
# 汇编
$ gcc -c hello.s -o hello.o    # 汇编后不链接
# 链接
$ gcc hello.o -o hello    # 链接后生成可执行代码

  预编译完成了去掉注释信息、引入包含文件、替换宏定义。编译后生成的是汇编代码,汇编后生成目标代码。链接过程把目标代码生成二进制可执行文件。

  头文件的引入,“-I”选项

# 主函数文件 main.c 引用当前目录下的 include/fun.h
$ cat main.c
# include
# include"fun.h"

void main(void){
        fun();    // 头文件 fun.h 中的函数引用
        printf("main is running...\n");
        return;
}

$ gcc main.c -o main -I include/

  编译程序包含多个源文件

$ gcc -o main main.c obj1.c obj2.c -I ../test

  静态编译,使用选项 -static(依赖glibc-static

$ gcc -Wall main.c -o main -static


  从链接方式上看,程序库可以分为静态库、动态库(共享库)两种类型。静态库:连接后被加入到可执行代码文件中,成为执行程序的一部分来执行的。共享库:连接后加入共享库的调用方式,在程序执行时调入程序执行。


2.静态库

  创建静态库时,Linux环境下使用ar工具。静态库在编译时指定库的路径和名称,完成编译后生成可执行文件。该文件执行时不需要把编译时的静态库输出到运行环境中,亦可正常运行该程序。

# 编译源文件,生成目标文件
$ gcc -c add.c
# 创建静态库,或者把目标文件加入到已存在的静态库中
$ ar rcs libadd-static.a add.o    # 将目标文件加入到指定的静态库中
$ ar t libstatic_libs.a    # 查看静态库中的目标文件
static_lib.o
$ gcc main.c -L. -I. -ladd-static -o main-static    # 使用静态库
$ ldd main-static    # 使用的是静态库,生成的执行文件,还使用了动态库
    linux-vdso.so.1 =>  (0x00007fff16fff000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fd3a6093000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fd3a642b000)


3.动态库

  动态编译,生成一个动态库文件

$ gcc -c -fpic add.c
$ gcc -c add.c -o add.a.o
$ gcc -shared add.o -o libadd.so
$ gcc -L. -ladd -I. main.c -o main-dynamic
$ ldd main-dynamic
    linux-vdso.so.1 =>  (0x00007fffc77ff000)
    libadd.so => /home/view/C/07 Gcc/dynamic_lib/libadd.so (0x00007fb645f4e000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fb645bba000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fb646154000)

  连接目标文件的时候,使用某个库,由于指定库名时,不是指定的全名,那么当存在两个同名库时,优先选择动态库。