开发规范之动态库(使用与容易遗漏的部分)

📅 2026/7/9 6:28:29
开发规范之动态库(使用与容易遗漏的部分)
一、为什么拷贝到/usr/lib必须加sudo1. 核心原因/usr/lib是系统保护目录普通用户没有写入权限Linux 权限机制/usr/下面属于系统核心目录存放系统自带软件、基础库、系统程序默认只有root 超级用户才能新建、删除、修改里面的文件你当前登录的普通用户执行cp libxxx.so /usr/lib会直接报错Permission denied权限拒绝。sudosuperuser do临时借用 root 管理员权限执行这一条拷贝命令改完自动收回权限防止普通用户乱删系统文件破坏系统。2. 光sudo cp还不够必须再加一步sudo cp libadd.so /usr/lib sudo ldconfigLinux 不会每次运行程序遍历所有文件夹找库而是靠缓存文件/etc/ld.so.cache快速查找ldconfig就是刷新这个系统动态库缓存把新放进/usr/lib的 so 录入系统索引不然程序依旧提示找不到库。二、那为什么非要丢进/usr/lib根源是动态库运行时查找规则静态库编译链接时直接打包进程序运行不需要原.a文件动态库只在编译时记录库名程序运行时才去硬盘搜索.so文件搜索优先级顺序编译时-Wl,-rpath硬编码路径环境变量LD_LIBRARY_PATH/etc/ld.so.cache系统缓存包含/usr/lib、/lib兜底默认路径/lib、/usr/lib把 so 放到/usr/lib就是放进系统默认兜底搜索目录任何终端、任何用户运行程序系统都能自动找到库不用额外配环境变量。三、完全可以不用 sudo、不用往系统目录拷贝三种更常用方案方案 1临时环境变量开发最常用不用 sudoso 还在当前文件夹执行export LD_LIBRARY_PATH./:$LD_LIBRARY_PATH ./a.out仅当前终端窗口生效关闭终端就失效适合调试。方案 2编译时指定 rpath永久绑定库路径编译 main 时直接写死 so 所在文件夹gcc main.c -L. -ladd -Wl,-rpath.生成的可执行文件自带查找路径以后直接./a.out就能运行全程不需要 sudo、不用移动 so 文件。方案 3添加自定义路径到系统缓存推荐正规安装新建文件夹放库sudo mkdir /usr/local/mylib复制 so 进去cp libadd.so /usr/local/mylib不用 sudo 也能写自定义目录把路径写入系统配置echo /usr/local/mylib | sudo tee /etc/ld.so.conf.d/mylib.conf sudo ldconfig后续全局可用也不会污染原生/usr/lib系统目录。四、动静库在头文件、声明那套规则完全一致.so只包含机器码 符号绝不打包.h 头文件库源码add.c里#include add.h只是作者自检防止声明实现不一致使用者可以丢弃原头文件自己新建任意命名.h只要函数签名匹配就能编译调用结构体、宏、typedef 必须依赖作者提供的.h否则无法使用。极简总结sudo只是为了突破系统目录写入权限限制不是动态库本身强制要求放进/usr/lib只是为了让系统默认路径能搜到 so属于部署方式不是唯一用法日常写代码优先用LD_LIBRARY_PATH或者-rpath尽量少往/usr/lib塞自定义库避免系统文件杂乱。