最近跨平台编译一个第三方库,想编译成能独立运行的绿色包(除了基础的C库),遇到一些常见问题,做了以下实验:
项目目录结构如下
├── bin
├── lib
│ ├── hello.c
│ └── world.c
└── main.c
world.c
#include<stdio.h>
void world(void)
{
printf("world.\n");
}
hello.c
#include <stdio.h>
void world(void);
void hello(void)
{
printf("hello\n");
world();
}
main.c
void hello(void);
int main(void)
{
hello();
}
编译world, hello dylib
gcc -c hello.c world.c
gcc world.o -dynamiclib -o libworld.dylib -install_name @rpath/../lib/libworld.dylib
gcc hello.o -dynamiclib -o libhello.dylib -L. -lworld -install_name @rpath/../lib/libhello.dylib
编译main
gcc main.c -o ./bin/test -lhello -lworld -L./lib -Wl,-rpath ./
查看test依赖信息
% otool -L test
test:
@rpath/../lib/libhello.dylib (compatibility version 0.0.0, current version 0.0.0)
@rpath/../lib/libworld.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.0.0)
查看 dylib依赖信息
% otool -L ./lib/lib*
./lib/libhello.dylib:
@rpath/../lib/libhello.dylib (compatibility version 0.0.0, current version 0.0.0)
@rpath/../lib/libworld.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.0.0)
./lib/libworld.dylib:
@rpath/../lib/libworld.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.0.0)
## 总结:
一直想让程序的动态库,变成相对路径(默认安装在系统目录/usr/lib/,/usr/local/bin, ...),macos一定要注意以下几点:
### 1. -install_name 在编译动态库的时候,一定不能忘记,参数主要是设置动态库 的@rpath, 是个占位符,具体可以常看下面引用链接
### 2. -L./lib 编译时动态库具体的依赖目录,负责编译链接时出错,找不到对应的动态库
### 3. -Wl,-rpath ./ 是给链接器传递rpath 相对路径(执行程序与库文件的相对路径,需要与-install_name 的@rpath 的路径进行字符串合并),比如本案例中相对于执行程序的位置是:./../lib/*dylib
参考链接:
https://blog.csdn.net/weixin_30522183/article/details/95064012