2013-02-26 67 views
0

我想在OS X上编译一个简单的Oracle应用程序并运行到链接问题。任何帮助,将不胜感激。在OSX上构建Oracle Instant Client链接错误

#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 

回答

0

乍一看,它看起来像你要么安装了32位的即时客户端,在这种情况下,您只能构建32位二进制文​​件,因此需要将-m32标志添加到gcc;或者您安装了64位即时客户端,并且gcc由于某种原因(例如别名)而默认为32位,在这种情况下,您可以用-m64标志覆盖。

无论哪种方式,您的即时客户似乎是错误的架构......实际上从你的错误信息,您正在构建64位模式下x86_64,因此你似乎已经安装了32位即时客户端。但是,你在你没有安装64位版本,你可以验证(你可能知道)的问题与所述:

$ file ~/oracle_client/libclntsh.dylib.11.1 

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

$ file ~/oracle_client/libclntsh.dylib 

它仍然不会与整理编译,但其余的错误而不是Oracle相关的,据我可以告诉...和约翰·马歇尔指出,刚将命令从gcc切换到g++可解决剩余的问题。

g++ -m32 main.cpp ... 

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

只是为了比较,使用一个32位的客户端与64位生成失败:

$ 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 

使用一个64位的客户端与32位生成失败:

$ 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 
1
Undefined symbols for architecture x86_64: 
"std::allocator::allocator()", referenced from: 
_main in ccWf4dno.o 
[...] 

所有这些未定义的符号是C++运行时支持库函数,无关的Oracle 。让GCC在把这些最简单,最好的办法是用g++命令,不gcc链接C++代码:

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

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

+0

即时客户端具有不同的32位和64位版本,它们不包含两者。用'-m32'或'-m64'避免了这个问题,只剩下那些错误。你说得很对,用'g ++'确实解决了这个问题 - 但你需要两个。 – 2013-02-26 23:24:30