Trying to build static CGO executable with oracle libraries on Linux/Ubuntu

一世执手 提交于 2019-12-18 17:29:58

问题


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:


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



来源:https://stackoverflow.com/questions/38785691/trying-to-build-static-cgo-executable-with-oracle-libraries-on-linux-ubuntu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!