【问题标题】:Trying to build static CGO executable with oracle libraries on Linux/Ubuntu尝试在 Linux/Ubuntu 上使用 oracle 库构建静态 CGO 可执行文件
【发布时间】:2016-08-05 09:20:12
【问题描述】:

我已经搜索了几天,尝试了几个建议,但没有任何帮助。目前我只想创建一个连接到 Oracle 数据库的小型 Go sn-p。虽然一切都可以通过使用普通的go build 并调用生成的动态链接应用程序来工作,但当我尝试运行静态编译器时我被卡住了。我已经静态地构建了其他项目(即使使用 CGO)也没有问题,但是这里 gcc 没有找到 oracle 库。也许有人有提示?

构建过程中出错:

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)拥有它需要的一切:

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 和/或 LD_LIBRARY_PATH 环境变量,但没有帮助。

Pkg-config 也显示库

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

正如所见,一个文件的大小为零,所以我必须运行 $ORACLE_HOME/bin/genclntst 来生成 libclntst12.a。

【问题讨论】:

  • 您还没有显示/usr/lib/oracle/12.1/client64/lib/ 是否包含您需要的所有东西的静态库(或者系统是否具有其依赖项的静态版本,但这更有可能)
  • 你好,我不得不承认我对编译静态程序的知识并不多。所以,这是我的目录:ls /usr/lib/oracle/12.1/client64/lib/ glogin.sql libclntsh.so libclntsh.so.12.1 libclntshcore.so libclntshcore.so.12.1 libipc1.so libmql1.so libnnz12.so libocci.so libocci.so.12.1 libociei.so libocijdbc12.so libons.so liboramysql12.so libsqlplus.so libsqlplusic.so ojdbc6.jar ojdbc7.jar ottclasses.zip xstreams.jar

标签: oracle go static-linking cgo oci8


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

    /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 中的符号。

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

【讨论】:

  • 您好,感谢您的快速回答。我的安装中没有重新链接工具(我没有完整安装 oracle),我下载了一些即时客户端软件包并通过外星人将它们安装在 ubuntu 上(按照此处的说明进行操作:[help.ubuntu.com/community/Oracle%20Instant%20Client])。稍后将检查重新链接是否在我尚未解压缩/安装的其他包中。
  • 嗨,所以我发现(见上面的评论)我缺少“.a”静态库。我的文件夹仅包含共享文件。现在我正在寻找 $ORACLE_HOME/bin/relink,因为它无法通过我从 Ubuntu 社区遵循的安装过程获得。我希望该工具随后会生成“.a”文件
  • 你好,同时我已经安装了oracle安装并找到了relink工具。在工具的日志中,我(再次)发现了一些关于链接器的错误消息,所以我必须通过它们来修复它们,直到我得到静态库......我猜......
  • 嗨,我在修复了一些问题后运行了重新链接工具(主要是在 (gemsofprogramming.wordpress.com/2013/09/19/…) 的帮助下。你是对的,现在我有很多符号丢失了,需要解决它们.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 2011-08-22
  • 2012-04-19
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
相关资源
最近更新 更多