厌倦了在连接EXE时写非立即.so,如何得到缓解?

时间:2013-02-25 07:59:14

标签: linux gcc

我认为业内应该有关于这个问题的最佳实践,所以我在这里问。

这个问题是关于将共享库(.so)链接到可执行文件,在Linux上使用gcc。但让我先从Windows开始。

假设我正在开发A.EXE,B.DLL,C1.DLL。依赖是

A -> B -> C1

表示:A从B调用API,B通过从C1调用API来实现自身。 A不直接在C1中调用API。

你知道,当链接A.EXE(使用Visual C ++)时,我只需要将B.lib(import lib)列为A的链接组件(在makefile中); C1不必出现在A的makefile中。所以有一天我想用C2取代C1以更好地实现B,我不需要更换A的makefile,因为C1已被替换。

这很好,因为它遵循了理性的想法:makefile只引用它直接相关的东西。有了这种便利,人们倾向于在Windows上编写DLL而不是LIB - 我想是的。

现在我转向linux上的gcc。使用相同的依赖方案,在A的makefile中,我必须明确地将C1或C2列为链接组件,如下所示:

gcc -o A a1.o a2.o -lB -lC1 

如此令人沮丧,想象你有十个项目A1,A2,... A10调用B,你必须修改十个makefile才能从C1转换到C2。

如何获得救济?

2 个答案:

答案 0 :(得分:3)

关联某些共享库libfoo.so时,您可以将其与其他共享库libbar.so相关联:

  gcc -fPIC -g -Wall -c foo1.c
  gcc -fPIC -g -Wall -c foo2.c
  gcc -shared -o libfoo.so foo1.o foo2.o -lbar

然后当您使用-lfoo时,libbar.so会自动关联,而不会要求它。

因此,您不必在A&#39的makefile中明确地将C1或C2列为链接组件。

如果只有静态库lib*.a

,则必须这样做

所以你可以用

建立一个程序
  gcc -Wall -g prog.c -lfoo
单独

(未明确提及libbar.so。)

尝试在GTK共享库上运行ldd(在我的Debian系统上):

  ldd /usr/lib/x86_64-linux-gnu/libgtk-3.so.0

我建议您阅读Levine's linker & loader book以了解Windows .dll和Linux .so之间的区别;他们是不同的野兽。另请阅读Program Library HowTo

您可能希望(或不)使用GNU libtool

顺便说一下,您也可以使用pkg-config,这将提供依赖...

答案 1 :(得分:1)

确保libB取决于libCldd libB.so); libB应该使用gcc -o libB.so -shared -fPIC *.c -L/path/to/libC -lC -Wl,-rpath,/path/to/libC

之类的内容进行编译

请注意,libB.so需要使用-rpath进行编译才能找到libC.so,或使用LD_LIBRARY_PATH环境变量(ldd上面提到的命令不得显示libC.so => not found