tags:

views:

182

answers:

1

hi everyone. I have some trouble with indirect linking. Here is a small example that shows what's going wrong:

$ 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;
}
A: 

From the ld man page:

When linking for two-level namespace, ld does not look at indirect dylibs, except when re-exported by a direct dylibs. On the other hand when linking for flat namespace, ld does load all indirect dylibs and uses them to resolve references.

I'm no OS X developer, but sounds like you either need to re-export fooB() from liba or specify -flat_namespace.

HUAGHAGUAH