当前位置: 首页 > 面试题库 >

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

顾高翰
2023-03-14
问题内容

我已经搜索了几天,尝试了一些建议,但没有帮助。目前,我只想创建一个连接到Oracle数据库的小型Go代码段。虽然一切都可以通过正常使用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和/ ord 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。


问题答案:
  • 使用$ ORACLE_HOME / bin / relink工具生成名为libclntst.a The stStand for static library的库。该文件通常不附带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版本上,整个数据库是使用Intel的ICC编译器构建和链接的。因此,当静态链接Oracle的客户端库时,还必须从ICC的运行时中添加一些静态库。



 类似资料:
  • 问题内容: 我爱得如此之多的两件事通常并不会引起我那么多的烦恼(除了我的孩子们)。我已经在工作中编写了一个Haskell程序,该程序使用诸如文本,xml- enumerator,attoparsec-text等库。我在Windows计算机,Ubuntu虚拟机(32位), Ubuntu桌面(再次为32位)和运行Ubuntu(64位)的EC2实例。 我们的客户端正在运行64位CentOS 5.3。我无

  • 问题内容: 我已经在Ubuntu中安装了Jenkins,而当我尝试在Jenkins中构建iOS应用时,会发生以下错误: 严重:找不到具有配置的路径/ usr / bin / xcodebuild的xcodebuild。 问题答案: 该工具是Apple Xcode SDK的一部分-仅可在Mac OS X上下载。 您不能简单地使用官方的iOS工具在未运行OS X的计算机上进行构建。 这意味着,如果您有

  • 以下是我的cmake代码: 我尝试从链接中合并步骤,但没有工作,并得到以下错误: /usr/bin/ld:尝试动态对象的静态链接`/usr/lib/x86_64-linux-gnu/libglu.so'collect2:错误:ld返回1退出状态src/cmakefiles/wwest-export-app.out.dir/build.make:774:recipe for targe'bin/ww

  • 问题内容: 我有一个Go库,它为C ++ OpenImageIO库(OpenImageiGO)提供绑定。我一直在通过与libOpenImageIO的标准动态链接来构建绑定,但现在尝试静态链接。我遇到了一个问题,无论我尝试使用哪种标志组合,外部链接器都会失败,并出现大量“未定义的引用”错误。我似乎回想起过去曾提到过的这个问题,他说链接器看到符号的顺序存在问题。但我似乎再也找不到此信息。 这是我最近一

  • 我在Netbeans中创建了一个java项目,现在正处于构建阶段。我的项目中的所有东西都设置好了,我在它的属性中设置了一个主类,我甚至将我的项目设置为主项目。当我进行“清理和构建”时,会用我的。jar文件创建一个dist文件夹。但是,.jar文件是不可执行的,为什么呢?我打开了。jar文件并查看了清单,指定了一个main类,那么有什么问题呢?我运行的是Netbeans 7.3.1。谢了。

  • 问题内容: 我可以使用带有静态链接的gcc构建可执行文件: gcc-静态xxx.c -o xxx 所以我可以在没有任何外部依赖库的情况下运行xxx。 但是,如果我要构建没有外部依赖库的共享库怎么办?我的意思是我希望共享库静态链接其外部引用。 问题答案: 这将起作用: 需要说明的是:-static标志(如果提供给gcc)会传递给链接器(ld),并告诉它与库的静态版本(.a)(由-l标志指定)一起使用