我正在尝试用 C 构建一个程序,该程序具有许多依赖于各种共享库的可选功能。
在我们的异构计算集群中,并非所有这些库在所有系统上都可用(或最新)。
sched_getcpu@@GLIBC_2.6
示例是来自较新 glibc ( , ) 或整个共享库的符号,__sched_cpucount@@GLIBC_2.6
它们可能可用也可能不可用 ( libnuma
, libR
, libpbs
)。
我知道我可以用andlibdl
来加载符号,但是对于越来越多的符号(目前大约 30 个)这样做充其量是乏味的。dlopen
dlsym
据我了解,Linux 中的共享库默认是延迟加载的,因此在实际使用之前不需要符号。
但是,如果我尝试提前检查,那么它在执行开始时会失败:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
#include <sched.h>
int main() {
void *lib_handle;
int (*fn)(void);
int x;
char *error;
lib_handle = dlopen("libc.so.6", RTLD_LAZY);
if (!lib_handle)
{
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
fn = dlsym(lib_handle, "sched_getcpu");
if ((error = dlerror()) != NULL)
{
fprintf(stderr, "%s\n", error);
exit(1);
}
printf("%d\n", sched_getcpu());
return 0;
}
在具有所有库的编译系统上:
$ icc test.c
$ ./a.out
10
在另一个具有较新版本 GLIBC 的系统上:
$ ./a.out
./a.out: /lib64/libc.so.6: version `GLIBC_2.6' not found (required by ./a.out)
如果我注释掉实际调用的行,sched_getcpu
那么我会在较小的系统上得到:
$ ./a.out
/lib64/libc.so.6: undefined symbol: sched_getcpu
那么,有没有办法强制库仅在使用时加载并在使用它们的块之前进行此类检查?