技术文档记录
问题:使用自编译的libc.so库进行动态链接报错
步骤:
- 获取源码:下载libc源码 https://ftp.gnu.org/gnu/glibc/glibc-2.29.tar.gz
- 调试模式:使用
export CFLAGS=" -g3 -Og"
来编译libc.so
- 测试编译:使用编译后的
libc.so
来编译示例程序demo
- 定位问题:为了增加详细的错误输出,设置链接标志
export LDFLAGS="${LDFLAGS} -Wl,-verbose"
问题分析
- 替换不完整:最初在原有工具链的基础上,只替换了
crt1.o
、crti.o
、crtn.o
、libc.so
和ld.so
最后解决问题的方法
一定要正确使用 make install
- 重要的配置步骤:运行
./configure --prefix=/path/to/install
来设置安装路径 - 结合
--prefix
参数,执行make install
后,所有的需要使用到该组件的库或者头文件都会整理到/path/to/install
下 - 完整替换所有相关文件,才能确保库文件的正常功能
编译指定C库的正确姿势
设置编译器和链接器的标志:
CFLAGS="-I${LIBCPATH}/include"
## 特别需要注意 -Wl,--rpath=指定是运行时的库搜索 -Wl,--dynamic-linker=指定运行时搜索的链接库 示例中的ld-2.29.so修改为你的ld库名
LDFLAGS="-L${LIBCPATH}/lib -lc -Wl,--rpath=/path/to/yourdev/lib -Wl,--dynamic-linker=/path/to/yourdev/lib/ld-2.29.so"
基础说明
告诉链接器使用的选项:
- 运行时搜索路径:
-Wl,--rpath=${LIBCPATH}/lib
,特别需要注意,这个路径是你实际运行环境的路径,不是编译服务器上的路径 - 动态库链接器:
-Wl,--dynamic-linker=${LIBCPATH}/lib/ld-2.29.so
,特别需要注意,这个路径是你实际运行环境的路径,不是编译服务器上的路径 - 编译链接:特别注意libc.so是一个链接脚本,详细的设置看链接脚本说明章节
链接脚本libc.so
## libc.so内容一般如下:
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( /path/to/your_compile_server/lib/libc.so.6 /path/to/your_compile_server/lib/libc_nonshared.a AS_NEEDED ( /path/to/your_compile_server/lib/ld-linux-armhf.so.3 ) )
注意针对修改GROUP为你的编译服务器的路径即可