2013-02-26 64 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