无法通过单击来运行程序,而我可以从终端

Posted

技术标签:

【中文标题】无法通过单击来运行程序,而我可以从终端【英文标题】:Cannot run a program by clicking on it while I can from Terminal 【发布时间】:2017-09-26 12:08:39 【问题描述】:

我正在尝试学习如何在 C++ 程序中构建和使用动态库。一切都很好,当我从终端启动它时我的程序运行良好(我在 mac OS X El Capitan 上)。令人惊讶的是,当我尝试通过单击可执行文件来启动它时,情况并非如此。我收到dyld: Library not loaded: liblibrary.soReason: image not found 错误。

我所有的文件都在同一个目录中。我用命令构建它们:

g++ -c -fPIC A.cpp
g++ -c -fPIC B.cpp
g++ -shared -fPIC A.o B.o -o library.so
g++ main.cpp library.so -o Program

提前感谢您的帮助。

我尝试了以下解决方案:

LD_LIBRARY_PATHDYLD_LIBRARY_PATH 中添加一个路径 更改库扩展名:library.solibrary.dylib 添加 rpath g++ main.cpp library.so -Wl,-rpath,. -o Programg++ main.cpp library.so -Wl,-rpath,$HOME/my_dir -o Program

【问题讨论】:

当你从命令行运行时,你和library.so文件在同一个目录吗?这就是系统可以找到该库的原因,因为它在您的当前目录 中。如果它不在 当前目录 中,那么系统需要找到库所在的位置,这可以通过 -rpath linker 选项完成。 顺便说一下,您的主应用程序不必使用-fPIC 选项构建,只需使用库即可。 是的,我在当前目录中,但我之前尝试g++ -Wl,-rpath,. main.cpp library.so -o Program 链接到我的当前目录,但没有任何改变。 rpath 不应该是相对目录,而是一些绝对路径。请编辑您的问题以解释已尝试过的内容 在使用一个简单的程序执行您的命令后,otool 报告它指的是“library.so”(即在. 中)。使用getcwd(),我可以看到OSX在~中启动双击程序,而不是可执行文件的目录。您需要使您的 rpath 引用相对于 @executable_path 【参考方案1】:

您可能需要在编译时提供明确的rpath(作为绝对路径,而不是相对路径)(例如使用g++ -Wall -Wl,-rpath,$HOME/yourdir main.cpp library.so -o Program),或设置一些DYLD_LIBRARY_PATH,请参阅this。您可能需要.dylib 后缀,而不是.so

(我没有MacOSX了,所以我忘记了细节)

【讨论】:

我尝试了所有这些解决方案,但没有一个对我有用。 那么请编辑您的问题以解释具体尝试了什么【参考方案2】:

最后,我找到了解决方案。实际上,macOS 的动态库创建是不同的。我从一开始就尝试的方法只适用于 Linux。

所以 Mac 的解决方案是:

g++ -dynamiclib -install_name "absolute_path/library.dylib" A.o B.o -o library.dylib

地点:

-dynamiclib-shared 的 Mac 等效项。 -install_name "absolute_path/library.dylib" 为使用library.dylib 所必需的链接器创建别名library.dylib

之后,传统的命令:

g++ main.cpp library.dylib -o Program

如果main.cpplibrary.dylib 在同一目录中,则创建可执行文件。

只要library.dylib 留在同一个地方,该程序就可以在系统中的任何地方使用。

按照@Ssswift的注释,可以通过命令实现相对路径链接:

g++ -dynamiclib -install_name "@executable_path/library.dylib" A.o B.o -o library.dylib

然后库可以跟随可执行文件。

感谢您的帮助。

【讨论】:

以上是关于无法通过单击来运行程序,而我可以从终端的主要内容,如果未能解决你的问题,请参考以下文章

无法运行 Spring Boot 应用程序?

通过单击按钮终止正在运行的子进程

Java - 从终端运行 jar 可以工作,但双击会中断功能

Streamlit 浏览器应用程序无法从 Sagemaker 终端打开

我可以通过单击我的反应应用程序中的按钮来运行 React UI 自动化测试吗?

Xcode - 终端程序的 C++ 代码将无法运行