创建一个共享对象C,它依赖于静态库B,而静态库B本身依赖于静态库a 目标

创建一个共享对象C,它依赖于静态库B,而静态库B本身依赖于静态库a 目标,c,linker,static-libraries,dynamic-library,C,Linker,Static Libraries,Dynamic Library,我想创建一个共享库libsquare.so,它静态链接到libmul.a,它本身静态链接到libadd.a 处境 我通过链接libadd.a来创建libmul.a。 然后我通过链接刚刚创建的libmul.a来创建libsquare.so libmul.a具有add-函数的代码 问题 当我将其链接到一个共享对象,并查看符号表时,添加-符号仍然存在,但未定义(*UND*),而不是在.text部分 我有一个MWE演示它 这里是objdump-t libsquare.so的一部分 libsquare.s

我想创建一个共享库
libsquare.so
,它静态链接到
libmul.a
,它本身静态链接到
libadd.a

处境 我通过链接
libadd.a
来创建
libmul.a
。 然后我通过链接刚刚创建的
libmul.a
来创建
libsquare.so

libmul.a
具有
add
-函数的代码

问题 当我将其链接到一个共享对象,并查看符号表时,
添加
-符号仍然存在,但未定义(
*UND*
),而不是在
.text
部分

我有一个MWE演示它

这里是
objdump-t libsquare.so的一部分

libsquare.so:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000         *UND*  0000000000000000              add
0000000000001119 g     F .text  000000000000001c              square
0000000000001135 g     F .text  000000000000003b              mul
... // some symbols omitted here... See repo for entire table
这里是整个
objdump-t libmul.a

mul.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 mul.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 g     F .text  000000000000003b mul
0000000000000000         *UND*  0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000000000         *UND*  0000000000000000 add


In nested archive libadd.a:

add.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 add.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 g     F .text  0000000000000014 add
实际上,运行的命令是:

cc-fPIC-rdynamic-o add.o-c add.c
cc-fPIC-rdynamic-o mul.o-c mul.c
cc-fPIC-rdynamic-o-square.o-c square.c
ar rcs libadd.a add.o
ranlib libadd.a
ar rcs libmul.a mul.o libadd.a
兰利布·利布穆尔
gcc-shared-Wl,-soname=square-o libsquare.so square.o libmul.a
cc-fPIC-rdynamic-o test-w-lib.o-c test-w-lib.c
cc-o test-w-lib libsquare.so test-w-lib.o-ldl
/usr/bin/ld:libsquare.so:add的未定义引用
collect2:错误:ld返回了1个退出状态

没关系,我找到了解决办法

开玩笑:)

问题在于我的
ar
命令。当通过
ar rcs libmul.a mul.o libadd.a
创建
libmul.a
时,它会创建一个名为
libmul.a
的归档文件,其中包含
mul.o
libadd.a
,如下所示:

libmul.a
├── mul.o
└── libadd.a
    └── add.o
另请参见objdump:

$ objdump libmul.a -t
In archive libmul.a:

mul.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 mul.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 g     F .text  000000000000003b mul
0000000000000000         *UND*  0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000000000         *UND*  0000000000000000 add


In nested archive libadd.a:

add.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 add.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 g     F .text  0000000000000014 add
当最终链接
libmul.a
gcc一样使用lib mul.c libmul.a
时,这也会失败。(因此,总体问题与共享对象部分无关)

解决方案 如注释和中所述,必须从dependency lib
libadd.a
解压对象,才能创建另一个lib
libmul.a

因此,要正确生成
libmul.a

libmul.a: mul.o libadd.a
    rm -rf libadd; mkdir libadd; cd libadd; ar x ../libadd.a
    ar rcs ${@} ${<} ./libadd/*.o
    ranlib ${@}
最后,要正确生成libsquare.so

libsquare.so: square.o libmul.a
    rm -rf libmul;  mkdir libmul; cd libmul; ar x ../libmul.a
    $(CC) -shared -Wl,-soname=square -o ${@} ${<} libmul/*.o

只是
gcc-shared-Wl,-soname=square-o libsquare.so square.o mul.o add.o
<代码>是静态链接的如果您希望将它们包含在库中,那么请解压缩静态库并链接到对象文件。包含是什么意思?假设我没有访问
add.o
,这是一个不同的项目,有自己的依赖项,我只得到
libadd.o
。所谓包含,我的意思是共享库将包含其中的所有代码。“静态链接”是什么意思?静态链接只意味着编译。解压缩静态库并从中提取对象文件。然后使用对象文件进行编译。静态库只是列出一个.o文件的“zip”,没有更多,也没有更少或者使用
--整个归档
,其作用与在编译行中包含所有目标文件相同。回答你的问题了吗?这个回答提到了拆包。它回答了你的问题吗?在提出问题之前,您做了哪些研究?“libmul.a有add函数的代码。”:您是如何理解的?这是错误的。只需使用
gcc-shared-Wl,-soname=square-o libsquare.so square.o libmul.a libadd.a
libsquare.so: square.o libmul.a
    rm -rf libmul;  mkdir libmul; cd libmul; ar x ../libmul.a
    $(CC) -shared -Wl,-soname=square -o ${@} ${<} libmul/*.o
$ objdump libsquare.so -t

libsquare.so:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000              square.c
0000000000000000 l    df *ABS*  0000000000000000              add.c
0000000000000000 l    df *ABS*  0000000000000000              mul.c
0000000000001135 g     F .text  0000000000000014              add
0000000000001119 g     F .text  000000000000001c              square
0000000000001149 g     F .text  000000000000003b              mul
...