Re: C++ (g++) linker error linking dependent static libraries to
create executable
On Jan 25, 12:24 am, "sriram.sundarara...@gmail.com"
<sriram.sundarara...@gmail.com> wrote:
I'm battling a linker issue. Here is the scenario. I have two static
libraries libA.a and libB.b and am trying to create an executable
hello.exe from hello.cpp, libA.a and libB.a.
blah/
/libA
libA.h libA.cpp -----> libA.a <= A::printA(string arga)
/libB
libB.h libB.cpp ------> libB.a <= B::printB(string argb)
{ A().(argb) }
/src
hello.cpp
LibA contains class A, with method A::printA(string arga).
LibB contains class B with method B::printB(string argb) which calls
A().printA(argb).
hello.cpp invokes B().printB("Hello, World"). When I compiled libB, I
did not link with libA.a as I wanted to keep the libraries separate.
My "real world" libraries are way way larger.
So I created static libraries libA.a and libB.a. When I tried to
create hello.exe using,
g++ -W -Wall -pipe -g -o main.exe main.o -Lblah/src -Lblah/lib1 -
Lblah/lib2 blah/lib1/libA.a blah/lib2/libB.a
Why not?
g++ -W -Wall -pipe -g -o main.exe main.o \
-Lblah/src -Lblah/lib1 - Lblah/lib2 -lA -lB
The purpose of the -L option is to allow the shorthand use of
-l.
Of course, you'll still have the problem, since A::printA isn't
an unresolved extern when you link in libA.a.
I got this....
blah/lib2/libB.a(libB.o): In function `ZN1B1aESs':
blah/lib2/libB.cpp:9: undefined reference to `A::printB(std::string)'
blah/lib2/libB.a(libB.o): In function `ZN1B1bEi':
blah/lib2/libB.cpp:15: undefined reference to `A::printA(int)'
collect2: ld returned 1 exit status
make: *** [debug/main.exe] Error
I am sure
1. I used my -L and -l options right
You didn't in the example.
2. I used nm to verify the symbols are actually in both the
libraries. (A in libA and B in libB. There are 'U'ndefined
references to A in libB though).
Then B must be linked in first.
The rest is really very gcc specific, but in general, linkers
work in one of two ways: most (including gcc and all Unix based
compilers I'm familiar with) process the files in the order they
are given; a few (VC++, for example), collect the libraries, and
process them as if they were a single library, after having
processed all of the object files. Generally, the first gives
you considerably more control, but requires exposing your
dependencies to the user. (FWIW, I once used a linker which not
only processed the libraries in order, but processed each
library sequentially. Even within a library, you had to do a
topological sort on the dependencies to ensure the order.)
3. The methods are public
4. I tried ordering the libraries differently in the -l option. Here
there are only 2 possibilities I guess.
No you didn't. Or you have other dependencies, which create a
cycle.
I am using MinGW. Any suggestions? Why does this occur? My
google-fu has failed me the past couple of days. I would like
to keep the libraries separate. combining libs A and B does
work. I'm puzzled as to why this approach does not work. The
symbol definitions are definitely present in both the
libraries.
I am guessing that since hello calls B::b, libB gets linked
first and the process of linking, the linker(?) tries to
lookup all symbols in B, including A.
These are libraries, not object files. The compiler processes
them in the order they occur, incorporating modules which
resolve unresolved external symbols, and only those modules.
Since when the compiler processes your libA.a, there is no
unresolved symbol A::printA, so the module which contains it is
not incorporated into the program. When the compiler later
processes libB.a, it finds an unresolved external for A::printA,
but there is nothing left to resolve it.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34