clang

NOTE

编译期

单文件编译

  • 实现将源代码(.cpp | .c | .mm)编译为可执行文件、目标文件或动态库
clang++ main.cpp -o main  // 实现编译 main.cpp 生成可执行文件 main
./main  // 运行可执行文件

多文件编译

  • 也就是说我们的文件是分多文件的时候:main.cpp util.cpp util.h ,此时想要进行一次性编译所有源文件
  • 意思就是 main.cpp 中调用了 util.cpp ,此时的编译就是这样来进行的吧
clang++ main.cpp util.cpp -o main
./main

目标文件编译

  • 指定需要生成的目标文件,也就是中间文件,便于后续的进行链接
clang++ -c util.cpp -o util.o // -c 表示的是只编译不链接

静态库和动态库的区分吧

TIP
  • 预处理(Preprocessing

    • 实现的是处理源代码中的预处理指令,类似于:#include #define #ifdef,展开头文件,替换宏,删除注释,生成纯 cpp 代码

    • 输入 .cpp 是基本的源代码文件吧

    • 输出:预处理后的源代码文件吧,一般用的是 .i 结尾的呢

    • 执行的命令为:clang++ -E main.cpp -o main.i -E表示的是只执行预处理即可,-o 执行输出文件

  • 编译(Compilation

    • 将预处理后的代码(.i)翻译成汇编语言(与 CPU 架构相关的低级指令)

    • 输入:预处理后的 .i 文件

    • 输出:汇编代码文件 .s 为后缀

    • clang++ -S main.i -o main.s

  • 汇编(Assembly

    • 将汇编代码(.s)翻译成机器码(二进制指令),生成目标文件

    • clang++ -c main.s -o main.o

  • 链接(Linking

    • 将多个目标文件(.o)和所需的库文件(静态库 / 动态库)合并,解决函数调用、变量引用的地址关联,最终生成可执行文件

    • clang++ main.o util.o -o myprogram

INFO

使用背景:当代码需要被多个程序复用(如工具函数、算法库)时,通常会打包为静态库动态库,两者的核心区别在于链接时机和依赖方式

静态库(Static Library)

  • 后缀区分:

    • liunx/macOS 是 .a

    • windows 是 .lib

  • 特点是:

    • 链接时被 “嵌入” 可执行文件,生成的程序不依赖外部库,可独立运行;

    • 缺点:可执行文件体积大,若静态库更新,所有依赖它的程序都需重新编译。

动态库(Dynamic Library)【共享库】

  • 独立的二进制文件,编译时仅记录 “引用关系”,程序运行时才被加载到内存中,可被多个程序共享

  • 后缀区分

    • linux .so

    • macOS .dylib

    • windows .dll

  • 特点是:

    • 不嵌入可执行文件,节省磁盘空间和内存(多个程序共享同一份库);

    • 库更新后,依赖它的程序无需重新编译(只需替换动态库文件);

    • 缺点:程序运行时必须依赖动态库存在,否则会报错(“找不到库文件”)。