我是一名计算机科学专业的一年级学生,学习了Makefile等课程。对于我们的第一个任务,我们必须创建一个共享库并链接它。
我有以下设置:
hw1
和app
。lib
lib
是一个名为libmine.so
的文件,我想链接的库。app
内,有两个文件:test.cpp
和Makefile
。前者使用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++
命令之前没有做任何事情。
非常感谢任何帮助:)
答案 0 :(得分:1)
运行测试时,我得到臭名昭着的`libmine.so:无法打开共享对象文件'错误。
这种情况正在发生,因为-L../lib
参数告诉 static 链接器在哪里找到库,但它没有告诉 dynamic 链接器(又称装载机),问题是后者无法找到这个库。
要解决此问题,您可以使用LD_LIBRARY_PATH
,但这通常是不明智的。
您想要的是RPATH
或RUNPATH
(假设您使用的是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