From 92f41c89fa9f9a07666d603c07e8facd2b0fb576 Mon Sep 17 00:00:00 2001 From: luojh Date: Tue, 2 Sep 2025 15:22:23 +0800 Subject: [PATCH 01/12] Add overview ans static linked library. --- docs/dev/library.md | 118 ++++++++++++++++++++++++++++++++++++++++++++ includes/authors.md | 1 + 2 files changed, 119 insertions(+) create mode 100644 docs/dev/library.md diff --git a/docs/dev/library.md b/docs/dev/library.md new file mode 100644 index 00000000..bfc3c0ca --- /dev/null +++ b/docs/dev/library.md @@ -0,0 +1,118 @@ +--- +icon: simple/cplusplus +--- + +# 链接库 + +!!! note "主要作者" + + [@luojh][luojh] + +!!! warning "本文编写中" + +!!! comment "适用范围" + + 本文介绍 Linux 上的**静态链接库** (一般为 `.a` 文件) 和**动态链接库** (一般为 `.so` 文件)。注意:这里的链接库是指包含了可执行二进制代码的库,并不是头文件 (Header file)、Python 库等。 + +## 总览 + +库 (Library),是包含**可重用代码和数据**的模块。 + +### 构建链接库 + +下图给出了一般的可执行文件 (executable)、静态链接库 (static library)、动态链接库 (dynamic library) 的构建过程。 + +```mermaid +flowchart TD + +source["源文件 (*.c, *.cpp)"] -->|编译| target["目标文件 (*.o)"] +header["头文件 (*.h)"] --- source +target -->|链接| executable["可执行文件 (ELF等)"] +target -->|ar rcs| staticlib["静态链接库 (*.a)"] +target -->|gcc -shared| dynamiclib["动态链接库 (*.a)"] +``` + +### 使用链接库 + +下图给出了**使用链接库**的方式。 + +```mermaid +flowchart TD +source["源文件 (*.c, *.cpp)"] -->|编译| target["目标文件 (*.o)"] +header["头文件 (*.h)"] --- source +target --> linker["链接器"] +staticlib["**静态链接库** (链接步骤加入)"] --> linker +linker --> executable["可执行文件 (ELF等)"] +dynamiclib["**动态链接库** (运行时加载)"] --> executable +``` + +## 源代码 + +对于 C 程序而言,链接库的源代码就是普通函数、变量之类,并无太多特殊要求。例如,创建并进入目录 `lib`,在 `square.c` 源文件中写一个函数 `square` + +```c +int square(int x) +{ + return x * x; +} +``` + +对应的,需要在头文件 `square.h` 中加入这个函数的原型 (prototype) + +```c +int square(int x); +``` + +以便其他使用链接库的程序**知道如何使用这个函数** (即使这些程序不知道函数内部的实现)。 + +因为链接库不是完整的、可以独立运行的程序,因此不需要入口点 (比如 `main` 函数)。 + +## 静态链接库 + +静态链接库是在**链接步骤就加入**的链接库类型。 + +### 构建 + +首先按照正常方法编译得到 `.o` 文件: + +```shell +gcc square.c -c -o square.o +``` + +然后使用 `ar` 程序创建静态链接库 `libsquare.a`: + +```shell +ar rcs libsquare.a square.o +``` + +注意这里的 `libsquare.a` 是命名惯例:一般静态链接库的文件名需要为 `lib<名称>.a`。 + +到这里就完成了静态链接库的创建。 + +### 使用 + +另一个 C 程序 `main.c` 中使用了 `square` 函数,那么首先需要包含 `square.h` 头文件,这样才能知道这个函数的原形,然后就可以正常调用了。 + +```c +#include +#include "lib/square.h" + +int main(void) +{ + int a; + scanf("%d", &a); + + printf("%d^2 = %d\n", a, square(a)); + return 0; +} +``` + +下面的命令可以将这个程序直接编译-链接到可执行文件 `main` (也可以分开成单独的编译步骤、链接步骤)。 + +```shell +gcc main.c -L./lib -lsquare -o main +``` + +这里,`-L./lib` 表示要求链接器在 `./lib` 中寻找链接库,`-lsquare` 表示需要链接 `libsquare.a` 这个头文件。 + +编译好之后,就可以正常使用了。由于静态链接库中的代码会被直接合并到链接产生的可执行文件 `main` 中,因此运行时不需要文件 `libsquare.a`。 diff --git a/includes/authors.md b/includes/authors.md index e1c44477..894c7139 100644 --- a/includes/authors.md +++ b/includes/authors.md @@ -23,3 +23,4 @@ [zeyugao]: https://github.com/zeyugao [relic-yuexi]: https://github.com/relic-yuexi [Jerry-Kwan]: https://github.com/Jerry-Kwan +[luojh]: https://github.com/luojh From f4ce4349a807ff79e53de366951bec60b20049c5 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 2 Sep 2025 07:23:05 +0000 Subject: [PATCH 02/12] [autofix.ci] apply automated fixes --- docs/dev/library.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/library.md b/docs/dev/library.md index bfc3c0ca..dbc2d04b 100644 --- a/docs/dev/library.md +++ b/docs/dev/library.md @@ -107,7 +107,7 @@ int main(void) } ``` -下面的命令可以将这个程序直接编译-链接到可执行文件 `main` (也可以分开成单独的编译步骤、链接步骤)。 +下面的命令可以将这个程序直接编译 - 链接到可执行文件 `main` (也可以分开成单独的编译步骤、链接步骤)。 ```shell gcc main.c -L./lib -lsquare -o main From fcfc89a8ba0ae6ad1ab85e39e5e88e7e4d53bc6a Mon Sep 17 00:00:00 2001 From: luojh Date: Tue, 2 Sep 2025 15:24:58 +0800 Subject: [PATCH 03/12] Add nav link to library.md --- mkdocs.yml | 117 +++++++++++++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index d55ba964..b565411d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -96,63 +96,64 @@ nav: - 章节编写指导: spec/writing.md - 贡献者: spec/contributors.md - 运维基础: - - ops/index.md - - 检查单: ops/checklist.md - - 服务器介绍: ops/server.md - - 包管理系统: ops/package.md - - 服务与日志管理: ops/service.md - - 存储系统: - - ops/storage/index.md - - 基础知识简介: ops/storage/intro.md - - 分区与文件系统: ops/storage/filesystem.md - - LVM: ops/storage/lvm.md - - RAID: ops/storage/raid.md - - 网络存储系统: ops/storage/network.md - - 备份与文件传输工具: ops/storage/backup.md - - ZFS: ops/storage/zfs.md - - 网络系统: - - ops/network/index.md - - 基础知识简介: ops/network/intro.md - - 网络服务实践: - - ops/network-service/index.md - - 网络时间同步: ops/network-service/ntp.md - - 隧道组网: ops/network-service/intranet.md - - Nginx: ops/network-service/nginx.md - - Zeroconf: ops/network-service/zeroconf.md - - 数据库: - - ops/database/index.md - - 关系型数据库: ops/database/rdbms.md - - 键值数据库: ops/database/kv.md - - 问题调试: ops/debug.md - - 虚拟化技术: - - ops/virtualization/index.md - - 基础知识简介: ops/virtualization/intro.md - - 容器: ops/virtualization/container.md - - QEMU/KVM: ops/virtualization/qemu-kvm.md - - 用户账户系统: ops/accounts.md - - 指标监控与告警: - - ops/monitor/index.md - - 本机指标收集: ops/monitor/local.md - - Telegraf + InfluxDB: ops/monitor/telegraf.md - - Prometheus: ops/monitor/prometheus.md - - Grafana: ops/monitor/grafana.md - - 安全: ops/security.md + - ops/index.md + - 检查单: ops/checklist.md + - 服务器介绍: ops/server.md + - 包管理系统: ops/package.md + - 服务与日志管理: ops/service.md + - 存储系统: + - ops/storage/index.md + - 基础知识简介: ops/storage/intro.md + - 分区与文件系统: ops/storage/filesystem.md + - LVM: ops/storage/lvm.md + - RAID: ops/storage/raid.md + - 网络存储系统: ops/storage/network.md + - 备份与文件传输工具: ops/storage/backup.md + - ZFS: ops/storage/zfs.md + - 网络系统: + - ops/network/index.md + - 基础知识简介: ops/network/intro.md + - 网络服务实践: + - ops/network-service/index.md + - 网络时间同步: ops/network-service/ntp.md + - 隧道组网: ops/network-service/intranet.md + - Nginx: ops/network-service/nginx.md + - Zeroconf: ops/network-service/zeroconf.md + - 数据库: + - ops/database/index.md + - 关系型数据库: ops/database/rdbms.md + - 键值数据库: ops/database/kv.md + - 问题调试: ops/debug.md + - 虚拟化技术: + - ops/virtualization/index.md + - 基础知识简介: ops/virtualization/intro.md + - 容器: ops/virtualization/container.md + - QEMU/KVM: ops/virtualization/qemu-kvm.md + - 用户账户系统: ops/accounts.md + - 指标监控与告警: + - ops/monitor/index.md + - 本机指标收集: ops/monitor/local.md + - Telegraf + InfluxDB: ops/monitor/telegraf.md + - Prometheus: ops/monitor/prometheus.md + - Grafana: ops/monitor/grafana.md + - 安全: ops/security.md - 开发速查手册: - - dev/index.md - - 编程语言概览: - - dev/language/index.md - - 前端简介: dev/language/frontend.md - - Python: dev/language/python.md - - C/C++ 与构建工具: dev/language/cxx.md - - Shell 脚本: dev/language/shell.md - - Golang: dev/language/golang.md - - 版本管理与合作: dev/git.md - - SSH 使用技巧: dev/ssh.md + - dev/index.md + - 编程语言概览: + - dev/language/index.md + - 前端简介: dev/language/frontend.md + - Python: dev/language/python.md + - C/C++ 与构建工具: dev/language/cxx.md + - Shell 脚本: dev/language/shell.md + - Golang: dev/language/golang.md + - 版本管理与合作: dev/git.md + - SSH 使用技巧: dev/ssh.md + - Linux 上的链接库: dev/library.md - 高级内容: - - advanced/index.md - - CUDA 环境简介: advanced/cuda.md - - Linux 桌面与窗口系统: advanced/desktop.md - - DAC 与 MAC: advanced/dac-mac.md - - Caddy: advanced/caddy.md - - Nmap: advanced/nmap.md - - ELK: advanced/elk.md + - advanced/index.md + - CUDA 环境简介: advanced/cuda.md + - Linux 桌面与窗口系统: advanced/desktop.md + - DAC 与 MAC: advanced/dac-mac.md + - Caddy: advanced/caddy.md + - Nmap: advanced/nmap.md + - ELK: advanced/elk.md From 20d843956a7ee0f088a197e02ab57ad133c65415 Mon Sep 17 00:00:00 2001 From: luojh Date: Tue, 2 Sep 2025 20:36:47 +0800 Subject: [PATCH 04/12] Fix many typos --- docs/dev/library.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dev/library.md b/docs/dev/library.md index dbc2d04b..c8374448 100644 --- a/docs/dev/library.md +++ b/docs/dev/library.md @@ -48,7 +48,7 @@ dynamiclib["**动态链接库** (运行时加载)"] --> executable ## 源代码 -对于 C 程序而言,链接库的源代码就是普通函数、变量之类,并无太多特殊要求。例如,创建并进入目录 `lib`,在 `square.c` 源文件中写一个函数 `square` +对于 C 程序而言,链接库的源代码就是普通函数、变量之类,并无太多特殊要求。例如,创建并进入目录 `lib`,在 `square.c` 源文件中写一个函数 `square`: ```c int square(int x) @@ -91,10 +91,10 @@ ar rcs libsquare.a square.o ### 使用 -另一个 C 程序 `main.c` 中使用了 `square` 函数,那么首先需要包含 `square.h` 头文件,这样才能知道这个函数的原形,然后就可以正常调用了。 +另一个 C 程序 `main.c` 中使用了 `square` 函数,那么首先需要包含 `square.h` 头文件,这样才能知道这个函数的原型,然后就可以正常调用了。 ```c -#include +#include #include "lib/square.h" int main(void) @@ -113,6 +113,6 @@ int main(void) gcc main.c -L./lib -lsquare -o main ``` -这里,`-L./lib` 表示要求链接器在 `./lib` 中寻找链接库,`-lsquare` 表示需要链接 `libsquare.a` 这个头文件。 +这里,`-L./lib` 表示要求链接器在 `./lib` 中寻找链接库,`-lsquare` 表示需要链接 `libsquare.a` 这个静态链接库文件。 编译好之后,就可以正常使用了。由于静态链接库中的代码会被直接合并到链接产生的可执行文件 `main` 中,因此运行时不需要文件 `libsquare.a`。 From b6703e4fdbaf5506ae479693776176b83fbfc540 Mon Sep 17 00:00:00 2001 From: luojh Date: Tue, 2 Sep 2025 20:42:11 +0800 Subject: [PATCH 05/12] Fix formatting on prettier --- mkdocs.yml | 94 +++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index b565411d..c02de8e2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -96,56 +96,56 @@ nav: - 章节编写指导: spec/writing.md - 贡献者: spec/contributors.md - 运维基础: - - ops/index.md - - 检查单: ops/checklist.md - - 服务器介绍: ops/server.md - - 包管理系统: ops/package.md - - 服务与日志管理: ops/service.md - - 存储系统: - - ops/storage/index.md - - 基础知识简介: ops/storage/intro.md - - 分区与文件系统: ops/storage/filesystem.md - - LVM: ops/storage/lvm.md - - RAID: ops/storage/raid.md - - 网络存储系统: ops/storage/network.md - - 备份与文件传输工具: ops/storage/backup.md - - ZFS: ops/storage/zfs.md - - 网络系统: - - ops/network/index.md - - 基础知识简介: ops/network/intro.md - - 网络服务实践: - - ops/network-service/index.md - - 网络时间同步: ops/network-service/ntp.md - - 隧道组网: ops/network-service/intranet.md - - Nginx: ops/network-service/nginx.md - - Zeroconf: ops/network-service/zeroconf.md - - 数据库: - - ops/database/index.md - - 关系型数据库: ops/database/rdbms.md - - 键值数据库: ops/database/kv.md - - 问题调试: ops/debug.md - - 虚拟化技术: - - ops/virtualization/index.md - - 基础知识简介: ops/virtualization/intro.md - - 容器: ops/virtualization/container.md - - QEMU/KVM: ops/virtualization/qemu-kvm.md - - 用户账户系统: ops/accounts.md - - 指标监控与告警: - - ops/monitor/index.md - - 本机指标收集: ops/monitor/local.md - - Telegraf + InfluxDB: ops/monitor/telegraf.md - - Prometheus: ops/monitor/prometheus.md - - Grafana: ops/monitor/grafana.md - - 安全: ops/security.md + - ops/index.md + - 检查单: ops/checklist.md + - 服务器介绍: ops/server.md + - 包管理系统: ops/package.md + - 服务与日志管理: ops/service.md + - 存储系统: + - ops/storage/index.md + - 基础知识简介: ops/storage/intro.md + - 分区与文件系统: ops/storage/filesystem.md + - LVM: ops/storage/lvm.md + - RAID: ops/storage/raid.md + - 网络存储系统: ops/storage/network.md + - 备份与文件传输工具: ops/storage/backup.md + - ZFS: ops/storage/zfs.md + - 网络系统: + - ops/network/index.md + - 基础知识简介: ops/network/intro.md + - 网络服务实践: + - ops/network-service/index.md + - 网络时间同步: ops/network-service/ntp.md + - 隧道组网: ops/network-service/intranet.md + - Nginx: ops/network-service/nginx.md + - Zeroconf: ops/network-service/zeroconf.md + - 数据库: + - ops/database/index.md + - 关系型数据库: ops/database/rdbms.md + - 键值数据库: ops/database/kv.md + - 问题调试: ops/debug.md + - 虚拟化技术: + - ops/virtualization/index.md + - 基础知识简介: ops/virtualization/intro.md + - 容器: ops/virtualization/container.md + - QEMU/KVM: ops/virtualization/qemu-kvm.md + - 用户账户系统: ops/accounts.md + - 指标监控与告警: + - ops/monitor/index.md + - 本机指标收集: ops/monitor/local.md + - Telegraf + InfluxDB: ops/monitor/telegraf.md + - Prometheus: ops/monitor/prometheus.md + - Grafana: ops/monitor/grafana.md + - 安全: ops/security.md - 开发速查手册: - dev/index.md - 编程语言概览: - - dev/language/index.md - - 前端简介: dev/language/frontend.md - - Python: dev/language/python.md - - C/C++ 与构建工具: dev/language/cxx.md - - Shell 脚本: dev/language/shell.md - - Golang: dev/language/golang.md + - dev/language/index.md + - 前端简介: dev/language/frontend.md + - Python: dev/language/python.md + - C/C++ 与构建工具: dev/language/cxx.md + - Shell 脚本: dev/language/shell.md + - Golang: dev/language/golang.md - 版本管理与合作: dev/git.md - SSH 使用技巧: dev/ssh.md - Linux 上的链接库: dev/library.md From 7a503978e70ead9c6f42ec1c9527d806f2f4fb7d Mon Sep 17 00:00:00 2001 From: luojh Date: Tue, 2 Sep 2025 20:42:11 +0800 Subject: [PATCH 06/12] Fix formatting on prettier & fix typo --- docs/dev/library.md | 2 +- mkdocs.yml | 94 ++++++++++++++++++++++----------------------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/dev/library.md b/docs/dev/library.md index c8374448..601fbbc2 100644 --- a/docs/dev/library.md +++ b/docs/dev/library.md @@ -57,7 +57,7 @@ int square(int x) } ``` -对应的,需要在头文件 `square.h` 中加入这个函数的原型 (prototype) +对应的,需要在头文件 `square.h` 中加入这个函数的原型 (prototype): ```c int square(int x); diff --git a/mkdocs.yml b/mkdocs.yml index b565411d..c02de8e2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -96,56 +96,56 @@ nav: - 章节编写指导: spec/writing.md - 贡献者: spec/contributors.md - 运维基础: - - ops/index.md - - 检查单: ops/checklist.md - - 服务器介绍: ops/server.md - - 包管理系统: ops/package.md - - 服务与日志管理: ops/service.md - - 存储系统: - - ops/storage/index.md - - 基础知识简介: ops/storage/intro.md - - 分区与文件系统: ops/storage/filesystem.md - - LVM: ops/storage/lvm.md - - RAID: ops/storage/raid.md - - 网络存储系统: ops/storage/network.md - - 备份与文件传输工具: ops/storage/backup.md - - ZFS: ops/storage/zfs.md - - 网络系统: - - ops/network/index.md - - 基础知识简介: ops/network/intro.md - - 网络服务实践: - - ops/network-service/index.md - - 网络时间同步: ops/network-service/ntp.md - - 隧道组网: ops/network-service/intranet.md - - Nginx: ops/network-service/nginx.md - - Zeroconf: ops/network-service/zeroconf.md - - 数据库: - - ops/database/index.md - - 关系型数据库: ops/database/rdbms.md - - 键值数据库: ops/database/kv.md - - 问题调试: ops/debug.md - - 虚拟化技术: - - ops/virtualization/index.md - - 基础知识简介: ops/virtualization/intro.md - - 容器: ops/virtualization/container.md - - QEMU/KVM: ops/virtualization/qemu-kvm.md - - 用户账户系统: ops/accounts.md - - 指标监控与告警: - - ops/monitor/index.md - - 本机指标收集: ops/monitor/local.md - - Telegraf + InfluxDB: ops/monitor/telegraf.md - - Prometheus: ops/monitor/prometheus.md - - Grafana: ops/monitor/grafana.md - - 安全: ops/security.md + - ops/index.md + - 检查单: ops/checklist.md + - 服务器介绍: ops/server.md + - 包管理系统: ops/package.md + - 服务与日志管理: ops/service.md + - 存储系统: + - ops/storage/index.md + - 基础知识简介: ops/storage/intro.md + - 分区与文件系统: ops/storage/filesystem.md + - LVM: ops/storage/lvm.md + - RAID: ops/storage/raid.md + - 网络存储系统: ops/storage/network.md + - 备份与文件传输工具: ops/storage/backup.md + - ZFS: ops/storage/zfs.md + - 网络系统: + - ops/network/index.md + - 基础知识简介: ops/network/intro.md + - 网络服务实践: + - ops/network-service/index.md + - 网络时间同步: ops/network-service/ntp.md + - 隧道组网: ops/network-service/intranet.md + - Nginx: ops/network-service/nginx.md + - Zeroconf: ops/network-service/zeroconf.md + - 数据库: + - ops/database/index.md + - 关系型数据库: ops/database/rdbms.md + - 键值数据库: ops/database/kv.md + - 问题调试: ops/debug.md + - 虚拟化技术: + - ops/virtualization/index.md + - 基础知识简介: ops/virtualization/intro.md + - 容器: ops/virtualization/container.md + - QEMU/KVM: ops/virtualization/qemu-kvm.md + - 用户账户系统: ops/accounts.md + - 指标监控与告警: + - ops/monitor/index.md + - 本机指标收集: ops/monitor/local.md + - Telegraf + InfluxDB: ops/monitor/telegraf.md + - Prometheus: ops/monitor/prometheus.md + - Grafana: ops/monitor/grafana.md + - 安全: ops/security.md - 开发速查手册: - dev/index.md - 编程语言概览: - - dev/language/index.md - - 前端简介: dev/language/frontend.md - - Python: dev/language/python.md - - C/C++ 与构建工具: dev/language/cxx.md - - Shell 脚本: dev/language/shell.md - - Golang: dev/language/golang.md + - dev/language/index.md + - 前端简介: dev/language/frontend.md + - Python: dev/language/python.md + - C/C++ 与构建工具: dev/language/cxx.md + - Shell 脚本: dev/language/shell.md + - Golang: dev/language/golang.md - 版本管理与合作: dev/git.md - SSH 使用技巧: dev/ssh.md - Linux 上的链接库: dev/library.md From f8d853b825af21c3d253a16843a59844239262c0 Mon Sep 17 00:00:00 2001 From: luojh Date: Tue, 2 Sep 2025 15:22:23 +0800 Subject: [PATCH 07/12] Add overview ans static linked library. --- docs/dev/library.md | 118 ++++++++++++++++++++++++++++++++++++++++++++ includes/authors.md | 1 + 2 files changed, 119 insertions(+) create mode 100644 docs/dev/library.md diff --git a/docs/dev/library.md b/docs/dev/library.md new file mode 100644 index 00000000..bfc3c0ca --- /dev/null +++ b/docs/dev/library.md @@ -0,0 +1,118 @@ +--- +icon: simple/cplusplus +--- + +# 链接库 + +!!! note "主要作者" + + [@luojh][luojh] + +!!! warning "本文编写中" + +!!! comment "适用范围" + + 本文介绍 Linux 上的**静态链接库** (一般为 `.a` 文件) 和**动态链接库** (一般为 `.so` 文件)。注意:这里的链接库是指包含了可执行二进制代码的库,并不是头文件 (Header file)、Python 库等。 + +## 总览 + +库 (Library),是包含**可重用代码和数据**的模块。 + +### 构建链接库 + +下图给出了一般的可执行文件 (executable)、静态链接库 (static library)、动态链接库 (dynamic library) 的构建过程。 + +```mermaid +flowchart TD + +source["源文件 (*.c, *.cpp)"] -->|编译| target["目标文件 (*.o)"] +header["头文件 (*.h)"] --- source +target -->|链接| executable["可执行文件 (ELF等)"] +target -->|ar rcs| staticlib["静态链接库 (*.a)"] +target -->|gcc -shared| dynamiclib["动态链接库 (*.a)"] +``` + +### 使用链接库 + +下图给出了**使用链接库**的方式。 + +```mermaid +flowchart TD +source["源文件 (*.c, *.cpp)"] -->|编译| target["目标文件 (*.o)"] +header["头文件 (*.h)"] --- source +target --> linker["链接器"] +staticlib["**静态链接库** (链接步骤加入)"] --> linker +linker --> executable["可执行文件 (ELF等)"] +dynamiclib["**动态链接库** (运行时加载)"] --> executable +``` + +## 源代码 + +对于 C 程序而言,链接库的源代码就是普通函数、变量之类,并无太多特殊要求。例如,创建并进入目录 `lib`,在 `square.c` 源文件中写一个函数 `square` + +```c +int square(int x) +{ + return x * x; +} +``` + +对应的,需要在头文件 `square.h` 中加入这个函数的原型 (prototype) + +```c +int square(int x); +``` + +以便其他使用链接库的程序**知道如何使用这个函数** (即使这些程序不知道函数内部的实现)。 + +因为链接库不是完整的、可以独立运行的程序,因此不需要入口点 (比如 `main` 函数)。 + +## 静态链接库 + +静态链接库是在**链接步骤就加入**的链接库类型。 + +### 构建 + +首先按照正常方法编译得到 `.o` 文件: + +```shell +gcc square.c -c -o square.o +``` + +然后使用 `ar` 程序创建静态链接库 `libsquare.a`: + +```shell +ar rcs libsquare.a square.o +``` + +注意这里的 `libsquare.a` 是命名惯例:一般静态链接库的文件名需要为 `lib<名称>.a`。 + +到这里就完成了静态链接库的创建。 + +### 使用 + +另一个 C 程序 `main.c` 中使用了 `square` 函数,那么首先需要包含 `square.h` 头文件,这样才能知道这个函数的原形,然后就可以正常调用了。 + +```c +#include +#include "lib/square.h" + +int main(void) +{ + int a; + scanf("%d", &a); + + printf("%d^2 = %d\n", a, square(a)); + return 0; +} +``` + +下面的命令可以将这个程序直接编译-链接到可执行文件 `main` (也可以分开成单独的编译步骤、链接步骤)。 + +```shell +gcc main.c -L./lib -lsquare -o main +``` + +这里,`-L./lib` 表示要求链接器在 `./lib` 中寻找链接库,`-lsquare` 表示需要链接 `libsquare.a` 这个头文件。 + +编译好之后,就可以正常使用了。由于静态链接库中的代码会被直接合并到链接产生的可执行文件 `main` 中,因此运行时不需要文件 `libsquare.a`。 diff --git a/includes/authors.md b/includes/authors.md index e1c44477..894c7139 100644 --- a/includes/authors.md +++ b/includes/authors.md @@ -23,3 +23,4 @@ [zeyugao]: https://github.com/zeyugao [relic-yuexi]: https://github.com/relic-yuexi [Jerry-Kwan]: https://github.com/Jerry-Kwan +[luojh]: https://github.com/luojh From 7ba354c5d4ee28aabe919d6f847e1954e2963fc9 Mon Sep 17 00:00:00 2001 From: luojh Date: Tue, 2 Sep 2025 15:24:58 +0800 Subject: [PATCH 08/12] Add nav link to library.md --- mkdocs.yml | 117 +++++++++++++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index d55ba964..b565411d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -96,63 +96,64 @@ nav: - 章节编写指导: spec/writing.md - 贡献者: spec/contributors.md - 运维基础: - - ops/index.md - - 检查单: ops/checklist.md - - 服务器介绍: ops/server.md - - 包管理系统: ops/package.md - - 服务与日志管理: ops/service.md - - 存储系统: - - ops/storage/index.md - - 基础知识简介: ops/storage/intro.md - - 分区与文件系统: ops/storage/filesystem.md - - LVM: ops/storage/lvm.md - - RAID: ops/storage/raid.md - - 网络存储系统: ops/storage/network.md - - 备份与文件传输工具: ops/storage/backup.md - - ZFS: ops/storage/zfs.md - - 网络系统: - - ops/network/index.md - - 基础知识简介: ops/network/intro.md - - 网络服务实践: - - ops/network-service/index.md - - 网络时间同步: ops/network-service/ntp.md - - 隧道组网: ops/network-service/intranet.md - - Nginx: ops/network-service/nginx.md - - Zeroconf: ops/network-service/zeroconf.md - - 数据库: - - ops/database/index.md - - 关系型数据库: ops/database/rdbms.md - - 键值数据库: ops/database/kv.md - - 问题调试: ops/debug.md - - 虚拟化技术: - - ops/virtualization/index.md - - 基础知识简介: ops/virtualization/intro.md - - 容器: ops/virtualization/container.md - - QEMU/KVM: ops/virtualization/qemu-kvm.md - - 用户账户系统: ops/accounts.md - - 指标监控与告警: - - ops/monitor/index.md - - 本机指标收集: ops/monitor/local.md - - Telegraf + InfluxDB: ops/monitor/telegraf.md - - Prometheus: ops/monitor/prometheus.md - - Grafana: ops/monitor/grafana.md - - 安全: ops/security.md + - ops/index.md + - 检查单: ops/checklist.md + - 服务器介绍: ops/server.md + - 包管理系统: ops/package.md + - 服务与日志管理: ops/service.md + - 存储系统: + - ops/storage/index.md + - 基础知识简介: ops/storage/intro.md + - 分区与文件系统: ops/storage/filesystem.md + - LVM: ops/storage/lvm.md + - RAID: ops/storage/raid.md + - 网络存储系统: ops/storage/network.md + - 备份与文件传输工具: ops/storage/backup.md + - ZFS: ops/storage/zfs.md + - 网络系统: + - ops/network/index.md + - 基础知识简介: ops/network/intro.md + - 网络服务实践: + - ops/network-service/index.md + - 网络时间同步: ops/network-service/ntp.md + - 隧道组网: ops/network-service/intranet.md + - Nginx: ops/network-service/nginx.md + - Zeroconf: ops/network-service/zeroconf.md + - 数据库: + - ops/database/index.md + - 关系型数据库: ops/database/rdbms.md + - 键值数据库: ops/database/kv.md + - 问题调试: ops/debug.md + - 虚拟化技术: + - ops/virtualization/index.md + - 基础知识简介: ops/virtualization/intro.md + - 容器: ops/virtualization/container.md + - QEMU/KVM: ops/virtualization/qemu-kvm.md + - 用户账户系统: ops/accounts.md + - 指标监控与告警: + - ops/monitor/index.md + - 本机指标收集: ops/monitor/local.md + - Telegraf + InfluxDB: ops/monitor/telegraf.md + - Prometheus: ops/monitor/prometheus.md + - Grafana: ops/monitor/grafana.md + - 安全: ops/security.md - 开发速查手册: - - dev/index.md - - 编程语言概览: - - dev/language/index.md - - 前端简介: dev/language/frontend.md - - Python: dev/language/python.md - - C/C++ 与构建工具: dev/language/cxx.md - - Shell 脚本: dev/language/shell.md - - Golang: dev/language/golang.md - - 版本管理与合作: dev/git.md - - SSH 使用技巧: dev/ssh.md + - dev/index.md + - 编程语言概览: + - dev/language/index.md + - 前端简介: dev/language/frontend.md + - Python: dev/language/python.md + - C/C++ 与构建工具: dev/language/cxx.md + - Shell 脚本: dev/language/shell.md + - Golang: dev/language/golang.md + - 版本管理与合作: dev/git.md + - SSH 使用技巧: dev/ssh.md + - Linux 上的链接库: dev/library.md - 高级内容: - - advanced/index.md - - CUDA 环境简介: advanced/cuda.md - - Linux 桌面与窗口系统: advanced/desktop.md - - DAC 与 MAC: advanced/dac-mac.md - - Caddy: advanced/caddy.md - - Nmap: advanced/nmap.md - - ELK: advanced/elk.md + - advanced/index.md + - CUDA 环境简介: advanced/cuda.md + - Linux 桌面与窗口系统: advanced/desktop.md + - DAC 与 MAC: advanced/dac-mac.md + - Caddy: advanced/caddy.md + - Nmap: advanced/nmap.md + - ELK: advanced/elk.md From a22ab5c6fd959dfe19dc948c8275b04c320fbc7c Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 2 Sep 2025 07:23:05 +0000 Subject: [PATCH 09/12] [autofix.ci] apply automated fixes --- docs/dev/library.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/library.md b/docs/dev/library.md index bfc3c0ca..dbc2d04b 100644 --- a/docs/dev/library.md +++ b/docs/dev/library.md @@ -107,7 +107,7 @@ int main(void) } ``` -下面的命令可以将这个程序直接编译-链接到可执行文件 `main` (也可以分开成单独的编译步骤、链接步骤)。 +下面的命令可以将这个程序直接编译 - 链接到可执行文件 `main` (也可以分开成单独的编译步骤、链接步骤)。 ```shell gcc main.c -L./lib -lsquare -o main From d8a7d9642b9de78363db64848b25557e3fa28c82 Mon Sep 17 00:00:00 2001 From: luojh Date: Tue, 2 Sep 2025 20:36:47 +0800 Subject: [PATCH 10/12] Fix many typos --- docs/dev/library.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dev/library.md b/docs/dev/library.md index dbc2d04b..c8374448 100644 --- a/docs/dev/library.md +++ b/docs/dev/library.md @@ -48,7 +48,7 @@ dynamiclib["**动态链接库** (运行时加载)"] --> executable ## 源代码 -对于 C 程序而言,链接库的源代码就是普通函数、变量之类,并无太多特殊要求。例如,创建并进入目录 `lib`,在 `square.c` 源文件中写一个函数 `square` +对于 C 程序而言,链接库的源代码就是普通函数、变量之类,并无太多特殊要求。例如,创建并进入目录 `lib`,在 `square.c` 源文件中写一个函数 `square`: ```c int square(int x) @@ -91,10 +91,10 @@ ar rcs libsquare.a square.o ### 使用 -另一个 C 程序 `main.c` 中使用了 `square` 函数,那么首先需要包含 `square.h` 头文件,这样才能知道这个函数的原形,然后就可以正常调用了。 +另一个 C 程序 `main.c` 中使用了 `square` 函数,那么首先需要包含 `square.h` 头文件,这样才能知道这个函数的原型,然后就可以正常调用了。 ```c -#include +#include #include "lib/square.h" int main(void) @@ -113,6 +113,6 @@ int main(void) gcc main.c -L./lib -lsquare -o main ``` -这里,`-L./lib` 表示要求链接器在 `./lib` 中寻找链接库,`-lsquare` 表示需要链接 `libsquare.a` 这个头文件。 +这里,`-L./lib` 表示要求链接器在 `./lib` 中寻找链接库,`-lsquare` 表示需要链接 `libsquare.a` 这个静态链接库文件。 编译好之后,就可以正常使用了。由于静态链接库中的代码会被直接合并到链接产生的可执行文件 `main` 中,因此运行时不需要文件 `libsquare.a`。 From 8d404ddf5bd9af8ee9909e3df1004862a0f640c3 Mon Sep 17 00:00:00 2001 From: luojh Date: Tue, 2 Sep 2025 20:42:11 +0800 Subject: [PATCH 11/12] Fix formatting on prettier & fix typo --- docs/dev/library.md | 2 +- mkdocs.yml | 94 ++++++++++++++++++++++----------------------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/dev/library.md b/docs/dev/library.md index c8374448..601fbbc2 100644 --- a/docs/dev/library.md +++ b/docs/dev/library.md @@ -57,7 +57,7 @@ int square(int x) } ``` -对应的,需要在头文件 `square.h` 中加入这个函数的原型 (prototype) +对应的,需要在头文件 `square.h` 中加入这个函数的原型 (prototype): ```c int square(int x); diff --git a/mkdocs.yml b/mkdocs.yml index b565411d..c02de8e2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -96,56 +96,56 @@ nav: - 章节编写指导: spec/writing.md - 贡献者: spec/contributors.md - 运维基础: - - ops/index.md - - 检查单: ops/checklist.md - - 服务器介绍: ops/server.md - - 包管理系统: ops/package.md - - 服务与日志管理: ops/service.md - - 存储系统: - - ops/storage/index.md - - 基础知识简介: ops/storage/intro.md - - 分区与文件系统: ops/storage/filesystem.md - - LVM: ops/storage/lvm.md - - RAID: ops/storage/raid.md - - 网络存储系统: ops/storage/network.md - - 备份与文件传输工具: ops/storage/backup.md - - ZFS: ops/storage/zfs.md - - 网络系统: - - ops/network/index.md - - 基础知识简介: ops/network/intro.md - - 网络服务实践: - - ops/network-service/index.md - - 网络时间同步: ops/network-service/ntp.md - - 隧道组网: ops/network-service/intranet.md - - Nginx: ops/network-service/nginx.md - - Zeroconf: ops/network-service/zeroconf.md - - 数据库: - - ops/database/index.md - - 关系型数据库: ops/database/rdbms.md - - 键值数据库: ops/database/kv.md - - 问题调试: ops/debug.md - - 虚拟化技术: - - ops/virtualization/index.md - - 基础知识简介: ops/virtualization/intro.md - - 容器: ops/virtualization/container.md - - QEMU/KVM: ops/virtualization/qemu-kvm.md - - 用户账户系统: ops/accounts.md - - 指标监控与告警: - - ops/monitor/index.md - - 本机指标收集: ops/monitor/local.md - - Telegraf + InfluxDB: ops/monitor/telegraf.md - - Prometheus: ops/monitor/prometheus.md - - Grafana: ops/monitor/grafana.md - - 安全: ops/security.md + - ops/index.md + - 检查单: ops/checklist.md + - 服务器介绍: ops/server.md + - 包管理系统: ops/package.md + - 服务与日志管理: ops/service.md + - 存储系统: + - ops/storage/index.md + - 基础知识简介: ops/storage/intro.md + - 分区与文件系统: ops/storage/filesystem.md + - LVM: ops/storage/lvm.md + - RAID: ops/storage/raid.md + - 网络存储系统: ops/storage/network.md + - 备份与文件传输工具: ops/storage/backup.md + - ZFS: ops/storage/zfs.md + - 网络系统: + - ops/network/index.md + - 基础知识简介: ops/network/intro.md + - 网络服务实践: + - ops/network-service/index.md + - 网络时间同步: ops/network-service/ntp.md + - 隧道组网: ops/network-service/intranet.md + - Nginx: ops/network-service/nginx.md + - Zeroconf: ops/network-service/zeroconf.md + - 数据库: + - ops/database/index.md + - 关系型数据库: ops/database/rdbms.md + - 键值数据库: ops/database/kv.md + - 问题调试: ops/debug.md + - 虚拟化技术: + - ops/virtualization/index.md + - 基础知识简介: ops/virtualization/intro.md + - 容器: ops/virtualization/container.md + - QEMU/KVM: ops/virtualization/qemu-kvm.md + - 用户账户系统: ops/accounts.md + - 指标监控与告警: + - ops/monitor/index.md + - 本机指标收集: ops/monitor/local.md + - Telegraf + InfluxDB: ops/monitor/telegraf.md + - Prometheus: ops/monitor/prometheus.md + - Grafana: ops/monitor/grafana.md + - 安全: ops/security.md - 开发速查手册: - dev/index.md - 编程语言概览: - - dev/language/index.md - - 前端简介: dev/language/frontend.md - - Python: dev/language/python.md - - C/C++ 与构建工具: dev/language/cxx.md - - Shell 脚本: dev/language/shell.md - - Golang: dev/language/golang.md + - dev/language/index.md + - 前端简介: dev/language/frontend.md + - Python: dev/language/python.md + - C/C++ 与构建工具: dev/language/cxx.md + - Shell 脚本: dev/language/shell.md + - Golang: dev/language/golang.md - 版本管理与合作: dev/git.md - SSH 使用技巧: dev/ssh.md - Linux 上的链接库: dev/library.md From 43b4eaf7c9743d598a5f87360907009463c92c1e Mon Sep 17 00:00:00 2001 From: luojh Date: Fri, 5 Sep 2025 19:37:53 +0800 Subject: [PATCH 12/12] Update dev/library --- docs/dev/library.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/dev/library.md b/docs/dev/library.md index 601fbbc2..5fcdc0e2 100644 --- a/docs/dev/library.md +++ b/docs/dev/library.md @@ -29,7 +29,7 @@ source["源文件 (*.c, *.cpp)"] -->|编译| target["目标文件 (*.o)"] header["头文件 (*.h)"] --- source target -->|链接| executable["可执行文件 (ELF等)"] target -->|ar rcs| staticlib["静态链接库 (*.a)"] -target -->|gcc -shared| dynamiclib["动态链接库 (*.a)"] +target -->|gcc -shared| dynamiclib["动态链接库 (*.so)"] ``` ### 使用链接库 @@ -116,3 +116,16 @@ gcc main.c -L./lib -lsquare -o main 这里,`-L./lib` 表示要求链接器在 `./lib` 中寻找链接库,`-lsquare` 表示需要链接 `libsquare.a` 这个静态链接库文件。 编译好之后,就可以正常使用了。由于静态链接库中的代码会被直接合并到链接产生的可执行文件 `main` 中,因此运行时不需要文件 `libsquare.a`。 + +## 动态链接库 + +动态链接库与静态链接库类似,都是首先需要对库的代码进行编译。但是,动态链接库需要生成位置无关代码 (PIC),且是在依赖这个库的程序**运行时**由加载器 (loader) 动态加载到内存空间中的。 + +!!! comment "关于动态加载" + + 如果多个程序共用一份动态链接库,那么内存中可以只有一份动态链接库的二进制代码,所有程序通过虚拟内存机制“看到”这份二进制代码,而非像静态链接库那样每个依赖于它的程序中都嵌入一份,有效节约了空间。 + + 也正因为此,动态库和依赖于动态库的程序是分开存储的 (两个不同的文件),这可能会带来一些问题: + + - 不同版本的动态库可能都安装在系统上,如果使用了不正确的版本,库提供的接口可能不对应,这会导致栈不平衡等严重的问题。 + - 动态链接库 (特别是常用的那些) 有被恶意修改的可能,如果程序依赖一个动态库而它被修改的话,几乎可以执行任意代码。