问题
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
Thest
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