我不得不在Ubuntu系统上做一些小的编程(在这个系统上,我是一个非常低级的初学者),我真的只是熟悉makefile。
我注意到告诉链接器哪些库包含的参数总是-l {库名},其中相应的库将在/ usr / lib文件夹中被称为“lib {库名} .a”。
我想知道:这是一个惯例吗? 我本以为我需要input-llibNAME才能find一个名为libNAME.a的库,但似乎假设了一个lib前缀。
这总是如此吗? 我可以命名一个库,而不使用lib前缀?
你可以任意指定一个名字,但是ld
的-l
假设一个lib
前缀同时适用于静态库和共享库,并且有很长的路要走。 你需要明确地命名它来使用没有lib
前缀的。
即使在现代系统上,这也是有用的:名称libfoo.so
可以被识别为链接时间库,而foo.so
表示一个实现运行时插件的共享对象。 或子系统特定的前缀代替lib
来识别特定子系统的插件; 请参阅例如pam_*.so
nss_*.so
和nss_*.so
。
name.a
是一个静态库(因为它是一个对象的存档)。
name.so
是一个动态库(因为它是一个共享对象,有时也被称为动态共享对象的DSO)。
-lfoo
链接器开关传统上采用形式为libfoo.{so,a}
,并在库路径上进行搜索。 您也可以直接将库名传递给链接器(不使用-l
开关),但是在这种情况下,必须明确地将路径传递给链接器。
正如@geekosaur
指出的那样,如果你在运行时打开一个共享对象, dlopen()
将获得完整的文件名。
简短的回答,是的,这是公约。
g ++的-l选项将在您的lib和本地路径中检查lib {somename} .so。
但是在UNIX中,您也可以使用符号链接,因此您可以拥有不同版本的库,而无需修改make脚本。
编辑添加:
正如有人在评论中指出的, .a
是一个静态库的扩展,而.so
是一个共享库。
其实没有 我的意思是, 差不多 ! 您正在将静态库与共享库混合。 静态库是.a
文件,共享库以.so
结尾。
总而言之,你在谈论共享库,好吗? 将应用程序与共享库链接时,需要使用-lNAME
的标准约定,其中NAME属于libNAME.so