C 是否可以使用静态链接库构建共享库?

C 是否可以使用静态链接库构建共享库?,c,linux,gcc,compiler-construction,C,Linux,Gcc,Compiler Construction,我可以用gcc和静态链接构建一个可执行文件: gcc-static xxx.c-o xxx 因此,我可以在没有任何外部依赖库的情况下运行xxx 但如果我想构建共享库而不需要依赖外部库呢?我的意思是我想要 共享库在中静态链接其外部引用。这将起作用: # Generate position independent code (PIC) gcc -fPIC -c -o xxx.o xxx.c # Build a shared object and link with static libraries

我可以用gcc和静态链接构建一个可执行文件:

gcc-static xxx.c-o xxx

因此,我可以在没有任何外部依赖库的情况下运行xxx

但如果我想构建共享库而不需要依赖外部库呢?我的意思是我想要 共享库在中静态链接其外部引用。

这将起作用:

# Generate position independent code (PIC)
gcc -fPIC -c -o xxx.o xxx.c

# Build a shared object and link with static libraries
ld -shared -static -o xxx.so xxx.o

# Same thing but with static libc
ld -shared -static -o xxx.so xxx.o -lc
需要说明的是,-static标志(如果提供给gcc)将传递给链接器(ld),并告诉它使用库的静态版本(.A)(使用-l标志指定),而不是动态版本(.so)

另一件事:在我的系统(Debian)上,最后一个例子给出了一个libc.a。。。使用-fPIC错误重新编译。很确定这意味着我系统上的libc.a不是用-fPIC编译的。然而,apt缓存搜索libc pic确实给出了一些结果


另请参见:,

如果您对共享库的可移植性有任何计划,请使用。它将为您处理编译器标志的大部分细节,并使您的生活更加轻松。如果您不使用
libtool
,但后来决定将程序移植到OS X或Windows,您最终还是要对其进行改造。

您可以使用Rpath进行一些巧妙的黑客攻击,以便可执行文件或.so将查找其依赖项。因此,文件首先与自身位于同一目录中:

  • 制作一个简短的脚本echo rpath,包括

    echo'-Wl,--rpath=$ORIGIN'

  • 将其作为gcc-o file-lwhatever
    `echo rpath`
    对象添加到构建命令行中


(回音机制防止Make或shell吃掉$sign,并确保它被传递到ld中。)

@Inshalla,我认为问题是我们可能会将两个链接到一个。到目前为止,我尝试了,但失败了。请查看我答案中的
“So:combing.So libs”
链接。似乎没有简单的方法来组合动态库,除非它们已使用
--relocate
标志链接(请参见ld(1)手册页)。@Inshallah-如果您想将非PIC代码链接到共享对象中,您可以使用gcc“-mimpure text”标志。共享对象中的非PIC代码可以很好地工作,但确实有一些折衷之处(代码页不能在进程之间共享,需要交换空间,重新定位会降低共享对象的加载速度,尽管在运行时可能会稍快一些,因为PIC代码要慢约5%。@R Samuel Klatchko,感谢您的提示。然而,手册页上说,
-mimpure text
选项仅在SunOS和Solaris上可用。我不知道这是否有技术上的原因,或者它是否只是没有在其他体系结构中实现。静态链接到
libc_pic
会导致在symbol pthread_cond_timedwait@GLIBC_2.4中找不到的
版本节点错误,并明确声明对除构建
libc以外的任何内容使用
libc_pic
,因此不支持
。@Chris Lutz,“生成独立库”可用于封闭源代码或更方便客户使用。@arsane:libtool(1)将使您能够以更独立于平台的方式生成库。它将执行适当的命令,为运行它的平台构建(静态或共享)库;即使你不需要它,拥有它也是件好事。@arsane-一般来说,GNU工具不需要你在GNU许可下授权你的代码才能使用它们。您可以合法地使用GCC编译封闭源代码,并且仍然可以在封闭源代码中获得GCC可移植性的好处,因此我认为您可以使用libtool编译共享库,而无需对库进行GPL。我不是律师或专家,所以请参阅相关许可证,但一般来说GNU不会这样做。