无法静态使用已安装的库

Cannot statically use an installed library

我正在尝试静态 link 并使用我在系统中安装的库,但即使在 compile/link 时我也没有收到错误。在运行时我得到它们。

获取图书馆

我下载并安装了 libpfm4。我运行makesudo make install:

得到这个:

installing in /usr/local
make[1]: Entering directory '/home/username/libpfm4/lib'
building: libpfm.a libpfm.so.4.11.1
mkdir -p /usr/local/lib
install -m 644 libpfm.a /usr/local/lib
install libpfm.so.4.11.1 /usr/local/lib
cd /usr/local/lib; ln -sf libpfm.so.4.11.1 libpfm.so.4
cd /usr/local/lib; ln -sf libpfm.so.4.11.1 libpfm.so
ldconfig
make[1]: Leaving directory '/home/username/libpfm4/lib'
make[1]: Entering directory '/home/username/libpfm4/tests'
make[1]: Nothing to be done for 'install'.
make[1]: Leaving directory '/home/username/libpfm4/tests'
make[1]: Entering directory '/home/username/libpfm4/examples'
make[1]: Nothing to be done for 'install'.
make[1]: Leaving directory '/home/username/libpfm4/examples'
make[1]: Entering directory '/home/username/libpfm4/perf_examples'
make[1]: Nothing to be done for 'install'.
make[1]: Leaving directory '/home/username/libpfm4/perf_examples'
make[1]: Entering directory '/home/username/libpfm4/include'
mkdir -p /usr/local/include/perfmon
install -m 644 perfmon/pfmlib.h perfmon/perf_event.h perfmon/pfmlib_perf_event.h /usr/local/include/perfmon
make[1]: Leaving directory '/home/username/libpfm4/include'
make[1]: Entering directory '/home/username/libpfm4/docs'
mkdir -p /usr/local/share/man/man3
( cd man3; install -m 644 libpfm.3 pfm_find_event.3 pfm_get_event_attr_info.3 pfm_get_event_info.3 pfm_get_event_encoding.3 pfm_get_event_next.3 pfm_get_pmu_info.3 pfm_get_os_event_encoding.3 pfm_get_version.3 pfm_initialize.3 pfm_terminate.3 pfm_strerror.3 libpfm_intel_core.3 libpfm_intel_x86_arch.3 libpfm_amd64.3 libpfm_amd64_k7.3 libpfm_amd64_k8.3 libpfm_amd64_fam10h.3 libpfm_amd64_fam15h.3 libpfm_amd64_fam16h.3 libpfm_amd64_fam17h.3 libpfm_amd64_fam17h_zen2.3 libpfm_amd64_fam19h_zen3.3 libpfm_amd64_fam19h_zen3_l3.3 libpfm_intel_atom.3 libpfm_intel_nhm.3 libpfm_intel_nhm_unc.3 libpfm_intel_wsm.3 libpfm_intel_wsm_unc.3 libpfm_intel_snb.3 libpfm_intel_snb_unc.3 libpfm_intel_ivb.3 libpfm_intel_ivb_unc.3 libpfm_intel_hsw.3 libpfm_intel_bdw.3 libpfm_intel_rapl.3 libpfm_intel_slm.3 libpfm_intel_tmt.3 libpfm_intel_skl.3 libpfm_intel_icl.3 libpfm_intel_glm.3 libpfm_intel_knl.3 libpfm_intel_knm.3 libpfm_intel_snbep_unc_cbo.3 libpfm_intel_snbep_unc_ha.3 libpfm_intel_snbep_unc_imc.3 libpfm_intel_snbep_unc_pcu.3 libpfm_intel_snbep_unc_qpi.3 libpfm_intel_snbep_unc_ubo.3 libpfm_intel_snbep_unc_r2pcie.3 libpfm_intel_snbep_unc_r3qpi.3 libpfm_intel_ivbep_unc_cbo.3 libpfm_intel_ivbep_unc_ha.3 libpfm_intel_ivbep_unc_imc.3 libpfm_intel_ivbep_unc_pcu.3 libpfm_intel_ivbep_unc_qpi.3 libpfm_intel_ivbep_unc_ubo.3 libpfm_intel_ivbep_unc_r2pcie.3 libpfm_intel_ivbep_unc_r3qpi.3 libpfm_intel_ivbep_unc_irp.3 libpfm_intel_knc.3 libpfm_intel_hswep_unc_cbo.3 libpfm_intel_hswep_unc_ha.3 libpfm_intel_hswep_unc_imc.3 libpfm_intel_hswep_unc_irp.3 libpfm_intel_hswep_unc_pcu.3 libpfm_intel_hswep_unc_qpi.3 libpfm_intel_hswep_unc_r2pcie.3 libpfm_intel_hswep_unc_r3qpi.3 libpfm_intel_hswep_unc_sbo.3 libpfm_intel_hswep_unc_ubo.3 libpfm_intel_bdx_unc_cbo.3 libpfm_intel_bdx_unc_ha.3 libpfm_intel_bdx_unc_imc.3 libpfm_intel_bdx_unc_irp.3 libpfm_intel_bdx_unc_pcu.3 libpfm_intel_bdx_unc_qpi.3 libpfm_intel_bdx_unc_r2pcie.3 libpfm_intel_bdx_unc_r3qpi.3 libpfm_intel_bdx_unc_sbo.3 libpfm_intel_bdx_unc_ubo.3 libpfm_intel_skx_unc_cha.3 libpfm_intel_skx_unc_imc.3 libpfm_intel_skx_unc_irp.3 libpfm_intel_skx_unc_m2m.3 libpfm_intel_skx_unc_m3upi.3 libpfm_intel_skx_unc_pcu.3 libpfm_intel_skx_unc_ubo.3 libpfm_intel_skx_unc_upi.3 pfm_get_perf_event_encoding.3 libpfm_perf_event_raw.3 /usr/local/share/man/man3 )
make[1]: Leaving directory '/home/username/libpfm4/docs'

我现在可以在 /usr/local/libpfm.{a,so,so.4,so.4.11.1} 中看到图书馆了。

编译程序

#include <stdio.h>
#include <perfmon/pfmlib.h>

int main(int argc, char **argv){
    int idx;
    pfm_os_t os;
    pfm_event_info_t info;

    idx = 239075328;
    os = PFM_OS_NONE;
    pfm_initialize();
    pfm_get_event_info(idx, os, &info);

    printf("Name:  %s\n"
           "Desc:  %s\n"
           "Equiv: %s\n"
           "Code:  %lu\n"
           "IDX:   %d\n"
           "Attr:  %d\n",
           info.name,
           info.desc,
           info.equiv,
           info.code,
           info.idx,
           info.nattrs);

    return 0;
}

我用这个编译:

gcc -lpfm -Wall -Werror -std=gnu11 -pthread -g -o0 -fno-omit-frame-pointer -I include -o out.bin code.c

我得到一个干净的输出。

运行 程序

$ ./out.bin
./out.bin: error while loading shared libraries: libpfm.so.4: cannot open shared object file: No such file or directory

如果我使用 ldd,我得到这个:

$ ldd out.bin
    linux-vdso.so.1 (0x00007ffc8f9fe000)
    libpfm.so.4 => not found
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fdcdcf0b000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fdcdcd40000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fdcdcf44000)

我可能遗漏了什么?

库的 link 时间路径与 运行 时间路径之间存在差异。

由于库位于(显然)不由 运行 时间加载程序处理的位置,因此您必须在 link 告诉 link 时添加一个标志er 在可执行文件中添加有关它的信息以供 运行-time 加载程序检查。

这是通过 -rpath linker specific 标志完成的。

您可以使用 gcc-Wl 选项来传递它:

gcc ... -Wl,-rpath=/usr/local/lib -L/usr/local/lib -lpfm