さまざまな共有ライブラリに依存する多くのオプション機能を持つ C でプログラムを構築しようとしています。
私たちのヘテロジニアス コンピューティング クラスターでは、これらのライブラリのすべてがすべてのシステムで利用できる (または最新の状態である) わけではありません。
例としては、新しい glibc のシンボル ( sched_getcpu@@GLIBC_2.6
、__sched_cpucount@@GLIBC_2.6
)、または利用できる場合と利用できない場合がある共有ライブラリ全体 ( libnuma
、libR
、libpbs
) があります。
とを使用libdl
してシンボルをロードできることはわかっていますが、増え続けるシンボル (現時点では約 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
ライブラリを強制的に使用時にのみロードし、それらを使用するブロックの前にこのようなチェックを行う方法はありますか?