Re: newbie has linker error

From: Larry I Smith (larryXiXsmith_at_verizon.net)
Date: 12/23/04


Date: Thu, 23 Dec 2004 22:18:05 GMT

Donnie Fuqua wrote:
> "Larry I Smith" <larryXiXsmith@verizon.net> wrote in message
> news:j0Cyd.8244$rL3.7530@trnddc03...
>
>>Donnie Fuqua wrote:
>>
>>>I have a class in a static library which has a pure virtual function.
>>>In the program that calls the library I derive a class and implement the
>>>function.
>>>Should this work?
>>>When I build the program I get "undefined reference to vtable" for the
>>>derived class,
>>>where I instantiate the class (linker error).
>>>The program builds with Visual C++ v6.0 with Microsoft extensions
>
> disabled
>
>>>and no
>>>windows header files.
>>>My best guess is that I am not using the linker correctly in the
>
> makefile.
>
>>>I would greatly appreciate any ideas.
>>>Regards,
>>>Donnie Fuqua
>>>
>>>
>>>
>>>
>>>----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet
>
> News==----
>
>>>http://www.newsfeeds.com The #1 Newsgroup Service in the World! >100,000
>
> Newsgroups
>
>>>---= East/West-Coast Server Farms - Total Privacy via Encryption =---
>>>
>
> I am using Suse Linux 9.1 Professional
> Here are the abridged listings of the base class declaration and the
> makefiles
> for library and the calling program.
>
> class CNeuralNet
> {
> private:
> CNNet* m_pNNet;
> public:
> CNeuralNet();
> virtual ~CNeuralNet();
> void CreateNetwork(ULONG arg1,ULONG arg2,ULONG arg3,ULONG arg4);
> // Other public functions which are implemented in NeuralNet.cpp
> virtual void TrainingProgress(ULONG arg1,float sse_error,float
> mse_error,float rms_error);
> // The above virtual function is implemented in NeuralNet.cpp
> without the virtual keyword.
> };
>
> makefile for library:
>
> AR=ar
> ARFLAGS=cq
> CC=g++
> CFLAGS=-c -Wall -O3 -march=pentium3
> SOURCES=AdjWeightsCls.cpp BackErrorCls.cpp (etc.)
> OBJECTS=$(SOURCES:%.cpp=%.o)
> LIBRARY=libnnet2.a
>
> all: $(SOURCES) $(LIBRARY)
>
> $(LIBRARY): $(OBJECTS)
> rm -f $@
> $(AR) $(ARFLAGS) $@ $(OBJECTS)
>
> .cpp.o:
> $(CC) $(CFLAGS) $< -o $@
>
> makefile for program that uses library:
>
> CC=g++
> CFLAGS=c -O3
> LFLAGS=-static
> SOURCES=NeuralNet2.cpp nntrain.cpp
> OBJECTS=$(SOURCES:%.cpp=%.o)
> EXE=nntrain
> LIB=nnet2
> LIBDIR=/home/dfuqua/projects/neuralnet2
>
> all: $(SOURCES) $(EXE)
>
> $(EXE): $(OBJECTS)
> rm -f $@
> $(CC) -o $(OBJECTS) -l$(LIB) -L$(LIBDIR) $(LFLAGS)
>
> .cpp.o:
> $(CC) $(CFLAGS) $< -o $@
>
>
>
>>>-----------== Posted via Newsfeed.Com - Uncensored Usenet News
>
> ==----------
>
>>> http://www.newsfeed.com The #1 Newsgroup Service in the World!
>>>-----= Over 100,000 Newsgroups - Unlimited Fast Downloads - 19 Servers
>
> =-----
>
>>Provide some sample code please.
>>
>>Which distro and version (Redhat 8.0, Suse 9.2, Mandrake 10, etc)?
>>Which compiler version (g++ 3.3.4, etc)?
>>
>>For C++, you normally let g++ invoke the linker (in the Makefile)
>>rather than invoking it yourself. g++ passes 'extra' stuff
>>to the linker to ensure all is done correctly.
>>
>>Regards,
>>Larry
>>
>>--
>>Anti-spam address, change each 'X' to '.' to reply directly.
>
>
>
>
>
> ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
> http://www.newsfeeds.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
> ---= East/West-Coast Server Farms - Total Privacy via Encryption =---
>
>
> -----------== Posted via Newsfeed.Com - Uncensored Usenet News ==----------
> http://www.newsfeed.com The #1 Newsgroup Service in the World!
> -----= Over 100,000 Newsgroups - Unlimited Fast Downloads - 19 Servers =-----

Oh, MS Windows code...

Well, there's not enough source to debug, but (assuming the
GNU tools are in use - ld, ar, make, gcc/g++, ranlib, etc):

  - Correct the '-march' option:

      -march=_pentium3

  - fix the option order in ARFLAGS and append 's' to include an
    index in the archive so archive modules may refer to each
    other (see 'man ar' for details on 's'):

       ARFLAGS=qcs

    -OR-

    add 'ranlib $(LIBRARY)' as the last build command for
    target $(LIBRARY).

  - '-L' must appear before any '-l' options which depend on it, eg:

    $(CC) -o $(OBJECTS) -L$(LIBDIR) -l$(LIB) $(LFLAGS)

  - You're putting C++ code into a static lib created by 'ar'.
    'ar' MAY have a name length restriction of 15 chars for
    backward compatability with other archive programs (are you
    running this under Cygwin?) So, your C++ mangled-names may
    not be correctly resolved. see 'man ar' for details.

'make' has builtin default rules for most file types.
Run 'make -p' to see what they are.
You are doing two things that are non-portable, and MAY induce
errors: a) using the 'C' predefined macros for C++ rules,
b) un-necessarily overriding the default rules. By redefining
the 'C' macros for C++ usage, rather than using the C++ macros,
other macros which depend on the 'C' macros will be changed.
Examine the output of 'make -p' and you'll see what I mean.

The default rules for compiling & linking '.c' files are:

  COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

  LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

The default rules for compiling & linking '.cc', '.cpp', and '.C'
files are:

  COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

  LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

So, reworking your Makefiles a little, we get:

makefile for library:

  # this is also the default value for AR
  AR=ar
  ARFLAGS=qcs
  # this is also the default value for CXX
  CXX=g++
  CXXFLAGS=-Wall -O3
  TARGET_ARCH=-march=_pentium3
  SOURCES=AdjWeightsCls.cpp BackErrorCls.cpp (etc.)
  OBJECTS=$(SOURCES:%.cpp=%.o)
  LIBRARY=libnnet2.a

  all: $(SOURCES) $(LIBRARY)

  $(LIBRARY): $(OBJECTS)
      rm -f $@
      $(AR) $(ARFLAGS) $@ $(OBJECTS)

makefile for program that uses library:

  CXX=g++
  CXXFLAGS=-Wall -O3
  # depending on the platform, '-static' may cause even the
  # system libs to be static linked, so we leave it out for now.
  ## LDFLAGS=-static
  SOURCES=NeuralNet2.cpp nntrain.cpp
  OBJECTS=$(SOURCES:%.cpp=%.o)
  EXE=nntrain
  LIB=nnet2
  LIBDIR=/home/dfuqua/projects/neuralnet2

  all: $(SOURCES) $(EXE)

  $(EXE): $(OBJECTS)
      $(CXX) -o $(EXE) $(OBJECTS) -L$(LIBDIR) -l$(LIB) $(LDFLAGS)

There's more, but my eyes are getting tired.....

Regards,
Larry

-- 
Anti-spam address, change each 'X' to '.' to reply directly.


Relevant Pages

  • Re: GNU make: recursive make vs single makefile
    ... technics of using single makefile and who knows in practice about ... I also made a set of macros so you could add new ... You learn a lot about make syntax and features getting it working ... sub-make defines the same variable. ...
    (comp.os.linux.development.system)
  • nmake building what it shouldnt?!
    ... I have an app that is made with one solution and several projects ... The way this is currently handled, with VS6, is with nmake makefiles. ... There is a separate file containing macros, ... into the main makefile for the solution. ...
    (microsoft.public.vc.ide_general)
  • Re: 68008 co-processor board complete working design available ...
    ... Uses 4 simple macros. ... All-h.txt = All .h files needed by the makefile run together into ... I do note that having the coprocessor interface with the 6502 CPU by a ... dedicated 512x9 FIFO in each direction allows some really nice things, ...
    (comp.sys.apple2)
  • Re: nmake building what it shouldnt?!
    ... The way this is currently handled, with VS6, is with nmake makefiles. ... There is a separate file containing macros, ... into the main makefile for the solution. ...
    (microsoft.public.vc.ide_general)