尝试在Linux/Ubuntu上使用oracle库构建静态CGO可执行文件 [英] Trying to build static CGO executable with oracle libraries on Linux/Ubuntu

查看:163
本文介绍了尝试在Linux/Ubuntu上使用oracle库构建静态CGO可执行文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经搜索了几天,尝试了一些建议,但没有帮助.目前,我只想创建一个连接到Oracle数据库的小型Go代码段.尽管一切都可以通过使用普通的go build并调用生成的动态链接应用程序来完成,但在尝试运行静态编译器时却遇到了麻烦.我已经静态地构建了其他项目(即使使用CGO也没有问题),但是在这里gcc找不到oracle库.也许有人有提示吗?

I have already searched for some days, tried several suggestions but none helped. At the moment I just want to create a small Go snippet which connects to an Oracle Database. While everything works by using normal go build and invoking the resulting dynamic linked application, I am stuck when I try to run the static compiler. I already have build other projects statically (even with CGO) without problems, but here gcc is not finding the oracle library. Maybe someone has a hint?

构建过程中出现错误:

host link: "gcc" "-m64" "-gdwarf-2" "-o" "/tmp/go-build319417544/command-line-arguments/_obj/exe/a.out" "-static" "/tmp/go-link-116023228/000000.o" "/tmp/go-link-116023228/000001.o" "/tmp/go-link-116023228/000002.o" "/tmp/go-link-116023228/go.o" "-g" "-O2" "-g" "-O2" "-lpthread" "-g" "-O2" "-L/usr/lib/oracle/12.1/client64/lib" "-lclntsh" "-static"
/home/hannes/.gvm/gos/go1.5/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: cannot find -lclntsh
collect2: error: ld returned 1 exit status

构建命令

 CGO_ENABLED=1  go build -work -x -ldflags  " -v -linkmode external -extldflags -static"  ${MAIN_SRC}

应用代码:

package main
/*
// #cgo CFLAGS: -I/usr/lib/oracle/12.1/client64/include
// #cgo LDFLAGS: -L/usr/lib/oracle/12.1/client64/lib -lclntsh
*/
import "C"
import (
    "fmt"
    "database/sql"
    _ "github.com/mattn/go-oci8"
    "time"
)

func main(){


    db, err := sql.Open("oci8", "...")
    ...
}

我已与

dconfig -p | grep cln
libkadm5clnt_mit.so.9 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libkadm5clnt_mit.so.9
libclntshcore.so.12.1 (libc6,x86-64) => /usr/lib/oracle/12.1/client64/lib/libclntshcore.so.12.1
libclntshcore.so (libc6,x86-64) => /usr/lib/oracle/12.1/client64/lib/libclntshcore.so
libclntsh.so.12.1 (libc6,x86-64) => /usr/lib/oracle/12.1/client64/lib/libclntsh.so.12.1
libclntsh.so (libc6,x86-64) => /usr/lib/oracle/12.1/client64/lib/libclntsh.so

动态构建可执行文件(只是"go build oracle_test.go")具有所需的一切:

The dynamic build executable (just "go build oracle_test.go) has everything it needs:

ldd oracle_test 
linux-vdso.so.1 =>  (0x00007ffeac867000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f083ef82000)
libclntsh.so.12.1 => /usr/lib/oracle/12.1/client64/lib/libclntsh.so.12.1 (0x00007f083bfc5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f083bbfa000)
/lib64/ld-linux-x86-64.so.2 (0x00005615b32e8000)
libmql1.so => /usr/lib/oracle/12.1/client64/lib/libmql1.so (0x00007f083b984000)
libipc1.so => /usr/lib/oracle/12.1/client64/lib/libipc1.so (0x00007f083b606000)
libnnz12.so => /usr/lib/oracle/12.1/client64/lib/libnnz12.so (0x00007f083aefb000)
libons.so => /usr/lib/oracle/12.1/client64/lib/libons.so (0x00007f083acb6000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f083aab2000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f083a7a9000)
libnsl.so.1 => /lib/x86_64-linux-gnu/libnsl.so.1 (0x00007f083a58f000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f083a387000)
libaio.so.1 => /lib/x86_64-linux-gnu/libaio.so.1 (0x00007f083a184000)
libclntshcore.so.12.1 => /usr/lib/oracle/12.1/client64/lib/libclntshcore.so.12.1 (0x00007f0839c12000)

我还尝试放置/导出CGO_LDFLAGS和/ord LD_LIBRARY_PATH环境变量,但这无济于事.

I also tried to put/export CGO_LDFLAGS and/ord LD_LIBRARY_PATH environment variable, which didn't help.

Pkg-config也显示了库

Pkg-config shows as well the library

pkg-config --libs oci8
-L/usr/lib/oracle/12.1/client64/lib -lclntsh

在查找静态库之后,我已经安装了完整的oracle数据库软件包,现在在lib文件夹中还有更多文件: ls /usr/lib/oracle/12.1/client64/lib/lib*.a
-rw-r--r-- 1 1424782 /usr/lib/oracle/12.1/client64/lib/libagent12.a -rw-r--r-- 1 1962088 /usr/lib/oracle/12.1/client64/lib/libasmclnt12.a -rw-r--r-- 1 2187864 /usr/lib/oracle/12.1/client64/lib/libasmclntsh12.a -rw-r--r-- 1 11386 /usr/lib/oracle/12.1/client64/lib/libasmperl12.a -rw-r--r-- 1 28454 /usr/lib/oracle/12.1/client64/lib/libavstub12.a -rw-r--r-- 1 7408322 /usr/lib/oracle/12.1/client64/lib/libcell12.a -rw-r--r-- 1 11246008 /usr/lib/oracle/12.1/client64/lib/libclient12.a -rw-r--r-- 1 0 /usr/lib/oracle/12.1/client64/lib/libclntst12.a -rw-r--r-- 1 1749282 /usr/lib/oracle/12.1/client64/lib/libclsr12.a -rw-r--r-- 1 10087032 /usr/lib/oracle/12.1/client64/lib/libcommon12.a -rw-r--r-- 1 5803698 /usr/lib/oracle/12.1/client64/lib/libcore12.a -rw-r--r-- 1 6051402 /usr/lib/oracle/12.1/client64/lib/libctx12.a -rw-r--r-- 1 1201840 /usr/lib/oracle/12.1/client64/lib/libctxc12.a -rw-r--r-- 1 56964 /usr/lib/oracle/12.1/client64/lib/libctxs12.a ...snipped...

After looking for the static libraries, I have installed the complete oracle database package and now I have some more files in lib folder: ls /usr/lib/oracle/12.1/client64/lib/lib*.a
-rw-r--r-- 1 1424782 /usr/lib/oracle/12.1/client64/lib/libagent12.a -rw-r--r-- 1 1962088 /usr/lib/oracle/12.1/client64/lib/libasmclnt12.a -rw-r--r-- 1 2187864 /usr/lib/oracle/12.1/client64/lib/libasmclntsh12.a -rw-r--r-- 1 11386 /usr/lib/oracle/12.1/client64/lib/libasmperl12.a -rw-r--r-- 1 28454 /usr/lib/oracle/12.1/client64/lib/libavstub12.a -rw-r--r-- 1 7408322 /usr/lib/oracle/12.1/client64/lib/libcell12.a -rw-r--r-- 1 11246008 /usr/lib/oracle/12.1/client64/lib/libclient12.a -rw-r--r-- 1 0 /usr/lib/oracle/12.1/client64/lib/libclntst12.a -rw-r--r-- 1 1749282 /usr/lib/oracle/12.1/client64/lib/libclsr12.a -rw-r--r-- 1 10087032 /usr/lib/oracle/12.1/client64/lib/libcommon12.a -rw-r--r-- 1 5803698 /usr/lib/oracle/12.1/client64/lib/libcore12.a -rw-r--r-- 1 6051402 /usr/lib/oracle/12.1/client64/lib/libctx12.a -rw-r--r-- 1 1201840 /usr/lib/oracle/12.1/client64/lib/libctxc12.a -rw-r--r-- 1 56964 /usr/lib/oracle/12.1/client64/lib/libctxs12.a ...snipped...

看到一个文件的大小为零,所以我不得不运行$ ORACLE_HOME/bin/genclntst生成libclntst12.a.

As seen the one file has zero size, so I had to run $ORACLE_HOME/bin/genclntst to generate libclntst12.a.

推荐答案

  • 使用$ ORACLE_HOME/bin/relink工具生成名为libclntst.a的库 st代表静态库.该文件通常不附带Oracle客户端.
  • 尝试将您的应用程序与此库链接.您很可能会发现许多符号丢失.
  • 使用nm工具查找那些缺失符号的来源.
  • 对于11gR2,此命令对我有用:

    • Use $ORACLE_HOME/bin/relink tool to generate the library named libclntst.a The st stands for static library. Oracle client is not usually shipped with this file. The
    • Try to link your app with this library. You will most probably find many symbols missing.
    • Use nm tool to find the source of those missing symbols.
    • In case of 11gR2 this command worked for me:

      /usr/bin/c++ -Wall -ggdb3 -fPIC \
       CMakeFiles/opassgen.dir/opassgen.cpp.o \
       CMakeFiles/opassgen.dir/dbutils.cpp.o \
       CMakeFiles/opassgen.dir/common.cpp.o  \
       CMakeFiles/opassgen.dir/crypto.cpp.o  \
       n.o  -o opassgen                      \
       -rdynamic -static-libgcc -L. -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic \
       /home/oracle/ivan/openssl-1.0.1t/libcrypto.a  \
       /oracle/u01/db/11.2.0.4/lib/libclntst11.a     \
       /oracle/u01/db/11.2.0.4/lib/libippdcmerged.a  \
       /oracle/u01/db/11.2.0.4/lib/libippsmerged.a   \
       -Wl,--whole-archive libtrotl.a -Wl,--no-whole-archive \
       -lpthread -ldl
      

    • 静态链接要求您手动解决所有依赖性. 在此示例中,libclntst11.a依赖于libippdcmerged.a和libippsmerged.a中的符号.

      Static linking requires, that you resolve all the dependencies manually. In this example libclntst11.a depends on symbols from libippdcmerged.a and libippsmerged.a.

      在较旧的Oracle版本上,整个数据库是使用Intel的ICC编译器构建和链接的.因此,当静态链接Oracle的客户端库时,还必须从ICC的运行时中添加一些静态库.

      On older Oracle version the whole database was build and linked using Intel's ICC compiler. So when linking Oracle's client lib statically you also had to add some static libs from ICC's runtime.

      这篇关于尝试在Linux/Ubuntu上使用oracle库构建静态CGO可执行文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆