这可能有点不寻常,但我有一个用 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/