学习 MakeFile [01] C语言编译(包含 C++)

学习 MakeFile [01] C语言编译(包含 C++)

lucas Lv4

C语言编译

首先我们看看文件树

1
2
3
4
5
6
7
8
$ tree   
.
└── src
├── add.c
├── main.c
└── minus.c

2 directories, 3 files

其中 add.c 、 minus.c 、 main.c 如下:

1
2
3
4
// add.c
int add(int a, int b) {
return a + b;
}
1
2
3
4
// minus.c
int minus(int a, int b) {
return a - b;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// main.c
#include <stdio.h>

int add(int a, int b);
int minus(int a, int b);

int main(int argc, char const* argv[]) {
int a = 3, b = 2;
int c = add(1, 2);
printf("a + b = %d\n", c);
c = minus(a, b);s
printf("a - b = %d\n", c);
return 0;
}

编译步骤

  1. 预处理

    • 展开所有宏定义(#define),将宏替换为它定义的值
    • 处理所有条件编译指令(#ifdef、#ifndef、#endif等)
    • 处理文件包含语句(#include),将包含的文件直接插s入到语句所在处
    • 删除所有注释
    • 添加行号和文件标识,以便在调s试和编译出错时快速定位到错误所在行

      ps: 代码中的编译器指令(#pragma)会被保留

  2. 编译(嗯…)

  3. 汇编(嗯…)

  4. 链接
    这里就是将函数的调用和函数的定义链接起来,如果没有定义或者定义的地方不止一处,则会出现链接错误

编译命令

常用的编译命令如下:

1
gcc [参数] [文件列表]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# -E 指定 .c 文件,激活预处理,但不会生成 .i 文件,除非用 -o 指定
gcc -E main.c
gcc -E main.c -o main.i

# -S 指定 .c 或者 .i 文件,激活预处理和编译,生成 .s 文件
gcc -S main.c
gcc -S main.i

# -c 指定 .c 、 .i 、.s 文件,激活预处理、编译和汇编,生成 .o 文件
gcc -c main.c
gcc -c main.i
gcc -c main.s

# 指定任意类型文件,激活生成可执行文件
gcc main.o add.i minus.c -o exec

# 执行
.exec

编译静态库

我在 src 目录下使用以下命令

1
2
3
4
5
6
7
8
9
10
# 编译成 .o 的文件
gcc -c [.c] -o [自定义文件名]
gcc -c [.c] [.c] ...

# 编译生成静态库
ar -r [lib自定义库名.a] [.o] [.o] ...

# 链接成可执行文件
gcc [.c] [.a] -o [自定义输出文件名]
gcc [.c] -o [自定义输出文件名] -l[库名] -L[库所在路径]

ps:

-l[库名] -L[库所在路径] lL 后面没有间隔直接跟库名和路径,就像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#  编译成 .o
gcc -c main.c add.c minus.c
# 生成静态库rcs:命令选项:
# r:插入文件到库中(替换已有文件)。
# c:创建库文件,如果库文件不存在。
# s:创建索引,提高库的访问速度。
ar -rcs liboperation.a add.o minus.o
# 链接生成可执行文件(方式 1)-loperation 用来指定库,-L.用来指定当前目录
gcc main.c -loperation -L. -o exec
# 链接生成可执行文件(方式 2)
gcc main.c liboperation.a -o exec
# 查看静态库内容
ar -t liboperation.a
# 输出结果
__.SYMDEF SORTED
add.o
minus.o

编译动态库

同样在 src 目录下使用以下命令

1
2
3
gcc -c -fpic [.c/.cpp][.c/.cpp]... 
gcc -shared [.o][.o]... -o [lib自定义库名.so]
gcc [.c/.cpp] -l[库名] -L[库路径] -Wl,-rpath=[库路径] -o [自定义可执行文件名]
1
2
3
# -fpic:生成位置无关代码,以便可以用于动态库
gcc -c -fpic add.c minus.c
gcc -shared add.o minus.o
1
gcc main.c -loperation -L. -o exec

C++ 编译

非常简单,将 C语言编译的 gcc 改成 g++ 即可

  • Title: 学习 MakeFile [01] C语言编译(包含 C++)
  • Author: lucas
  • Created at : 2024-11-19 16:34:45
  • Updated at : 2024-11-28 19:37:16
  • Link: https://darkflamemasterdev.github.io/2024/11/19/学习MakeFile-01-C语言编译-包含C++/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments