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

Wil*_*sch 17 macos linker gcc ld dynamic-library

如果您试图了解动态链接,这个问题很可能会引起关注.

该问题的答案之一提供了创建和使用动态库的一个很好的例子.基于它,我有一些简单的文件:

main.c中:

extern void someFunction (int x);

int main (int argc, char** argv ) {
    someFunction(666);
}
Run Code Online (Sandbox Code Playgroud)

mylibrary.c:

#include <stdio.h>

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

生成文件:

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
Run Code Online (Sandbox Code Playgroud)

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

someFunction called with x=666
Run Code Online (Sandbox Code Playgroud)

现在,我想把事情搞混一些.我创建了一个目录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/*.*
Run Code Online (Sandbox Code Playgroud)

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

编辑:感谢您的回复.有很多选择很棒,但初学者只想要一个有效的选项.这是我在最后一行尝试的内容,但显然我不明白.makefile执行时没有错误,但在运行时它会显示"找不到库".

    gcc main.o -rpath,'$$ORIGIN/hidelib' -lmylibrary -o main
Run Code Online (Sandbox Code Playgroud)

lee*_*777 16

一个有效的选项是install_name在链接时设置标志.dylib.

gcc -dynamiclib -install_name '$(CURDIR)/hidelib/libmylibrary.dylib' -current_version 1.0 mylibrary.o -o libmylibrary.dylib
Run Code Online (Sandbox Code Playgroud)

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

gcc main.o -L '$(CURDIR)/hidelib' -lmylibrary -o main
Run Code Online (Sandbox Code Playgroud)


wby*_*ung 7

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

在链接之后尝试移动东西时,您需要一个dyld环境变量来搜索.man dyld并且您应该能够获得有关DYLD_LIBRARY_PATH其他环境变量的更多信息.

但是,通常,在链接到具有-install_name链接器标志的内容之前设置库的安装名称为类似@rpath/mylibrary.dylib值,然后在使用-rpath标志编译时在主可执行文件上设置运行路径搜索路径@executable_path/hidelib.

欲了解更多信息,请参阅install_name_tool-rpath-install_name论据ld.

基本上,您尝试做的事情有很多选择.