help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Cannot link against my own library due to undefined symbols???


From: Pep
Subject: Cannot link against my own library due to undefined symbols???
Date: Tue, 5 Feb 2008 10:06:08 -0800 (PST)
User-agent: G2/1.0

Using g++ 3.3.6 on various linux distro's.

I have a namespace spread over 4 source files called file1.h file1.cc
file2.h file2.cc, which are built in to a static library. My problem
is that I cannot link against the library I create. The symbols from
the library used in the main routine are rejected as undefined. I have
checked the mangled names in both the main routine and the library and
they match.

g++ -I. -L. -ltest -o test-main main.cc
/tmp/ccuB5As0.o: In function `main':
main.cc:(.text+0x19): undefined reference to
`ns1::derived_class::derived_class()'
main.cc:(.text+0x29): undefined reference to
`ns1::derived_class::~derived_class()'
collect2: ld returned 1 exit status

Yet if I compile and link the objects in one unit, everything is fine,
as shown by the following

g++ -I. -o test-main main.cc file1.cc file2.cc

./test-main
ns1::base_class::base_class()
ns1::derived_class::derived_class()
ns1::derived_class::~derived_class()
ns1::base_class::~base_class()

Here's the working source files that demonstrate the problem, with the
output of the build steps at the end

// file1.h
#ifndef X__FILE1_H__X
#define X__FILE1_H__X

namespace ns1
{
        class base_class
        {
                public:
                        base_class();
                        ~base_class();
        };
}
#endif // X__FILE1_H__X

// file 1.cc
#include <file1.h>

#include <iostream>

ns1::base_class::base_class()
{
        std::cout << "ns1::base_class::base_class()" << std::endl;
}

ns1::base_class::~base_class()
{
        std::cout << "ns1::base_class::~base_class()" << std::endl;
}

// file2.h
#ifndef X__FILE2_H__X
#define X__FILE2_H__X

#include <file1.h>

namespace ns1
{
        class derived_class
                : public base_class
        {
                public:
                        derived_class();
                        ~derived_class();
        };
}
#endif // X__FILE2_H_X

// file2.cc
#include <file2.h>

#include <iostream>

ns1::derived_class::derived_class()
{
        std::cout << "ns1::derived_class::derived_class()" <<
std::endl;
}

ns1::derived_class::~derived_class()
{
        std::cout << "ns1::derived_class::~derived_class()" <<
std::endl;
}

// file main.cc
#include <file2.h>

int main(int argc, char** argv)
{
        ns1::derived_class object;

        return(1);
}

file1 contains a base class called base_class which is derived in to a
class called derived_class in file2.

main.cc contains a simple test for the problem that only instantiates
an object of derived_class.

Here's the output of the library build step with output from nm

g++ -c -I./ file1.cc file2.cc && ar cqsv libtest.a *.o && nm --print-
armap libtest.a
a - file1.o
a - file2.o

Archive index:
_ZN3ns110base_classD1Ev in file1.o
_ZN3ns110base_classD2Ev in file1.o
_ZN3ns110base_classC1Ev in file1.o
_ZN3ns110base_classC2Ev in file1.o
_ZN3ns113derived_classD1Ev in file2.o
_ZN3ns113derived_classD2Ev in file2.o
_ZN3ns113derived_classC1Ev in file2.o
_ZN3ns113derived_classC2Ev in file2.o

file1.o:
00000046 t _GLOBAL__I__ZN3ns110base_classC2Ev
00000000 t _Z41__static_initialization_and_destruction_0ii
000000ca T _ZN3ns110base_classC1Ev
000000f6 T _ZN3ns110base_classC2Ev
00000072 T _ZN3ns110base_classD1Ev
0000009e T _ZN3ns110base_classD2Ev
         U _ZNSolsEPFRSoS_E
         U _ZNSt8ios_base4InitC1Ev
         U _ZNSt8ios_base4InitD1Ev
         U _ZSt4cout
         U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
00000000 b _ZSt8__ioinit
         U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
         U __cxa_atexit
         U __dso_handle
         U __gxx_personality_v0
0000005e t __tcf_0

file2.o:
00000046 t _GLOBAL__I__ZN3ns113derived_classC2Ev
         U _Unwind_Resume
00000000 t _Z41__static_initialization_and_destruction_0ii
         U _ZN3ns110base_classC2Ev
         U _ZN3ns110base_classD2Ev
00000146 T _ZN3ns113derived_classC1Ev
000001a4 T _ZN3ns113derived_classC2Ev
00000072 T _ZN3ns113derived_classD1Ev
000000dc T _ZN3ns113derived_classD2Ev
         U _ZNSolsEPFRSoS_E
         U _ZNSt8ios_base4InitC1Ev
         U _ZNSt8ios_base4InitD1Ev
         U _ZSt4cout
         U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
00000000 b _ZSt8__ioinit
         U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
         U __cxa_atexit
         U __dso_handle
         U __gxx_personality_v0
0000005e t __tcf_0

Here's the output of the main.cc build step with output from nm

g++ -c -I. -o main.o main.cc && nm --print-armap main.o
         U _ZN3ns113derived_classC1Ev
         U _ZN3ns113derived_classD1Ev
         U __gxx_personality_v0
00000000 T main

I've been looking at this for some time now and am frankly stumped by
what I know must be a simple case of me not doing something I should
have but I don't know what. I blame all these RAD tools and things
like autoconf, etc because I've been so embedded in them for years
that I can't do a simple thing on the comand line, lol.

TIA,
Pep.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]