ld无法找到现有库

180

我正在尝试在这个Debian Lenny系统上使用g++链接一个应用程序。ld报错说找不到指定的库。这里的具体例子是ImageMagick,但我也遇到了一些其他库的类似问题。

我使用以下命令调用链接器:

g++ -w (..lots of .o files/include directories/etc..) \
-L/usr/lib -lmagic

ld抱怨:

/usr/bin/ld: cannot find -lmagic

然而,libmagic存在:

$ locate libmagic.so
/usr/lib/libmagic.so.1
/usr/lib/libmagic.so.1.0.0
$ ls -all /usr/lib/libmagic.so.1*
lrwxrwxrwx 1 root root    17 2008-12-01 03:52 /usr/lib/libmagic.so.1 -> libmagic.so.1.0.0
-rwxrwxrwx 1 root root 84664 2008-09-09 00:05 /usr/lib/libmagic.so.1.0.0
$ ldd /usr/lib/libmagic.so.1.0.0 
    linux-gate.so.1 =>  (0xb7f85000)
    libz.so.1 => /usr/lib/libz.so.1 (0xb7f51000)
    libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7df6000)
    /lib/ld-linux.so.2 (0xb7f86000)
$ sudo ldconfig -v | grep "libmagic"
    libmagic.so.1 -> libmagic.so.1.0.0

我该如何进一步诊断这个问题,可能出了什么问题?我是在做一些非常愚蠢的事情吗?

9个回答

182
问题在于链接器正在寻找libmagic.so文件,但实际上您只有libmagic.so.1文件。

一种快速的解决方法是将libmagic.so.1文件创建符号链接,指向libmagic.so文件。


3
这个可以用,但我有点困惑为什么默认情况下会以完全无用的方式命名文件 - 你能提供任何解释为什么会这样吗? - maxpenguin
7
foo.so.1也是指向foo.so.1.0.0的符号链接。这样,您可以在系统中拥有几个版本的库,如果应用程序需要特定版本,则可以链接到该版本,而通常情况下,符号链接将选择最新的版本。我不知道为什么缺少了这个符号链接。 - Svante
52
libmagic.so.1 是动态链接器使用的 soname;libmagic.so 由链接器使用,并且通常与 -dev 包中的头文件一起。符号链接可能会缺失,因为未安装 -dev 包。 - CesarB
14
我遇到了同样的问题……不过我没有使用“hack”的方法,而是安装了“*-devel”版本,这解决了编译问题。 - Trevor Boyd Smith
4
如何将libmagic.so.1符号链接到libmagic.so?在哪里可以找到那些“devel”包? - Black
显示剩余3条评论

70

如grepsedawk所说,答案在于使用g++-l选项,并调用ld。如果您查看此命令的手册页,则可以选择执行以下操作:

  • g++ -l:libmagic.so.1 [...]
  • 或:如果您的libs路径中有名为libmagic.so的符号链接,则执行g++ -lmagic [...]

1
简而言之,在使用-l时链接到它时,请删除lib前缀。 -llibmagic应为-lmagic - phyatt

35

按照Debian的惯例,将共享库分成其运行时组件(libmagic1:/usr/lib/libmagic.so.1 → libmagic.so.1.0.0)和开发组件(libmagic-dev:/usr/lib/libmagic.so →…)。

由于库的soname是libmagic.so.1,因此该字符串嵌入到可执行文件中,因此在运行可执行文件时加载该文件。

但是,由于库在链接器中被指定为-lmagic,所以它会查找libmagic.so,这就是为什么需要它进行开发的原因。

有关Linux上所有这些工作方式的详细信息,请参见Diego E. Pettenò: Linkers and names


简而言之,您应该apt-get install libmagic-dev。 这不仅会给您libmagic.so,还会提供其他编译所需的文件,例如/usr/include/magic.h


10
在Ubuntu中,你可以安装libtool来自动解决库的依赖关系。
$ sudo apt-get install libtool

这对我解决了一个关于 ltdl 的问题,因为它是作为 libltdl.so.7 安装的,所以在编译时不能简单地使用 -lltdl 进行引用。


它没有解决错误“找不到-LGL”。您能否提供有关libtool的更多信息以及如何解决库问题? - Shahryar Saljoughi

8

如上所述,链接器正在寻找libmagic.so,但您只有libmagic.so.1

要解决此问题,只需执行更新缓存操作即可。

ldconfig -v 

为了验证,您可以运行以下命令:

$ ldconfig -p | grep libmagic

4

除非我弄错了,libmagic-lmagic不是与ImageMagick相同的库。您说您需要ImageMagick。

ImageMagick附带一个实用程序,可向编译器提供所有适当的选项。

例如:

g++ program.cpp `Magick++-config --cppflags --cxxflags --ldflags --libs` -o "prog"

1
从Ubuntu仓库安装libgl1-mesa-dev解决了我的问题。

5
你肯定不会像2008年的maxpenguin一样遭遇脚本错误吧。 - Sophit
它解决了我的问题。你能否提供更多关于它是什么以及如何解决这个问题的信息?(我指的是:libgl1-mesa-dev)。谢谢。 - Shahryar Saljoughi

1

我尝试了上面提到的所有解决方案,但都没有解决我的问题,最终我通过以下命令解决了它。

sudo apt-get install libgmp3-dev

这将会产生神奇的效果。

0

解决这个问题的另一种方法是安装-devel包。

如果编译器正在寻找libabc.so,而您只有libabc.so.1,则需要安装-devel包,例如libabc-devel,因为libabc.so.1是运行时库,而libabc.so是开发库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接