我有一个可执行文件和一个.so文件,它使用不同版本的Oracle Instant Client库。它们与不同版本兼容,我必须同时使用它们。
可执行文件使用版本11 - 它链接到使用“libclntsh.so.11.1”的.so文件 - 版本是硬编码的,我无法修改.so文件。
ldd Executable_name
linux-vdso.so.1 => (0x00007ffffe7fe000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fbb33e80000)
libdx_t.so => not found
libudr_t.so => not found
libnsl.so.1 => /lib64/libnsl.so.1 (0x00007fbb33c66000)
**libclntsh.so.11.1** => not found
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fbb3395e000)
libm.so.6 => /lib64/libm.so.6 (0x00007fbb3365c000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fbb33445000)
libc.so.6 => /lib64/libc.so.6 (0x00007fbb33084000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbb340aa000)
.so文件正在使用版本12,它正在使用dlopen
。
ldd libOracleClient.so
linux-vdso.so.1 => (0x00007fff705a2000)
libclntsh.so.12.1 => not found
libocci.so.12.1 => not found
libnnz12.so => not found
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fe8d6d49000)
libm.so.6 => /lib64/libm.so.6 (0x00007fe8d6a46000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe8d6830000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe8d646f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe8d72e4000)
我已经成功编译了我的代码。我为这两个版本的Oracle Instant Client创建了两个目录,并将它们都添加到LD_LIBRARY_PATH。
问题是在两个Oracle Instant Client 11和12目录中有一些.so文件具有相同的名称。
Oracle Instant Client 11库: -
libclntsh.so libclntsh.so.11.1 libnnz11.so libocci.so libocci.so.11.1 libociei.so libocijdbc11.so ojdbc5.jar ojdbc6.jar xstreams.jar
Oracle Instant Client 12库: -
libclntshcore.so.12.1 libclntsh.so.12.1 libmql1.so libocci.so.12.1 libociei.so libons.so ojdbc6.jar xstreams.jar libclntsh.so libipc1.so libnnz12.so libocci.so_bkp libocijdbc12.so liboramysql12.so ojdbc7.jar
具有相同名称的库:libociei.so等。
现在,情况是来自Oracle 12客户端的.so文件在内部调用了一个存在于Oracle 11客户端目录中的.so文件。将使用哪个.so,因为在LD_LIBRARY_PATH中都存在?
答案 0 :(得分:0)
一个相当简单的方法是让您的LD_LIBRARY_PATH
仅引用当前版本的12c库位置,并从中移除11g路径。
然后有一个包装器脚本(或shell函数)设置11g路径并调用可执行文件,比如my_exe_wrapper
:
export LD_LIBRARY_PATH=/path/to/instant_client_12_1
# add anything else you need in that variable, except the 11g path
/path/to/original_exe
添加别名,以便您仍然可以通过原始名称引用它:
alias -x original_exe=/path/to/my_exe_wrapper
现在当你运行original_exe
时,它将调用包装器脚本,它将设置环境变量并调用真正的可执行文件。这将无法查看12c库,因为它们的路径不再被搜索。反过来说,其他一切 - 包括任何使用libOracleClient.so
- 将无法看到11g库。
如果您的LD_LIBRARY_PATH
包含大量条目,并且您不想从头开始重新创建它,并且如果11g和12c库位置的路径相似,则可以使用{{1}仅替换该段。如果你把它们放在sed
和/opt/instant_client_11_2
之下,你的包装器可以这样做:
/opt/instant_client_12_1