Help building/linking to static library

This is a discussion on Help building/linking to static library within the C++ Programming forums, part of the General Programming Boards category; I'm creating my first good sized project, and decided to take the opportunity to learn how to write Makefiles and ...

  1. #1
    Registered User Kernel Sanders's Avatar
    Join Date
    Aug 2008
    Posts
    61

    Help building/linking to static library

    I'm creating my first good sized project, and decided to take the opportunity to learn how to write Makefiles and libraries. I made two out of the helper classes I had written. One works, the other will not link successfully.
    **EDIT**
    I should mention that if I compile Timer on its own and link to Timer.o it works fine. Putting it into a library breaks it though

    Here is the error I get

    Code:
    make
    g++ -m64 -O2 -o exec -framework OpenGL -framework GLUT -lThreading -lUtil main.o 
    Undefined symbols:
      "Timer::~Timer()", referenced from:
          sync_thread(void*) in main.o
      "Timer::Timer()", referenced from:
          sync_thread(void*) in main.o
      "Timer::start()", referenced from:
          sync_thread(void*) in main.o
      "Timer::reset()", referenced from:
          sync_thread(void*) in main.o
      "Timer::getMicroSeconds()", referenced from:
          sync_thread(void*) in main.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status
    make: *** [exec] Error 1
    Timer is in my Util library, which will not link successfully. Here is the makefile that generates that particular library

    Code:
    CC = g++
    FLAGS = -m64 -O2 -ansi -W -Wall -c
    LIBDIR = /usr/lib
    INCDIR = /usr/include
    
    all: Timer.o
    install:
    	@ar -cvq libUtil.a Timer.o
    	@mv libUtil.a $(LIBDIR)/libUtil.a
    	@cp Timer.h $(INCDIR)/Timer.h
    uninstall: 
    	@rm $(LIBDIR)/libUtil.a
    	@rm $(INCDIR)/Timer.h
    clean:
    	@rm Timer.o
    
    Timer.o: Timer.cpp Timer.h
    	$(CC) $(FLAGS) Timer.cpp
    If anybody can help me out I would greatly appreciate it. Attached is an archive with two folders. include contains the source for both libraries. To compile and create the library run 'make' then 'make install'. This will put two libraries in /usr/lib and a few headers in /usr/include. 'make uninstall' will remove them

    I'm writing this on OS X, which is what the default files will compile on. I also included an archive with what I think the proper code to compile on linux is (it's untested tho).

    As I said, I'm also new with Makefiles. If anybody has comments/suggestions or if there's any styles or conventions that I'm violating or omitting, or wants to call me a moron, every bit of advice is welcome

    Hmmm..seems that I can't upload archives. Here are rapidshare links to the files
    OS X zip
    OS X tarball
    Linux zip
    Linux tarball
    Last edited by Kernel Sanders; 08-15-2008 at 05:35 AM.

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,490
    > g++ -m64 -O2 -o exec -framework OpenGL -framework GLUT -lThreading -lUtil main.o
    Try putting the libraries AFTER main.o

    Historically, the linker would only look in a library if there were already some unresolved symbols. If you pass the library before seeing any symbols the library resolves, you lose.

    Modern linkers however can (so I hear) scan libraries multiple times.

    Also, you might consider running ranlib on your archive to create an index. This might in itself fix the previous problem.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Registered User Kernel Sanders's Avatar
    Join Date
    Aug 2008
    Posts
    61
    Thank you for the reply. I tried both of those things and no luck on either. I ran 'ranlib -s libUtil.a' in /usr/lib and changed the main Makefile to

    Code:
    CC = g++
    FLAGS = -m64 -O2
    
    exec : main.o 
    	$(CC) $(FLAGS) -o exec -framework OpenGL -framework GLUT main.o -lUtil -lThreading
    main.o : main.cpp
    	$(CC) $(FLAGS) -c main.cpp
    But I still get the same errors :\

    Is there a problem with the library consisting of only one object file?

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    What happens if you try this?
    Code:
    $(CC) $(FLAGS) -o exec main.o -framework OpenGL -framework GLUT -lUtil -lThreading
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,660
    Another dart to throw...Use this for Util.a
    Code:
    ar rcs libUtil.a Timer.o
    As per http://www.linux.org/docs/ldp/howto/...libraries.html

    gg

  6. #6
    Registered User Kernel Sanders's Avatar
    Join Date
    Aug 2008
    Posts
    61
    Quote Originally Posted by dwks View Post
    What happens if you try this?
    Code:
    $(CC) $(FLAGS) -o exec main.o -framework OpenGL -framework GLUT -lUtil -lThreading
    Same result

    Quote Originally Posted by Codeplug View Post
    Another dart to throw...Use this for Util.a
    Code:
    ar rcs libUtil.a Timer.o
    As per http://www.linux.org/docs/ldp/howto/...libraries.html

    gg
    Thanks for the link, my perusal of the man page led me to other options for ar. Unfortunately, the problem remains

    Does the library's makefile look okay? I'm putting everything in the correct directory with the correct name, right?

    Code:
    CC = g++
    FLAGS = -m64 -O2 -ansi -W -Wall -c
    LIBDIR = /usr/lib
    INCDIR = /usr/include
    
    all: Timer.o
    install:
    	@ar rcs libUtil.a Timer.o
    	@mv libUtil.a $(LIBDIR)/libUtil.a
    	@cp Timer.h $(INCDIR)/Timer.h
    uninstall: 
    	@rm $(LIBDIR)/libUtil.a
    	@rm $(INCDIR)/Timer.h
    clean:
    	@rm Timer.o
    
    Timer.o: Timer.cpp Timer.h
    	$(CC) $(FLAGS) Timer.cpp

  7. #7
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,490
    It would be better if they were put in /usr/local/lib and /usr/local/include.

    There's a verbose option for the linker which should tell you more about what it's doing.

    There's also the "nm" utility for showing you the symbol names in objects and libraries.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  8. #8
    Registered User
    Join Date
    Jan 2008
    Posts
    287
    I was able to compile and run this program just fine on my linux machine:
    Code:
    #include <iostream>
    #include <Timer.h>
    
    int main(void) {
       Timer t;
       
       t.start();
       std::cout << t.getMicroSeconds() << std::endl;
       t.reset();
       
       return 0;
    }
    Using:
    Code:
    $ g++ -I"$HOME/linking/incl" -L"$HOME/linking/lib" test.cpp -lThreading -lUtil
    ... warnings about no newlines at end of file snipped ...
    $ ./a.out
    1
    $
    I ran your makefiles exactly, except I modified the lib and include paths for the installation. I don't have the OpenGL libraries / headers on my linux machine, so I can't test your main.cpp.

  9. #9
    Registered User Kernel Sanders's Avatar
    Join Date
    Aug 2008
    Posts
    61
    Quote Originally Posted by Salem View Post
    It would be better if they were put in /usr/local/lib and /usr/local/include.
    Thanks for the advice

    There's a verbose option for the linker which should tell you more about what it's doing.
    Do you know what that option is? gcc's man page is pretty daunting

    There's also the "nm" utility for showing you the symbol names in objects and libraries.
    Here is what nm outputs for libUtil.a

    Code:
    /my/home/folder/linking/lib/libUtil.a(Timer.o):
    0000000000000178 s EH_frame1
    0000000000000160 s __GLOBAL__I__ZN5TimerC2Ev
    0000000000000348 s __GLOBAL__I__ZN5TimerC2Ev.eh
    0000000000000110 s __Z41__static_initialization_and_destruction_0ii
    0000000000000318 s __Z41__static_initialization_and_destruction_0ii.eh
    00000000000000b0 T __ZN5Timer15getMicroSecondsEv
    00000000000002b8 S __ZN5Timer15getMicroSecondsEv.eh
    0000000000000080 T __ZN5Timer5resetEv
    0000000000000288 S __ZN5Timer5resetEv.eh
    0000000000000050 T __ZN5Timer5startEv
    0000000000000258 S __ZN5Timer5startEv.eh
    0000000000000020 T __ZN5TimerC1Ev
    00000000000001c8 S __ZN5TimerC1Ev.eh
    0000000000000000 T __ZN5TimerC2Ev
    0000000000000198 S __ZN5TimerC2Ev.eh
    0000000000000040 T __ZN5TimerD1Ev
    0000000000000228 S __ZN5TimerD1Ev.eh
    0000000000000030 T __ZN5TimerD2Ev
    00000000000001f8 S __ZN5TimerD2Ev.eh
                     U __ZNSt8ios_base4InitC1Ev
                     U __ZNSt8ios_base4InitD1Ev
    0000000000000378 b __ZSt8__ioinit
                     U ___cxa_atexit
                     U ___dso_handle
                     U ___gxx_personality_v0
    00000000000000f0 t ___tcf_0
    00000000000002e8 s ___tcf_0.eh
                     U _gettimeofday

    Quote Originally Posted by arpsmack View Post
    I was able to compile and run this program just fine on my linux machine:
    Code:
    #include <iostream>
    #include <Timer.h>
    
    int main(void) {
       Timer t;
       
       t.start();
       std::cout << t.getMicroSeconds() << std::endl;
       t.reset();
       
       return 0;
    }
    Using:
    Code:
    $ g++ -I"$HOME/linking/incl" -L"$HOME/linking/lib" test.cpp -lThreading -lUtil
    ... warnings about no newlines at end of file snipped ...
    $ ./a.out
    1
    $
    I ran your makefiles exactly, except I modified the lib and include paths for the installation. I don't have the OpenGL libraries / headers on my linux machine, so I can't test your main.cpp.
    Hmmm... I did the changed the install path to the same one you did and ran the same line to compile and I got the same error. :\

  10. #10
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,490
    If you do the same "nm" on main.o, you should see the Timer:: methods it's looking for.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  11. #11
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,490
    Also try say
    g++ -M prog.cpp
    as well.

    The -M option lists all the dependencies (as makefile rules).
    Are you getting the Timer.h you think you're supposed to be getting?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  12. #12
    Registered User
    Join Date
    Jul 2003
    Posts
    110
    I'm trying to build your OS X tarball, and I built your libraries fine and installed them.

    When I go to make exec, I can't get past the 64-bit library stuff which I seem to be missing:

    Code:
    whoie$ g++ --version
    i686-apple-darwin8-g++-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5370)
    Copyright (C) 2005 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    whoie$ cd Desktop/linking
    whoie$ cd include/
    whoie$ ls
    Makefile        Threading       Util
    whoie$ make all
    for i in Threading Util ; do \
    ( cd $i ; make ) ; \
    done
    g++ -O2 -m64 -ansi -W -Wall -c ConditionVariable.cpp
    g++ -O2 -m64 -ansi -W -Wall -c FrameSync.cpp
    g++ -O2 -m64 -ansi -W -Wall -c Mutex.cpp
    g++ -O2 -m64 -ansi -W -Wall -c Thread.cpp
    g++ -m64 -O2 -ansi -W -Wall -c Timer.cpp
    whoie$ sudo bash
    root$ make install
    for i in Threading Util ; do\
    ( cd $i ; make install ) ; \
    done
    q - FrameSync.o
    q - ConditionVariable.o
    q - Mutex.o
    q - Thread.o
    q - Timer.o
    root$ exit
    whoie$ cd ../main
    whoie$ make exec
    g++ -m64 -O2 -o exec -framework OpenGL -framework GLUT -lThreading -lUtil main.o 
    ld64 warning: in /System/Library/Frameworks//OpenGL.framework/OpenGL, missing required architecture x86_64 in file
    ld64 warning: in /System/Library/Frameworks//GLUT.framework/GLUT, missing required architecture x86_64 in file
    Undefined symbols:
      _glColor3f, referenced from:
          display()    in main.o
      _glutPostRedisplay, referenced from:
          idle()    in main.o
      _glPushMatrix, referenced from:
          display()    in main.o
      _glutSpecialFunc, referenced from:
          _main in main.o
      _glutDisplayFunc, referenced from:
          _main in main.o
      _glPopMatrix, referenced from:
          display()    in main.o
      _glClearColor, referenced from:
          init()    in main.o
      _glutCreateWindow, referenced from:
          _main in main.o
      _glutInitWindowSize, referenced from:
          _main in main.o
      _glutSwapBuffers, referenced from:
          display()    in main.o
      _glutInit, referenced from:
          _main in main.o
      _glMatrixMode, referenced from:
          reshape(int, int)in main.o
          reshape(int, int)in main.o
      _glRectf, referenced from:
          display()    in main.o
      _glutReshapeFunc, referenced from:
          _main in main.o
      _glClear, referenced from:
          display()    in main.o
      _glViewport, referenced from:
          reshape(int, int)in main.o
      _glutMainLoop, referenced from:
          _main in main.o
      _glRotatef, referenced from:
          display()    in main.o
      _glutInitDisplayMode, referenced from:
          _main in main.o
      _glutInitWindowPosition, referenced from:
          _main in main.o
      _glLoadIdentity, referenced from:
          reshape(int, int)in main.o
          reshape(int, int)in main.o
      _glOrtho, referenced from:
          reshape(int, int)in main.o
      _glShadeModel, referenced from:
          init()    in main.o
      _glutIdleFunc, referenced from:
          _main in main.o
    ld64-62.1 failed: symbol(s) not found
    collect2: ld returned 1 exit status
    make: *** [exec] Error 1
    whoie$
    When I tried removing th -m64 option from your makefiles, I get crazy errors that _main symbol is not found. I could never get the Timer lib to go missing though. The linker probably never gets far enough to check that.

    Have you tried a g++ -print-search-dirs to see if your library search path includes /usr/lib?

    I did get this to work:
    Code:
    whoie$ g++ -print-search-dirs
    install: /usr/lib/gcc/i686-apple-darwin8/4.0.1/
    programs: =/usr/libexec/gcc/i686-apple-darwin8/4.0.1/:/usr/libexec/gcc/i686-apple-
    darwin8/4.0.1/:/usr/libexec/gcc/i686-apple-darwin8/:/usr/lib/gcc/i686-apple-
    darwin8/4.0.1/:/usr/lib/gcc/i686-apple-darwin8/:/usr/libexec/gcc/i686-apple-
    darwin8/4.0.1/:/usr/libexec/gcc/i686-apple-darwin8/:/usr/lib/gcc/i686-apple-
    darwin8/4.0.1/:/usr/lib/gcc/i686-apple-darwin8/:/usr/lib/gcc/i686-apple-
    darwin8/4.0.1/../../../../i686-apple-darwin8/bin/i686-apple-darwin8/4.0.1/:/usr/lib/gcc/i686-
    apple-darwin8/4.0.1/../../../../i686-apple-darwin8/bin/
    libraries: =/usr/lib/gcc/i686-apple-darwin8/4.0.1/:/usr/lib/gcc/i686-apple-
    darwin8/4.0.1/:/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../../i686-apple-darwin8/lib/i686-
    apple-darwin8/4.0.1/:/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../../i686-apple-
    darwin8/lib/:/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../i686-apple-
    darwin8/4.0.1/:/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../:/lib/i686-apple-
    darwin8/4.0.1/:/lib/:/usr/lib/i686-apple-darwin8/4.0.1/:/usr/lib/
    whoie$ cat main.cpp
    /*
     *  main.cpp
     *  
     *
     *  Created by Max Salley on 8/11/08.
     *  Copyright 2008 __MyCompanyName__. All rights reserved.
     *
     */
    
    #include <iostream>
    #include <Timer.h>
    
    using std::cout;
    using std::cin;
    using std::endl;
    
    int main(int argc, char **argv){
      char c;
      unsigned long usec = 0;
    
      Timer t; 
    
      for( t.start(); cin.get(c); t.reset() ) {
        usec = t.getMicroSeconds();
        cout << "Time elapsed: " << usec << " usecs." << endl;
      }
    
      return 0;
    }
    whoie$ g++ -o main main.cpp -lUtil
    whoie$ ./main
    
    Time elapsed: 2033980 usecs.
    
    Time elapsed: 2199623 usecs.
    
    Time elapsed: 1062060 usecs.
    
    Time elapsed: 399868 usecs.
    
    Time elapsed: 824993 usecs.
    
    Time elapsed: 138011 usecs.
    
    Time elapsed: 549930 usecs.
    whoie$
    I'm thinking either your path is wrong, or something in your program is killing the build process and you are just getting a weird linking error from it.

    I wish I could help further, this sounds like a real frustrating problem.

  13. #13
    Registered User
    Join Date
    Jan 2008
    Posts
    287
    That's an interesting point. Why don't you try putting all your files in the same directory and building your main file with the command:

    g++ -m64 -O2 -o exec -I. -L. main.cpp -framework OpenGL -framework GLUT -lThreading -lUtil

    You'll see whether its a path issue or not at least.

    Also, check here: Mac LD Man Page. Look under the section named "Options for introspecting the linker". Try passing the linker the "-t" flag.

  14. #14
    Registered User Kernel Sanders's Avatar
    Join Date
    Aug 2008
    Posts
    61
    Quote Originally Posted by Salem View Post
    If you do the same "nm" on main.o, you should see the Timer:: methods it's looking for.
    nm says that the library has the symbols that main.o is looking for

    Quote Originally Posted by Salem View Post
    Also try say
    g++ -M prog.cpp
    as well.

    The -M option lists all the dependencies (as makefile rules).
    Are you getting the Timer.h you think you're supposed to be getting?
    It's getting the correct Timer.h

    Quote Originally Posted by whoie View Post
    I'm trying to build your OS X tarball, and I built your libraries fine and installed them.

    When I go to make exec, I can't get past the 64-bit library stuff which I seem to be missing:

    When I tried removing th -m64 option from your makefiles, I get crazy errors that _main symbol is not found. I could never get the Timer lib to go missing though. The linker probably never gets far enough to check that.

    Have you tried a g++ -print-search-dirs to see if your library search path includes /usr/lib?
    It includes /usr/lib, but not /usr/local/lib. Do you know how I can add that to the path? (It's not what's causing the error because the library used to be in /usr/lib tho)

    I did get this to work:

    I'm thinking either your path is wrong, or something in your program is killing the build process and you are just getting a weird linking error from it.

    I wish I could help further, this sounds like a real frustrating problem.
    Still nothing on my end . You've helped my knowledge a lot, even if I still can't get the damned thing to link

    Quote Originally Posted by arpsmack View Post
    That's an interesting point. Why don't you try putting all your files in the same directory and building your main file with the command:

    g++ -m64 -O2 -o exec -I. -L. main.cpp -framework OpenGL -framework GLUT -lThreading -lUtil

    You'll see whether its a path issue or not at least.
    Still nothing.

    Code:
    $ ls
    libUtil.a	main.cpp
    
    $ cat main.cpp 
    #include <iostream>
    #include <Timer.h>
    
    using std::cout;
    using std::cin;
    using std::endl;
    
    int main(int argc, char **argv){
      char c;
      unsigned long usec = 0;
    
      Timer t; 
    
      for( t.start(); cin.get(c); t.reset() ) {
        usec = t.getMicroSeconds();
        cout << "Time elapsed: " << usec << " usecs." << endl;
      }
    
      return 0;
    }
    
    $ g++ -L. -o main main.cpp -lUtil
    Undefined symbols:
      "Timer::~Timer()", referenced from:
          _main in ccHp0mMQ.o
          _main in ccHp0mMQ.o
      "Timer::Timer()", referenced from:
          _main in ccHp0mMQ.o
      "Timer::start()", referenced from:
          _main in ccHp0mMQ.o
      "Timer::reset()", referenced from:
          _main in ccHp0mMQ.o
      "Timer::getMicroSeconds()", referenced from:
          _main in ccHp0mMQ.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status
    I guess it has to be a problem with the library, it's in the same directory so it isn't a problem of finding it. Here's what nm gives me tho

    Code:
    $nm main.o
    000001f8 s EH_frame1
    0000014f s GCC_except_table0
    000001e0 s __GLOBAL__I_main
    000002a0 s __GLOBAL__I_main.eh
             U __Unwind_Resume
    00000188 s __Z41__static_initialization_and_destruction_0ii
    00000274 s __Z41__static_initialization_and_destruction_0ii.eh
             U __ZN5Timer15getMicroSecondsEv
             U __ZN5Timer5resetEv
             U __ZN5Timer5startEv
             U __ZN5TimerC1Ev
             U __ZN5TimerD1Ev
             U __ZNKSt9basic_iosIcSt11char_traitsIcEEcvPvEv
             U __ZNSi3getERc
             U __ZNSolsEPFRSoS_E
             U __ZNSolsEm
             U __ZNSt8ios_base4InitC1Ev
             U __ZNSt8ios_base4InitD1Ev
             U __ZSt3cin
             U __ZSt4cout
             U __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
    00000322 b __ZSt8__ioinit
             U __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
             U ___cxa_atexit
             U ___dso_handle
             U ___gxx_personality_v0
    00000110 t ___tcf_0
    00000248 s ___tcf_0.eh
    00000000 T _main
    00000218 S _main.eh
    
    $ nm libUtil.a 
    
    libUtil.a(Timer.o):
    0000000000000178 s EH_frame1
    0000000000000160 s __GLOBAL__I__ZN5TimerC2Ev
    0000000000000348 s __GLOBAL__I__ZN5TimerC2Ev.eh
    0000000000000110 s __Z41__static_initialization_and_destruction_0ii
    0000000000000318 s __Z41__static_initialization_and_destruction_0ii.eh
    00000000000000b0 T __ZN5Timer15getMicroSecondsEv
    00000000000002b8 S __ZN5Timer15getMicroSecondsEv.eh
    0000000000000080 T __ZN5Timer5resetEv
    0000000000000288 S __ZN5Timer5resetEv.eh
    0000000000000050 T __ZN5Timer5startEv
    0000000000000258 S __ZN5Timer5startEv.eh
    0000000000000020 T __ZN5TimerC1Ev
    00000000000001c8 S __ZN5TimerC1Ev.eh
    0000000000000000 T __ZN5TimerC2Ev
    0000000000000198 S __ZN5TimerC2Ev.eh
    0000000000000040 T __ZN5TimerD1Ev
    0000000000000228 S __ZN5TimerD1Ev.eh
    0000000000000030 T __ZN5TimerD2Ev
    00000000000001f8 S __ZN5TimerD2Ev.eh
                     U __ZNSt8ios_base4InitC1Ev
                     U __ZNSt8ios_base4InitD1Ev
    0000000000000378 b __ZSt8__ioinit
                     U ___cxa_atexit
                     U ___dso_handle
                     U ___gxx_personality_v0
    00000000000000f0 t ___tcf_0
    00000000000002e8 s ___tcf_0.eh
                     U _gettimeofday
    Also, check here: Mac LD Man Page. Look under the section named "Options for introspecting the linker". Try passing the linker the "-t" flag.
    Thanks for the link. I don't think I'm invoking ld correctly (I've never linked without gcc/g++'s interface) since it can't find what looks like some iostream related symbols

    Code:
    $ ls
    libUtil.a	main.cpp
    $ g++ -m64 -c main.cpp 
    $ ld main.o -L. -t
    main.o
    Undefined symbols:
      "__ZNSolsEm", referenced from:
          _main in main.o
      "___gxx_personality_v0", referenced from:
          EH_frame1 in main.o
      "__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_", referenced from:
          _main in main.o
      "__ZN5TimerD1Ev", referenced from:
          _main in main.o
          _main in main.o
      "__ZNSt8ios_base4InitD1Ev", referenced from:
          ___tcf_0 in main.o
      "__ZNSolsEPFRSoS_E", referenced from:
          _main in main.o
      "__ZNSi3getERc", referenced from:
          _main in main.o
      "___cxa_atexit", referenced from:
          __Z41__static_initialization_and_destruction_0ii in main.o
      "__ZNKSt9basic_iosIcSt11char_traitsIcEEcvPvEv", referenced from:
          _main in main.o
      "__ZN5TimerC1Ev", referenced from:
          _main in main.o
      "__ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc", referenced from:
          _main in main.o
          _main in main.o
      "__ZNSt8ios_base4InitC1Ev", referenced from:
          __Z41__static_initialization_and_destruction_0ii in main.o
      "__ZN5Timer5startEv", referenced from:
          _main in main.o
      "__ZN5Timer5resetEv", referenced from:
          _main in main.o
      "__Unwind_Resume", referenced from:
          _main in main.o
      "__ZSt3cin", referenced from:
          _main in main.o
      "__ZN5Timer15getMicroSecondsEv", referenced from:
          _main in main.o
      "__ZSt4cout", referenced from:
          _main in main.o
    ld: symbol(s) not found for inferred architecture x86_64
    Thanks for all the help guys. Just when I thought I understood linking...

    These two archives contain the simple program I'm working with now and the Timer files. Nothing is 64 bit and no non-standard headers are required. Here is the output of make for me
    Code:
    $ make
    g++ -ansi -W -Wall -c Timer.cpp
    a - Timer.o
    g++ -ansi -W -Wall -c main.cpp
    main.cpp:8: warning: unused parameter Ďargcí
    main.cpp:8: warning: unused parameter Ďargví
    g++ -ansi -W -Wall -o main -L. -I. main.o -lUtil
    Undefined symbols:
      "Timer::~Timer()", referenced from:
          _main in main.o
          _main in main.o
      "Timer::Timer()", referenced from:
          _main in main.o
      "Timer::start()", referenced from:
          _main in main.o
      "Timer::reset()", referenced from:
          _main in main.o
      "Timer::getMicroSeconds()", referenced from:
          _main in main.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status
    make: *** [all] Error 1

    Zip File

    Tarball

  15. #15
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,490
    > U __ZN5Timer5startEv (in main)
    > T __ZN5Timer5startEv (in lib)
    Well that's exactly what I expected to see, but I'm stumped as to why it doesn't work.

    So I grabbed the zip, and tried it on cygwin.

    With a couple of edits to the makefile, it works.

    First I got this
    ar: libUtil.a: No such file or directory
    So I fixed the invocation of ar

    Then I got this
    main.cpp:2:19: Timer.h: No such file or directory
    So I fixed the FLAGS

    Then all was well...
    Code:
    $ make
    g++ -ansi -W -Wall -I. -c Timer.cpp
    g++ -ansi -W -Wall -I. -c main.cpp
    main.cpp:8: warning: unused parameter 'argc'
    main.cpp:8: warning: unused parameter 'argv'
    g++ -ansi -W -Wall -I. -o main -L. main.o -lUtil
    $ ./main
    123
    Time elapsed: 2653000 usecs.
    Time elapsed: 0 usecs.
    Time elapsed: 0 usecs.
    Time elapsed: 0 usecs.
    The makefile now looks like this
    Code:
    $ cat Makefile
    CC = g++
    FLAGS = -ansi -W -Wall -I.
    
    all: libUtil.a main.o
            $(CC) $(FLAGS) -o main -L. main.o -lUtil
    libUtil.a: Timer.o
            @ar crs libUtil.a Timer.o
    Timer.o: Timer.cpp Timer.h
            $(CC) $(FLAGS) -c Timer.cpp
    main.o: main.cpp
            $(CC) $(FLAGS) -c main.cpp
    Just for good measure, I did this as well
    Code:
    $ g++ main.o Timer.o
    $ ./a.exe
    234
    Time elapsed: 1582000 usecs.
    Time elapsed: 0 usecs.
    Time elapsed: 0 usecs.
    Time elapsed: 0 usecs.
    If you just link both objects, does it work?
    It might tell us whether it's a linker problem or a library problem.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. create a static library from C++ and C code
    By lehe in forum C++ Programming
    Replies: 1
    Last Post: 04-06-2009, 07:28 PM
  2. Using static libraries
    By steve1_rm in forum C++ Programming
    Replies: 5
    Last Post: 02-29-2008, 10:40 PM
  3. Replies: 4
    Last Post: 07-06-2006, 02:53 AM
  4. [GLUT] Pointers to class methods
    By cboard_member in forum C++ Programming
    Replies: 13
    Last Post: 02-16-2006, 03:03 PM
  5. Linker errors with simple static library
    By Dang in forum Windows Programming
    Replies: 5
    Last Post: 09-08-2001, 09:38 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21