C++ 如何使用静态库(.a文件)而不是一组对象文件(.o)来创建共享库

C++ 如何使用静态库(.a文件)而不是一组对象文件(.o)来创建共享库,c++,g++,linker-errors,C++,G++,Linker Errors,我有一个共享库,我用它来创建一个可执行的二进制文件。我只能控制库和可执行二进制文件的构建过程,而不能控制涉及的源文件。正如预期的那样,可执行二进制文件中的源文件引用了库中的许多函数 目前,共享库是直接使用objectfiles(.o)构建的 g++ -shared ${OBJECT_FILES} -o ${SHARED_LIBRARY} 我也想通过在静态库(.a文件或achive)中分组来发布对象文件 为了节省空间,我在创建归档文件时删除了所有.o文件。现在,build命令是 g++ -sha

我有一个共享库,我用它来创建一个可执行的二进制文件。我只能控制库和可执行二进制文件的构建过程,而不能控制涉及的源文件。正如预期的那样,可执行二进制文件中的源文件引用了库中的许多函数

目前,共享库是直接使用objectfiles(.o)构建的

g++ -shared ${OBJECT_FILES} -o ${SHARED_LIBRARY}
我也想通过在静态库(.a文件或achive)中分组来发布对象文件

为了节省空间,我在创建归档文件时删除了所有.o文件。现在,build命令是

g++ -shared ${ACRCHIVE_FILE} -o ${SHARED_LIBRARY}
图书馆建设得很好。
但是,当我试图通过链接到此共享库来构建可执行二进制文件时,该二进制文件引用的符号没有定义,并且无法链接。(未定义对
上下文::Get()
的引用)


根据我的理解,无论是直接使用.o文件创建共享库,还是创建包含所有.o文件的存档,但是很明显,要么这是不可能的,要么我可能遗漏了什么。

共享库
libfoo。因此
应该包含代码,而静态库
libfoo.a
包含普通的非PIC代码。因此,无法从静态库创建共享库

共享库需要位置独立的代码,因为它们的段位于几乎任意和可变的地址,而没有固定的映射。。。另见

原则上,您可以从PIC对象文件构建静态库,但实际上没有人这样做

你可以(如果你真的坚持)用非PIC代码创建一个共享对象,但是结果会有非常糟糕的性能;动态链接器会有很多,所以大多数段都是非共享的,动态链接会非常慢

要将共享库的
foo.cc
编译为PIC对象文件
foo.PIC.o

g++ -Wall -c -O foo.cc  -fPIC -o foo.pic.o
要在普通非PIC对象文件
foo.o
中编译静态库,请执行以下操作:

g++ -Wall -c -O foo.cc -o foo.o 
要将
foo.pic.o
bar.pic.o
的共享库制作成
libfoobar.so
在一些
libdep.so
共享库中链接:

g++ -shared foo.pic.o bar.pic.o -ldep -o libfoobar.so
在创建上述共享库时,通常需要添加更多链接选项,例如
-Wl,-rpath,
。。。或
-Wl,-soname,

顺便说一句,不可能将存档文件
libfoobar.a
(即使它是由PIC文件组成)链接到
libfoobar.so
,因为没有未定义的名称,需要链接
libfoobar.a
(也许您可以尝试用
-u symb
取消某些符号
symb
的定义,但我不建议这样做)

foo.o
bar.o
的静态库制作成
libfoobar.a

ar cv libfoobar.a foo.o bar.o
请注意,由于GNU
ar
完成了它的工作,所以不再需要(创建归档的索引)

同时阅读,,,(通常,如果主程序在运行时加载了
dlopen
-ed插件,则需要将其与
-rdynamic
链接,以使插件能够在主程序中找到一些符号)

注意:我只需要构建一个共享库,而不关心静态链接。请注意,在某些系统上,PIC的开销很小(稍大和/或较慢的代码)。好吧,x86-64上的PIC开销比32位Linux x86代码上的开销要小。在某些体系结构和ABIs上,PIC的开销可以忽略不计(甚至可能比非位置独立代码更有效)


引用:&&

Mebbe试试这个?你试过用g++-shared-Wl,--no未定义的${OBJECT\u FILES}-o${shared\u LIBRARY}构建吗另外,通过添加-Wl,-soname,“.a只不过是一个.o文件的存档,原则上与.tar.gz或.zip甚至是一个目录没有区别。我错了吗?
ar
命令也做了
ranlib
用来做的事情:制作一些索引。那么.a库与PIC有什么关系呢?It(静态
libxxx.a
库)与PIC无关,它包含非PIC对象。如果进入.a的.o是用-fPIC编译的,那么我们应该可以吗?