具体“无法打开共享对象文件”错误

时间:2016-02-12 15:32:55

标签: makefile export shared-libraries shared-objects

我是一名计算机科学专业的一年级学生,学习了Makefile等课程。对于我们的第一个任务,我们必须创建一个共享库并链接它。

我有以下设置:

  • 包含文件夹hw1app
  • 的文件夹lib
  • 内部lib是一个名为libmine.so的文件,我想链接的库。
  • app内,有两个文件:test.cppMakefile。前者使用libmine库。

Makefile如下(在文件本身,缩进等 正确):

all: test

test: test.cpp
      g++ -Wall -o test -L../lib -I../lib/include test.cpp -lmine

然而,当运行 test时,我得到臭名昭着的`libmine.so:无法打开共享对象文件'错误。

我认为这与导出LD_LIBRARY_PATH有关。我尝试过这样做(export LD_LIBRARY_PATH=$[very long relative path to the lib folder]),但我希望在Makefile中执行此操作。另外,我不希望路径是相对的,因为当我发送给他时,我的教师应该能够打开文件(所以我认为它应该是../lib/libmine.so)。

我查看了各种StackOverflow帖子,例如this one,但似乎没有人回答这个具体问题(要么是不同的设置,要么解决方案根本不起作用)。顺便说一句:将行export LD_LIBRARY_PATH=../lib放在test: test.cpp下面g++命令之前没有做任何事情。

非常感谢任何帮助:)

1 个答案:

答案 0 :(得分:1)

  

运行测试时,我得到臭名昭着的`libmine.so:无法打开共享对象文件'错误。

这种情况正在发生,因为-L../lib参数告诉 static 链接器在哪里找到库,但它没有告诉 dynamic 链接器(又称装载机),问题是后者无法找到这个库。

要解决此问题,您可以使用LD_LIBRARY_PATH,但这通常是不明智的。

您想要的是RPATHRUNPATH(假设您使用的是Linux或类似系统):

 g++ -Wall -o test -L../lib -I../lib/include test.cpp -Wl,-rpath=../lib -lmine
  

此外,我不希望路径是相对的,因为我的教师应该能够在我发送给他时打开文件

您的老师是否会在相同的系统上运行二进制文件,或者在另一个系统上运行二进制文件?如果是前者,你可以这样做:

g++ -Wall -o test -L../lib -I../lib/include test.cpp -Wl,-rpath=/full/path/to/hw1/lib -lmine

如果是后者,/full/path/to/hw1/lib可能会或可能不会在您老师的机器上提供,并且您需要考虑您将要发送给他的确切内容。

解决此问题的常用方法是将应用程序和库打包到tar文件中:

tar cvf to-send.tar app/test lib/libmine.so

然后,教师可以将tar文件的各个部分提取到任意目录中,然后尝试运行它。要使其工作,您需要与应用程序相关的RPATH,无论应用程序在何处结束。为此,您需要:

g++ -Wall -o test -L../lib -I../lib/include test.cpp -Wl,-rpath='$ORIGIN/../lib' -lmine