ILD

--whole-archive
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2025-12-3 站点:Inside Linux Development

最近有个共享库libraw的编译,需要将一个额外的第三方库静态库编译进共享库。这个第三方库是gpr库,用来让libraw.so支持gpr格式的图片。


第一步:编译gpr库

gpr默认编译出来是静态库,但是没有加-fPIC选项,导致不能链接到共享库

/usr/bin/ld: /work/nas/gpr-1.1/staging/lib/libdng_sdk.a(dng_host.cpp.o): relocation R_X86_64_PC32 against symbol `_ZTV8dng_host' can not be used when making a shared object; recompile with -fPIC


但是如果一个符号只是内部用的话,可以不加-fPIC选项


第二步:将gpr库链接到libraw.so


使用 -Lstaging/lib -lgrp_sdk


编译libraw.so没有报错报错,但是在编译使用libraw.so的可执行程序时,报错了。

ld: lib/.libs/libraw.so: undefined reference to `InitImage'


$ readelf -a build/lib/.libs/libraw.so | grep InitImage

00000022f3b8  00c900000402 R_AARCH64_JUMP_SL 0000000000000000 InitImage + 0

   201: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND InitImage

  6374: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND InitImage


发现这个符号是UND,应该是静态库没有链接到共享库里面。


经过搜索发现了--whole-archive选项,手动运行编译命令,在静态库前后加上:

-Wl,--whole-archive /work/gpr-1.1/lib/libdng_sdk.a  /work/gpr-1.1/lib/libgpr_sdk.a -Wl,--no-whole-archive \


运行后

$ readelf -a libraw.so.23.0.0 | grep InitImage

00000024f350  0bb700000402 R_AARCH64_JUMP_SL 00000000001707b0 InitImage + 0

  2999: 00000000001707b0    44 FUNC    GLOBAL DEFAULT   12 InitImage

  6753: 00000000001707b0    44 FUNC    GLOBAL DEFAULT   12 InitImage


备注:

静态库,可以-Lpath -lcommon,也可以直接指定路径,/path/libcommon.a


LD手册说的很详细

whole-archive是把静态库的所有object包含进去,通常用来将一个archive链接到shared libary


--whole-archive

For each archive mentioned on the command line after the ‘--whole-archive’

option, include every object file in the archive in the link, rather than searching

the archive for the required object files. This is normally used to turn an archive

file into a shared library, forcing every object to be included in the resulting

shared library. This option may be used more than once.


Two notes when using this option from gcc: First, gcc doesn’t know about this

option, so you have to use ‘-Wl,-whole-archive’. Second, don’t forget to use

‘-Wl,-no-whole-archive’ after your list of archives, because gcc will add its

own list of archives to your link and you may not want this flag to affect those

as well.



参考:

https://stackoverflow.com/questions/17558881/how-to-use-whole-archive-with-libtool


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.