MacOS -- 如何使用 gcc/ld 将动态库与相对路径链接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10021428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 09:02:05  来源:igfitidea点击:

MacOS -- how to link a dynamic library with a relative path using gcc/ld

macosgcclinkerlddynamic-library

提问by William Jockusch

If you are trying to understand dynamic linking, this questionis likely to be of interest.

如果您正在尝试了解动态链接,这个问题可能会引起您的兴趣。

One of the answers to that question provides a wonderful example of creating and using a dynamic library. Based on it, I some simple files:

该问题的一个答案提供了一个创建和使用动态库的绝妙示例。基于它,我有一些简单的文件:

main.c:

主文件:

extern void someFunction (int x);

int main (int argc, char** argv ) {
    someFunction(666);
}

mylibrary.c:

mylibrary.c:

#include <stdio.h>

void someFunction (int x) {
    printf ("\nsomeFunction called with x=%d\n", x);
}

makefile:

生成文件:

main: mylibrary.c main.c
    gcc -c mylibrary.c
    gcc -dynamiclib -current_version 1.0 mylibrary.o -o libmylibrary.dylib
    gcc -c main.c
    gcc -v main.o ./libmylibrary.dylib -o main

clean:
    rm *.o
    rm main
    rm *.dylib

So far, everything works great. If I make and then enter ./main at the command prompt, I see the expected output:

到目前为止,一切都很好。如果我 make 然后在命令提示符下输入 ./main ,我会看到预期的输出:

someFunction called with x=666

Now, I want to mix things up a little. I've created a directory hidelib, which is a subdirectory of my main directory. And I'm adding one line to my makefile:

现在,我想把事情搞混一点。我创建了一个目录 hidelib,它是我的主目录的子目录。我在我的 makefile 中添加了一行:

main: mylibrary.c main.c
    gcc -c mylibrary.c
    gcc -dynamiclib -current_version 1.0 mylibrary.o -o libmylibrary.dylib
    gcc -c main.c
    mv libmylibrary.dylib hidelib     # this is the new line

clean:
    rm *.o
    rm main
    rm hidelib/*.*

Now, I want to add another line to the makefile so it will find libmylibrary.dylib in the hidelib subdirectory. I want to be able to run ./main in the same way. How can I do that?

现在,我想在 makefile 中添加另一行,以便在 hidelib 子目录中找到 libmylibrary.dylib。我希望能够以同样的方式运行 ./main。我怎样才能做到这一点?

EDIT: Thanks for the response. Having lots of options is wonderful, but a beginner just wants one concrete option that works. Here is what I am trying for the last line, but clearly I don't understand something. The makefile executes without errors, but at runtime it says "library not found."

编辑:感谢您的回应。有很多选择固然很棒,但初学者只需要一个可行的具体选择。这是我在最后一行尝试的内容,但显然我不明白一些事情。makefile 执行时没有错误,但在运行时显示“未找到库”。

    gcc main.o -rpath,'$$ORIGIN/hidelib' -lmylibrary -o main

采纳答案by leedm777

One concrete option that works would be to set the install_nameflag when linking the .dylib.

一个可行的具体选项是install_name在链接.dylib.

gcc -dynamiclib -install_name '$(CURDIR)/hidelib/libmylibrary.dylib' -current_version 1.0 mylibrary.o -o libmylibrary.dylib

Then you can just link to the library normally:

然后你可以正常链接到库:

gcc main.o -L '$(CURDIR)/hidelib' -lmylibrary -o main

回答by wbyoung

You probably need the -Lcompiler/linker flag which adds to the search path for libraries.

您可能需要将-L编译器/链接器标志添加到库的搜索路径中。

Are trying to move things after linking, you'll need a dyldenvironment variable for where to search. man dyldand you should be able to get more information on DYLD_LIBRARY_PATHand other environment variables.

尝试在链接后移动事物,您需要一个dyld环境变量来搜索位置。man dyld并且您应该能够获得有关DYLD_LIBRARY_PATH和其他环境变量的更多信息。

Typically, though, you set the install name of the library before linking to something with the -install_namelinker flag to something like @rpath/mylibrary.dylibas the value, then set the run path search paths on the main executable while compiling with the -rpathflag to @executable_path/hidelib.

但是,通常情况下,您在使用-install_name链接器标志链接到某些东西之前设置库的安装名称@rpath/mylibrary.dylib,然后将主可执行文件上的运行路径搜索路径设置-rpath@executable_path/hidelib.

For more information see install_name_tooland the -rpath& -install_namearguments of ld.

有关更多信息,请参阅install_name_tool和 的-rpath&-install_name参数ld

Basically, there are a lot of options for what you're trying to do.

基本上,对于您要执行的操作有很多选择。