如何在Mac OS X(C ++)使用dylib [英] How to use dylib in Mac OS X (C++)

查看:354
本文介绍了如何在Mac OS X(C ++)使用dylib的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做调用一些dylib成功,但是,dylib文件和可执行文件在不同的目录中的应用程序(可执行文件)。我添加了目录包含dylib文件到$ PATH环境变量,但是,它仍然不会加载。我所有的dylib文件复制到可执行文件,程序终于运行。这证实了dylib文件没有问题。但是,我怎么能告诉OS找呢?
在Windows中,我只需要添加的目录路径中包含的dll文件到$ PATH。我需要做什么的Mac OS X呢?
非常感谢!


解决方案

读取贾斯汀提供的链接后,我能够成功使用 @executable_path 标记改变我dylib install_name的以指向我的可执行文件位于同一目录。


  

@executable_path 绝对路径是烦人。有时你要嵌入框架到应用程序,而不必安装
  该框架成/库或类似的位置。


  
  

Mac的解决方案是@executable_path。这是一个神奇的令牌
  即,当放置在一个库的安装名称的开始,获取
  扩大到可执行文件的路径加载它,减去
  最后一个组件。例如,让我们说,Bar.app对链接
  Foo.framework。如果安装在/应用Bar.app,
  @executable_path将扩大到/Applications/Bar.app/Contents/MacOS。
  如果你打算嵌入内容/框架的框架,那么你
  可以只设置Foo.framework的安装名称
  @executable_path /../框架/ Foo.framework /版本/ A /美孚。该
  动态连接器将展开以
  /Applications/Bar.app/Contents/MacOS/../Frameworks/Foo.framework/Versions/A/Foo
  并且会发现那里的框架。


  
  

    

http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html


  

我会用一个例子来证明。

让我们说我有以下可执行文件的的/ opt / local / bin目录/转换的及其dylibs是的的/ opt / local / lib目录的。
 我想将它复制到另一个目录,并将它从同一个目录,我复制的可执行文件加载其dylibs。

 > MKDIR〜/ tmp目录/箱
> CP /选择/ local / bin目录/转换〜/ tmp目录/箱

获取可执行dylibs名单

 > otool -L〜的/ tmp /斌/转换
〜/ tmp目录/斌/转换:
    /opt/local/lib/libtiff.3.dylib(兼容版本13.0.0,当前版本13.5.0)
    /usr/lib/libSystem.B.dylib(兼容版本1.0.0,当前版本159.1.0)
    /opt/local/lib/libjpeg.8.dylib(兼容版本12.0.0,当前版本12.0.0)
    /opt/local/lib/libfontconfig.1.dylib(兼容版本6.0.0,目前版本6.4.0)
    /opt/local/lib/libiconv.2.dylib(兼容版本8.0.0,目前版本8.1.0)
    /opt/local/lib/libfreetype.6.dylib(兼容版本15.0.0,当前版本15.0.0)
    /opt/local/lib/libexpat.1.dylib(兼容版本7.0.0,目前版本7.2.0)
    /opt/local/lib/libbz2.1.0.dylib(兼容1.0.0版本,目前版本1.0.6)
    /opt/local/lib/libz.1.dylib(兼容1.0.0版本,目前版本1.2.6)
    ...

我只关心在的/ opt / local / lib目录的目录中dylibs,所以我们拉出只的 /选择的dylibs。我想保持所有其他dylib引用完好特别是对的 / usr / lib目录/ libSystem中的东西。

 > DYLIBS =`otool -L〜的/ tmp /斌/转换| grep的/选择| awk的-F'''{打印$ 1}'`

复制所有dylibs,凡可执行文件已被复制到相同的目录可执行文件的引用。

 >在$ DYLIBS dylib;做CP $ dylib〜的/ tmp /斌/;完成的;

使用 install_name_tool 来改变这一切,我们在以上步骤拉出dylibs的安装名称,由$ P $替换它们ppending的 @executable_path 来的dylib名称。这将使动态连接器查找在同一目录所在的可执行文件位于dylib。

 >在$ DYLIBS dylib;做install_name_tool -change $ @ dylib executable_path /`基名$ dylib`〜的/ tmp /斌/转换;完成的;

确认安装名称已被更改,并且 libSystem中的仍然指向的 / usr / lib目录/ libSystem中

 > otool -L〜的/ tmp /斌/转换
〜/ tmp目录/斌/转换:
    @ executable_path / libtiff.3.dylib(兼容版本13.0.0,当前版本13.5.0)
    /usr/lib/libSystem.B.dylib(兼容版本1.0.0,当前版本159.1.0)
    @ executable_path / libjpeg.8.dylib(兼容版本12.0.0,当前版本12.0.0)
    @ executable_path / libfontconfig.1.dylib(兼容版本6.0.0,目前版本6.4.0)
    @ executable_path / libiconv.2.dylib(兼容版本8.0.0,目前版本8.1.0)
    @ executable_path / libfreetype.6.dylib(兼容版本15.0.0,当前版本15.0.0)
    @ executable_path / libexpat.1.dylib(兼容版本7.0.0,目前版本7.2.0)
    @ executable_path / libbz2.1.0.dylib(兼容1.0.0版本,目前版本1.0.6)
    @ executable_path / libz.1.dylib(兼容1.0.0版本,目前版本1.2.6)
    ...

I made an application (an executable) calling some dylib successfully, However, the dylib files and the executable are in different directory. I added the directory contains dylib files to the $PATH environment variable, however, it still doesn't load. I copy all the dylib files to the executable, the program finally runs. This confirms the dylib files have no problem. However, How can I tell the OS to find it? In windows, I just need to add the directory path contains dll files to $PATH. What do I need to do for Mac OS X? Thanks a lot!

解决方案

After reading the link that Justin provided, I was successfully able to use the @executable_path token to change my dylib install_name to point to the same dir where my executable is located.

@executable_path Absolute paths are annoying. Sometimes you want to embed a framework into an application instead of having to install the framework into /Library or a similar location.

The Mac's solution to this is @executable_path. This is a magic token that, when placed at the beginning of a library's install name, gets expanded to the path of the executable that's loading it, minus the last component. For example, let's say that Bar.app links against Foo.framework. If Bar.app is installed in /Applications, @executable_path will expand to /Applications/Bar.app/Contents/MacOS. If you intend to embed the framework in Contents/Frameworks, then you can just set Foo.framework's install name to @executable_path/../Frameworks/Foo.framework/Versions/A/Foo. The dynamic linker will expand that to /Applications/Bar.app/Contents/MacOS/../Frameworks/Foo.framework/Versions/A/Foo and will find the framework there.

http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html

I will demonstrate with an example.

Let's say I have the following executable /opt/local/bin/convert and its dylibs are in /opt/local/lib. I want to copy it to another dir and have it load its dylibs from the same directory as where I copied the executable.

> mkdir ~/tmp/bin
> cp /opt/local/bin/convert ~/tmp/bin

Get a list of the executables dylibs

> otool -L ~/tmp/bin/convert
~/tmp/bin/convert:
    /opt/local/lib/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
    /opt/local/lib/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
    /opt/local/lib/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0)
    /opt/local/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
    /opt/local/lib/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0)
    /opt/local/lib/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
    /opt/local/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
    /opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6)
    ...

I only care about the dylibs in the /opt/local/lib dir, so we pull out only dylibs in /opt. I want to keep all other dylib references intact especially to /usr/lib/libSystem stuff.

> DYLIBS=`otool -L ~/tmp/bin/convert | grep "/opt" | awk -F' ' '{ print $1 }'`

Copy all the dylibs that the executable references to the same dir where the executable has been copied to.

> for dylib in $DYLIBS; do cp $dylib ~/tmp/bin/; done;

Use the install_name_tool to change the install name of all the dylibs we pulled out in the step above, and replace them by prepending the @executable_path to the dylib name. This will make the dynamic linker look for the dylib in the same directory as where the executable is located.

> for dylib in $DYLIBS; do install_name_tool -change $dylib @executable_path/`basename $dylib` ~/tmp/bin/convert; done;

Confirm that the install names have been changed and that libSystem is still pointing to /usr/lib/libSystem.

> otool -L ~/tmp/bin/convert
~/tmp/bin/convert:
    @executable_path/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
    @executable_path/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
    @executable_path/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0)
    @executable_path/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
    @executable_path/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0)
    @executable_path/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
    @executable_path/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
    @executable_path/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6)
    ...

这篇关于如何在Mac OS X(C ++)使用dylib的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆