objective-c - 迪尔德 : Library not loaded when trying to run Fortran executable from Objective-C using NSTask

标签 objective-c xcode macos cocoa

这可能有点不寻常,但我有一个用 Fortran 编写的程序,它接受一些命令行参数并执行模拟。现在我想添加一个用 Xcode 编写的 GUI 来运行可执行文件并给它一些命令行参数。我使用命令行编译 Fortran 程序,然后尝试在 Xcode 中运行它,如下所示:

   NSString * path = @"path/to/executable";
   NSArray * args = [NSArray arrayWithObjects:@"arg1",@"arg2", nil];

   [NSTask launchedTaskWithLaunchPath:path arguments:args] waitUntilExit];

但是,当我运行它时,我得到:libmkl_intel_lp64.dylib dyld:未加载库。原因:找不到图像。 这些库在我的 .profile 中设置,并且可以从命令行正常工作/链接,但从 Xcode 中它不起作用。我什至尝试通过复制 .a 并用它编译我的程序来静态链接它,但无济于事。

根据要求,otool -L 的输出:

   lnew-host:$ otool -L /Users/username/Desktop/Simulation/Sim

/Users/username/Desktop/Simulation/Sim:
    libmkl_intel_lp64.dylib (compatibility version 0.0.0, current version 0.0.0)
    libmkl_intel_thread.dylib (compatibility version 0.0.0, current version 0.0.0)
    libmkl_core.dylib (compatibility version 0.0.0, current version 0.0.0)
    libiomp5.dylib (compatibility version 5.0.0, current version 5.0.0)
    /usr/local/lib/libfgsl.0.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)

最佳答案

问题与用于解析 .dylib 路径的机制有关。

从命令行运行它时,您通过设置环境变量 $DYLD_LIBRARY_PATH 解析路径。

当通过 NSTask 运行时,您根本没有做任何事情(Xcode 不会继承您在 .profile 中设置的环境;事实上,任何不使用 /usr/bin/open 调用的应用程序如何获取其环境都非常复杂。

此问题的最佳长期解决方案是使用 install_name_tool 修复每个 Intel 库在可执行文件中的位置:

cd /Users/username/Desktop/Simulation
for lib in libmkl_intel_lp64.dylib libmkl_intel_thread.dylib libmkl_core.dylib 
do
    install_name_tool -change $lib /opt/intel/mkl/lib/$lib Sim
done

此更改是永久性的,意味着不再需要使用 $DYLD_LIBRARY_PATH,但是如果您构建了 Sim,那么这一切都可以在链接它时完成。

现在,如果您打算打包您的 GUI 以便在 App Store(或什至 Ad Hoc 分发)上销售,那么您将需要将这些库与应用程序包打包在一起,您还有更多工作要做才能做到这一点正确的。但那是另一个故事不是吗。

底线:在任何版本的 *NIX 下使用 $LD_LIBRARY_PATH$DYLD_LIBRARY_PATH 总是一个坏主意(对于 Linux 使用 /etc/ld.so .conf.d 对于 OSX 使用 install_name_tool)。

关于objective-c - 迪尔德 : Library not loaded when trying to run Fortran executable from Objective-C using NSTask,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23777191/

相关文章:

objective-c - NSUserNotification - 单击时如何打开应用程序

iphone - 用户界面自动化 : Failed to authorize rights with status: -60007

macos - 如何使用 SwiftUI 向 macOS 应用程序添加工具栏?

objective-c - dispatch_semaphore_t 重用-我在这里缺少什么?

iphone - 如何在检测到用户单击 UIAlertView 上的确定按钮后退出程序

ios - 我如何获得录制音频文件的最大限制?

ios - 单击 AdBannerView 时应用程序崩溃

iphone - 使用 SQLite3 API 时 Xcode 内存泄漏

swift - UIDatePicker 只显示周日的日期吗?

ios - Xcode 8 无法存档 "Command/usr/bin/codesign failed with exit code 1"