2010-04-28 81 views
66

我正在编译一个使用g++ld的C++程序。我想在链接过程中使用.so库。但是,在/usr/local/lib中存在同名库,并且ld正在使用我直接指定的库。我怎样才能解决这个问题?如何指定库路径的偏好?

对于下面的例子,我的库文件是/my/dir/libfoo.so.0。事情我已经试过了不起作用:

  • 我的G ++命令是g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
  • 添加/my/dir的开头或我$PATH en`变量
  • 加入/my/dir/libfoo.so.0端作为参数传递给G ++
+0

还有哪些'libfoo。*'文件存在,哪里有'.so'没有'.0','.a'等等? – 2010-04-28 05:20:38

回答

69

添加路径到你的新库是LD_LIBRARY_PATH(它在Mac上略有不同的名字......)

您的解决方案应该使用-L/my/dir -lfoo选项,在运行时使用LD_LIBRARY_PATH指向库的位置。

OR

通过GCC使用rpath的选项链接器 - 运行时库搜索路径,将使用 而不是查找在标准目录(GCC选项):

-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH) 

这是很好的一个临时解决方案在查看标准目录之前,链接器首先搜索LD_LIBRARY_PATH库。

如果你不想永久更新LD_LIBRARY_PATH你可以做到这一点对命令行飞:

LD_LIBRARY_PATH=/some/custom/dir ./fooo 

您可以检查哪些库链接器知道如何使用(例如):

/sbin/ldconfig -p | grep libpthread 
     libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0 

你可以检查你的应用程序正在使用的库:

ldd foo 
     linux-gate.so.1 => (0xffffe000) 
     libpthread.so.0 => /lib/libpthread.so.0 (0xb7f9e000) 
     libxml2.so.2 => /usr/lib/libxml2.so.2 (0xb7e6e000) 
     librt.so.1 => /lib/librt.so.1 (0xb7e65000) 
     libm.so.6 => /lib/libm.so.6 (0xb7d5b000) 
     libc.so.6 => /lib/libc.so.6 (0xb7c2e000) 
     /lib/ld-linux.so.2 (0xb7fc7000) 
     libdl.so.2 => /lib/libdl.so.2 (0xb7c2a000) 
     libz.so.1 => /lib/libz.so.1 (0xb7c18000) 
+10

在运行时搜索'LD_LIBRARY_PATH',在编译时想要设置'LIBRARY_PATH'。请参阅https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html – 2014-10-18 16:49:11

+1

如果您的库与系统库完全不同,也就是始终使用的库,请使用rpath解决方案。 LD_LIBRARY_PATH是用于测试的黑客攻击,不应要求使可执行文件正确工作。 – user2746401 2015-03-20 14:20:55

+0

其适用于Mac的DYLD_LIBRARY_PATH – cbinder 2015-11-27 06:33:33

16

指定绝对路径图书馆应该很好地工作:

g++ /my/dir/libfoo.so.0 ... 

你记得删除-lfoo一旦你添加的绝对路径?

+1

此解决方案对我来说也很合适 - 试图链接除发行版软件包之外的Qt5版本。谢谢。 – wump 2016-05-03 10:39:56

+0

如何使这个工作适用于@版本符号?最简单的例子:https://github.com/cirosantilli/cpp-cheat/blob/0b4b1bdeed693d16129b282ce0c8145499bf34f6/shared-library/symbol-version/Makefile#L13 – 2017-03-26 11:11:15

8

作为替代方案,您可以使用环境变量LIBRARY_PATHCPLUS_INCLUDE_PATH,分别指示在何处寻找库和在哪里找头(CPATH也将做的工作),不指定-L和-I选项。

编辑: CPATH包括标题与-ICPLUS_INCLUDE_PATH-isystem

+0

请问您可以添加使用示例吗? – 2016-06-08 09:39:34

+0

''在你正在编译的同一个控制台会话中导出LIBRARY_PATH =/path/to/lib' – 2016-06-08 11:55:12

0

如果在Windows中使用DLL来处理DLL,并想跳过linux/QT中的.so版本号,那么添加“CONFIG + = plugin”将会取出版本号。为了使用.so的绝对路径,正如Klatchko先生所说,将它交给链接器工作正常。

10

这是一个老问题,但似乎没有人提到过这一点。

你幸运的是,事情是连接在一起。

你需要改变

g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp 

这样:

g++ -g -Wall -o my_binary -L/my/dir bar.cpp -lfoo 

你的链接跟踪它需要解决的符号。如果它首先读取库, 它没有任何所需的符号,所以它会忽略它中的符号。在需要 链接到它们的东西之后指定库,以便链接器具有在其中找到的符号。

而且,-lfoo使得它根据需要专门搜索名为libfoo.alibfoo.so的文件。不是libfoo.so.0。所以要么是ln的名称,要么将库改名为appopriate。

引述GCC手册页:

-l library 
    ... 
    It makes a difference where in the command you 
    write this option; the linker searches and processes 
    libraries and object files in the order they are 
    specified. Thus, foo.o -lz bar.o searches library z 
    after file foo.o but before bar.o. If bar.o refers 
    to functions in z, those functions may not be loaded. 

直接将文件添加到g++的命令行应该有工作, 当然,除非你把它之前bar.cpp,造成连接器 忽视它缺乏任何必需的符号,因为还没有需要符号。