2009-01-19 81 views
1

間接鏈接有一些問題。這裏是展示什麼錯一個小例子:OSX上的間接鏈接故障

$ make 
g++ -fPIC -Wall -c -o main.o main.cpp 
g++ -fPIC -Wall -c -o a.o a.cpp 
g++ -fPIC -Wall -c -o b.o b.cpp 
g++ -fPic -Wall -r -dynamiclib b.o -o libb.dylib 
g++ -fPic -Wall -r -dynamiclib a.o -o liba.dylib -L. -lb 
LD_LIBRARY_PATH=. g++ main.o -o runme -L. -la -O 
/usr/libexec/gcc/powerpc-apple-darwin8/4.0.1/ld: Undefined symbols: 
fooB() 
collect2: ld returned 1 exit status 
make: *** [runme] Error 1 

的Makefile

all: runme 

CXXFLAGS=-fPIC -Wall 

runme: main.o liba.dylib libb.dylib 
     LD_LIBRARY_PATH=. g++ main.o -o runme -L. -la -O 

libb.dylib: b.o 
     g++ -fPic -Wall -r -dynamiclib b.o -o libb.dylib 

liba.dylib: a.o libb.dylib 
     g++ -fPic -Wall -r -dynamiclib a.o -o liba.dylib -L. -lb 

clean: 
     rm -f *.o *.dylib runme 

A.H

#ifndef A_H_INCLUDED 
#define A_H_INCLUDED 

// liba depends on libb 
#include "b.h" 

// call through to fooB, implemented in the header. 
inline int fooA() 
{ 
     return fooB(); 
} 

// call through to barB, implemented in the library. 
int barA(); 

#endif // A_H_INCLUDED 

a.cpp

#include "a.h" 

int barA() 
{ 
     return barB(); 
} 

b.h

#ifndef B_H_INCLUDED 
#define B_H_INCLUDED 

int fooB(); 

int barB(); 

#endif // B_H_INCLUDED 

b.cpp

#include "b.h" 

int fooB() 
{ 
     return 42; 
} 

int barB() 
{ 
     return 314; 
} 

的main.cpp

#include <iostream> 

#include "a.h" 

int main() 
{ 
     std::cout << barA() << "\n"; 
     std::cout << fooA() << "\n"; 
     return 0; 
} 

回答

0

ld man page

當連接了兩個級別的命名空間, ld不看間接dylibs, 除非通過直接 再次出口dylibs。另一方面,當爲平面名稱空間鏈接 時,ld確實加載了所有的間接dylib並使用它們 來解析引用。

我不是OS X開發人員,但聽起來你需要從liba重新導出fooB()或指定-flat_namespace。