女主宣言
在测试和部署 C++ 动态库时,经常遇到的问题就是程序链接到了系统路径下的动态库,有时候 make 编译时链接到本地路径的动态库,但实际 make install 时则会丢失这个依赖。本文将要介绍的就是一种通用解决方法,使用 RPATH 来绑定链接路径。
PS:丰富的一线技术、多元化的表现形式,尽在“360云计算”,点关注哦!
1
动态库编译和使用简单示例
给出以下示例库:
// foo.h
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void foo();
#ifdef __cplusplus
}
#endif
// foo.cc
#include "foo.h"
#include <stdio.h>
void foo() { printf("foo\n"); }
生成动态库 libfoo.so:
g++ -o libfoo.so -fPIC -shared foo.cc
然后给出调用代码:
// main.cc
#include "foo.h"
int main(int argc, char* argv[]) {
foo();
return 0;
}
编译时链接到当前目录:
$ gcc main.c -L . -lfoo
$ ./a.out
foo
$ ldd a.out | grep libfoo
libfoo.so (0x00007fc2010f7000)
至此,一切正常。
2
依赖动态库的动态库
实际编写程序时,往往会依赖一些第三方库来避免重复造轮子。比如,这里我们要写一个库依赖于 libfoo.so。
目录层次:
.
├── include
│ └── bar.h
├── src
│ └── bar.cc
└── thirdparty
├── include
│ └── foo.h
└── lib
└── libfoo.so
然后编译生成 libbar.so:
g++ -o libbar.so -fPIC -shared src/bar.cc \
-I include/ -I thirdparty/include/ \
-L thirdparty/lib/ -lfoo
问题来了,编译出的 libbar.so 找不到 libfoo.so 的依赖:
$ ldd libbar.so | grep foo
libfoo.so => not found
当然,这样的话,你编译依赖 libbar.so 的程序时会直接失败,从