V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
adow
V2EX  ›  问与答

请问Mac OS X (10.9.1)下创建和使用动态链接库的方法

  •  
  •   adow · 2013-12-26 11:53:05 +08:00 · 10563 次点击
    这是一个创建于 3779 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近我需要创建和使用静态库和动态库,所以就想学习gcc来编译一个c的代码:
    比如有
    a.c,a.h;
    b.c,b.h;
    c.c,c.h;

    首先编译到对象文件:
    gcc -fPIC -c a.c b.c c.c
    生成了
    a.o,b.o,c.o

    如果要打包成静态库 libtest.a:
    ar -r libtest.a a.o b.o c.o
    然后我在另一个目录下有一个main.c编译链接这个libtest.a是可以的。

    现在我要弄成动态库 libtest.dylib:
    gcc -fPIC -dynamiclib a.o b.o c.o -o libtest.dylib
    我发现编译成libtest.so也一样:
    gcc -fPIC -shared a.o b.o c.o -o libtest.so

    然后我复制到/usr/lib下,然后修改了所有者和用户组:
    chown root:wheel libtest.dylib

    到另一个目录下的main.c,我已经复制过来了头文件,然后我编译main.c时来链接这个动态库,应该是不用指定 -L的:
    gcc main.c -ltest -o main -fPIC
    这时我发现提示找不到lib:ld: library not found for -ltest。

    那我想就指定一下库的搜索路径吧:
    gcc main.c -L/usr/lib/. -ltest -o main -fPIC
    一样的错误。

    然后我就干脆指定这个文件吧:
    gcc main.c /usr/lib/libtest.dylib -o main -fPIC
    这个到可以了,然后运行./main也可以;

    我想要是放其他目录呢:
    gcc main.c -L/Users/reynoldqin/Desktop/. -ltest -o main -fPIC
    这样在编译的时候成功了,但是运行./main的时候又提示:
    dyld: Library not loaded: libtest.dylib
    Reason: image not found
    这时如果我把libtest.dylib又复制一份放到/usr/lib下,运行./main却有可以了。

    后来我发现原来还有一个动态库目录,然后我就把他放到
    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/lib
    我直接使用动态库编译,不指定-L:
    gcc main.c -ltest -o main -fPIC
    编译成功了,但是运行./main 一样提示找不到,我还是得在/usr/lib下放一份才可以运行;

    无论是libtest.dylib还是libtest.so,上面都是一样的。

    上面就是我测试了一圈的过程:
    * libtest.dylib放在/usr/lib貌似不是用来编译的,只是运行的时候需要;
    * /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/lib 这个目录是可以作为动态库目录来编译的,但是运行时怎么又需要在/usr/lib;

    所以我就搞不清楚了,既然叫动态库的话,我应该只要把库文件放在/usr/lib 就可以直接链接了吧。请问这是怎么回事呢?我还没有在linux下试过的。
    4 条回复    1970-01-01 08:00:00 +08:00
    hewigovens
        1
    hewigovens  
       2013-12-26 12:48:59 +08:00   ❤️ 1
    你otool -L看一下main和libtest.dylib的install-name, 默认的第三方库的路径是/usr/local/lib...
    adow
        2
    adow  
    OP
       2013-12-26 14:26:05 +08:00
    @hewigovens 我放那里后编译main的时候也找不到啊
    hewigovens
        3
    hewigovens  
       2013-12-26 14:50:07 +08:00   ❤️ 1
    现在常见做法都是使用相对路径, 比如QQ, @executable_path/../Frameworks/xp_macosx.framework/Versions/A/xp_macosx Mac的做法是把link的库都写入了binary里, 然后有个install_name_tool可以修改, 当然你用xcode工程创建dylib是可以配置的, 具体可以看Apple的文档: http://developer.apple.com/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html
    tomliu
        4
    tomliu  
       2013-12-29 21:29:25 +08:00   ❤️ 1
    前段时间项目用到了ffmpeg研究过,使用就是两步工作
    1.使用otool -L 查看路径
    2.install_name_tool -change 命令去修改那些路径是/usr/local/lib的,需要先把的dylib都copy到目录里面
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1078 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:54 · PVG 07:54 · LAX 16:54 · JFK 19:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.