dongzanghong4379 2016-08-05 09:20
浏览 111
已采纳

尝试在Linux / Ubuntu上使用oracle库构建静态CGO可执行文件

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?

Error during build:

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

Build command

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

Application code:

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", "...")
    ...
}

I have checked with

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

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)

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

Pkg-config shows as well the library

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

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...

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

  • 写回答

1条回答 默认 最新

  • douji6735 2016-08-05 10:51
    关注
    • 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
      

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

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题