在OSX上构建时出现Oracle Instant Client链接错误

时间:2013-02-26 19:12:16

标签: xcode macos oracle gcc

我正在尝试在OS X上编译一个简单的Oracle应用程序并遇到链接问题。任何帮助,将不胜感激。

#include <iostream>
#include <occi.h>

using namespace std;
using namespace oracle::occi;

Environment * env;
Connection * conn;

int main(int argc, char ** argv)
{
    env = Environment::createEnvironment(Environment::OBJECT);
    conn = env->createConnection("scott", "tiger", "//lcoalhost:1521/xe");
    Statement *stmt = conn->createStatement("SELECT COUNT(*) FROM TAB");
    ResultSet *rs=stmt->executeQuery();
    rs->next();
    string ntabs=rs->getString(1);
    cout << "Number of tables " << ntabs << endl;
    conn->terminateStatement(stmt);
    // Close connection etc
    env->terminateConnection(conn);
    Environment::terminateEnvironment(env);
    return 0;
}

我在~/oracle_client安装了x64 oracle即时客户端。我可以使用sqlpluspython (cx_Oracle)连接到数据库。

我正在使用以下命令编译文件

gcc main.cpp -I ~/oracle_client/sdk/include/ -L ~/oracle_client -locci -lclntsh

以下是我收到的ld错误:

ld: warning: ignoring file <ORACLE_HOME >/libclntsh.dylib, file was built for unsupported file format ( 0x62 0x6f 0x6f 0x6b 0x 0 0x 0 0x 0 0x 0 0x6d 0x61 0x72 0x6b 0x 0 0x 0 0x 0 0x 0 ) which is not the architecture being linked (x86_64): <ORACLE_HOME>/libclntsh.dylib
Undefined symbols for architecture x86_64:
"std::allocator::allocator()", referenced from:
_main in ccWf4dno.o
"std::allocator::~allocator()", referenced from:
_main in ccWf4dno.o
"std::basic_ostream >::operator >& (*)(std::basic_ostream >&))", referenced from:
_main in ccWf4dno.o
"std::basic_string, std::allocator >::basic_string(char const*, std::allocator const&)", referenced from:
_main in ccWf4dno.o
"std::basic_string, std::allocator >::~basic_string()", referenced from:
_main in ccWf4dno.o
"std::ios_base::Init::Init()", referenced from:
__static_initialization_and_destruction_0(int, int)in ccWf4dno.o
"std::ios_base::Init::~Init()", referenced from:
___tcf_0 in ccWf4dno.o
"std::cout", referenced from:
_main in ccWf4dno.o
"std::basic_ostream >& std::endl >(std::basic_ostream >&)", referenced from:
_main in ccWf4dno.o
"std::terminate()", referenced from:
_main in ccWf4dno.o
"std::basic_ostream >& std::operator >(std::basic_ostream >&, char const*)", referenced from:
_main in ccWf4dno.o
"std::basic_ostream >& std::operator, std::allocator >(std::basic_ostream >&, std::basic_string, std::allocator > const&)", referenced from:
_main in ccWf4dno.o
"___gxx_personality_v0", referenced from:
Dwarf Exception Unwind Info (__eh_frame) in ccWf4dno.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

2 个答案:

答案 0 :(得分:1)

Undefined symbols for architecture x86_64:
"std::allocator::allocator()", referenced from:
_main in ccWf4dno.o
[...]

所有这些未定义的符号都是C ++运行时支持库函数,与Oracle无关。让GCC引入这些内容的最简单和最好的方法是将C ++代码与g++命令相关联,而不是gcc

g++ main.cpp -I ~/oracle_client/sdk/include/ -L ~/oracle_client -locci -lclntsh

链接器关于 libclntsh.dylib 的架构警告只是警告,因此您安装的即时客户端可能包含正确的架构以及它所抱怨的内容。在任何情况下,摆脱这些虚假的C ++运行时链接问题,您将能够更好地调试任何剩余的Oracle链接问题。

答案 1 :(得分:0)

乍一看,您似乎安装了32位即时客户端,在这种情况下,您只能构建32位二进制文​​件,因此需要向-m32添加gcc标记;或者您安装了64位即时客户端,gcc由于某种原因(例如别名)默认为32位,在这种情况下,您可以使用-m64标记覆盖。

无论哪种方式,您的即时客户端出现都是错误的架构......实际上,从错误消息中的x86_64开始,您构建的是64位模式,因此你好像已经安装了32位即时客户端。但是你在问题中说你确实安装了64位版本,你可以用它验证(你可能知道):

$ file ~/oracle_client/libclntsh.dylib.11.1

...如果是64位,将以x86_64结尾。由于它没有抱怨libocci.dylib它似乎能够应付这一点,建议采用一种混合装置。据推测,您已为libclntsh.dyliblibocci.dylib创建了指向完整.11.1版本的符号链接。 libclntsh.dylib是否可能指向另一个目录中的32位版本;或者您将其作为32位复制到该名称,然后用64位版本替换所有内容并错过了手动复制的文件?这显示了什么架构:

$ file ~/oracle_client/libclntsh.dylib

它仍然无法使用已整理的编译进行编译,但就我所知,其余的错误与Oracle无关......正如John Marshall指出的那样,只需将命令从gcc切换到g++解决了剩余的问题。

g++ -m32 main.cpp ...

...如果正确安装/链接32位即时客户端,则创建a.out

仅用于比较,使用具有64位版本的32位客户端失败:

$ g++ -m64 main.cpp -I ~/oracle_client32/sdk/include/ -L ~/oracle_client32 -locci -lclntsh
ld: warning: ignoring file /Users/alex/oracle_client32/libocci.dylib, file was built for unsupported file format ( 0xce 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 0 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (x86_64): /Users/alex/oracle_client32/libocci.dylib
ld: warning: ignoring file /Users/alex/oracle_client32/libclntsh.dylib, file was built for unsupported file format ( 0xce 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 0 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (x86_64): /Users/alex/oracle_client32/libclntsh.dylib
Undefined symbols for architecture x86_64:
  "oracle::occi::Environment::createEnvironment(oracle::occi::Environment::Mode, void*, void* (*)(void*, unsigned long), void* (*)(void*, void*, unsigned long), void (*)(void*, void*))", referenced from:
      _main in ccWD5dXB.o
  "oracle::occi::Environment::terminateEnvironment(oracle::occi::Environment*)", referenced from:
      _main in ccWD5dXB.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

使用具有32位版本的64位客户端失败:

$ g++ -m32 main.cpp -I ~/oracle_client64/sdk/include/ -L ~/oracle_client64 -locci -lclntsh
ld: warning: ignoring file /Users/alex/oracle_client64/libocci.dylib, file was built for unsupported file format ( 0xcf 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 1 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (i386): /Users/alex/oracle_client64/libocci.dylib
ld: warning: ignoring file /Users/alex/oracle_client64/libclntsh.dylib, file was built for unsupported file format ( 0xcf 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 1 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (i386): /Users/alex/oracle_client64/libclntsh.dylib
Undefined symbols for architecture i386:
  "oracle::occi::Environment::createEnvironment(oracle::occi::Environment::Mode, void*, void* (*)(void*, unsigned long), void* (*)(void*, void*, unsigned long), void (*)(void*, void*))", referenced from:
      _main in ccuBypLo.o
  "oracle::occi::Environment::terminateEnvironment(oracle::occi::Environment*)", referenced from:
      _main in ccuBypLo.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status

但请注意,两者都抱怨两个库,而不仅仅是libclntsh。使用32位客户端和32位版本,或64位客户端和64位版本,都可以工作:

$ g++ -m32 main.cpp -I ~/oracle_client32/sdk/include/ -L ~/oracle_client32 -locci -lclntsh
$ file a.out
a.out: Mach-O executable i386

$ g++ -m64 main.cpp -I ~/oracle_client64/sdk/include/ -L ~/oracle_client64 -locci -lclntsh
$ file a.out
a.out: Mach-O 64-bit executable x86_64