我认为业内应该有关于这个问题的最佳实践,所以我在这里问。
这个问题是关于将共享库(.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。
如何获得救济?
答案 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
取决于libC
(ldd 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
)