一周学习经验汇总之OpenSSH6 移植与库链接心得笔记
1. 环境与目标
在嵌入式系统上移植 OpenSSH6
系统存在 自研 OpenSSL 1.0.1 库(
libsrosssl101.so
,libsroscrypto101.so
)同时需要依赖 系统通用库(
libdl
,libutil
,libcrypt
,libresolv
,zlib
等)目标:保证 编译能通过,运行时能优先加载自研库,并且与系统库 稳定共存。
2. 主要问题与排查过程
2.1 编译阶段问题
表现:出现
undefined reference
或cannot find -lxxx
原因:
-L
指定目录不全,导致找不到库静态库(.a)和动态库(.so)混用,引入交叉依赖,导致链接失败
经验:
-L
用于编译阶段搜索库路径避免盲目引入
.a
,否则最终包过大且依赖复杂
2.2 运行阶段问题
表现:运行
dlz_sshd
没有输出,或者直接报错 找不到系统库原因:
动态加载器
ld.so
默认优先使用 RPATH如果只设置
/usr/lib/openssl101
,会覆盖系统库路径,导致找不到libdl.so.2
等
经验:
RPATH
需同时包含 自研库目录 与 系统库目录RPATH 优先级高于
LD_LIBRARY_PATH
,必须小心配置
2.3 动态库冲突
表现:加载到错误版本的 OpenSSL(比如系统默认 vs 自研库),导致运行时异常
经验:
通过
-Wl,-rpath
指定搜索顺序,确保自研库优先用
ldd ./dlz_sshd
检查最终可执行文件依赖必要时使用
LD_DEBUG=libs
跟踪库加载过程
3. 关键解决方案
3.1 Makefile 配置要点
# 运行阶段优先搜索的库目录
OPENSSL101_RUNDIR := /usr/lib/openssl101# 编译 & 链接阶段
OPENSSH_LDFLAGS := -L$(ROOTFS)/usr/lib \-Wl,-rpath,$(OPENSSL101_RUNDIR):/usr/libLIBS := -lsrosssl101 -lsroscrypto101 -ldl -lutil -lz -lcrypt -lresolvsshd: $(SSHDOBJS)$(CC) -o $@ $(SSHDOBJS) $(LIBS) $(OPENSSH_LDFLAGS)
3.2 验证方法
ldd 检查依赖
ldd ./dlz_sshd
确保自研库和系统库都能正确加载
调试加载顺序
LD_DEBUG=libs ./dlz_sshd
确认优先从
/usr/lib/openssl101
加载 ssl/crypto
4. 总结出的经验点
编译阶段(-L) vs 运行阶段(RPATH)
-L
只影响 编译器链接RPATH
决定 运行时加载顺序
双库共存原则
自研库放在专用目录(如
/usr/lib/openssl101
)系统库保留
/usr/lib
,避免覆盖
调试工具必备
ldd
→ 检查可执行文件的依赖库LD_DEBUG=libs
→ 跟踪动态库加载顺序readelf -d
→ 查看 ELF 的 RPATH 和依赖
避免静态库滥用
静态库
.a
打包会导致臃肿,除非必要,不要混编
5. 收获与提升
掌握了 编译期 vs 运行期 动态库搜索机制
熟悉了 RPATH、LD_LIBRARY_PATH、ld.so 的关系
积累了 调试工具链 使用方法
学会了在复杂依赖环境下让 自研库与系统库共存