Compiling on x86_64 with external libraries

Discussion in 'Mac Programming' started by nh12, Aug 29, 2011.

  1. macrumors newbie

    Joined:
    Aug 29, 2011
    #1
    I just started using a 64-bit Mac Pro with Mac OS X Lion 10.7.1 and I can't seem to compile any c/c++ code that uses external libraries. I downloaded and built Googles libkml and also a file writing package called hdf5. Both are apparently built properly (the example code even works for the libkml stuff?!?), but when I try to write a simple program that includes the necessary libraries, I get an error like this:


    Code:
    bash-3.2$ gcc -I /opt/local/include hdf5test.cc -o hdf5test
    Undefined symbols for architecture x86_64:
      "_H5check_version", referenced from:
          _main in ccLZ5OT5.o
      "_H5Fcreate", referenced from:
          _main in ccLZ5OT5.o
      "_H5Fclose", referenced from:
          _main in ccLZ5OT5.o
    ld: symbol(s) not found for architecture x86_64
    collect2: ld returned 1 exit status
    My code is very simple:

    Code:
    #include "hdf5.h"
    #define FILE "file.h5"
    
    int main()
    {
      hid_t file_id;  // file identifier                                                          
      herr_t status;
    
      file_id = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
      status = H5Fclose(file_id);
    
      return 0;
    }
    where hdf5.h is a header file that came with the hdf5 package. I have tried adding options like -m64 and others, but nothing seems to work. What boggles my mind is that when I built libkml (different from the example I give above), the example programs that were compiled with the build actually work; however if I copy and paste them to my own directory they give me the same error message given above.

    Any help/guidance/wisdom would be greatly appreciated. Thanks,

    Nate
     
  2. macrumors 603

    Joined:
    Aug 9, 2009
    #2
    It looks like the library you're linking to doesn't have an x86_64 arch in it.

    Or you're not linking to a library at all: -I only specifies a location for includes. It doesn't specify an external library.

    See man gcc
     
  3. thread starter macrumors newbie

    Joined:
    Aug 29, 2011
    #3
    Okay, if I add the option -L /opt/local/lib, where all of the relevant .a and .dylib files appear to be, I get the same error. Is this what you meant?
     
  4. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #4
    So far you've said to compiler where to find header files -I (uppercase I) and the library files -L (uppercase L), but you haven't said which library files to link against. You need to add a -l (lowercase L) option for each library file you want to link against.

    Assuming the there's a libkml.dylib and a libhdf5.dylib in /opt/local/lib, the command to compile would be something like:
    Code:
    g++ -I /opt/local/include -L /opt/local/lib -l kml -l hdf5 -o hdf5test hd5test.cc
     
  5. macrumors 603

    Joined:
    Aug 9, 2009
    #5
    To find out what arch's are in your external libraries, use the file command on them:
    Code:
    file /path/to/libfoo.a
    
    If it doesn't show x86_64, then that's the problem. Either way, post the actual output, so we know exactly what you're seeing.
     
  6. macrumors 6502a

    Joined:
    Jan 15, 2007
    #6
    Actually for .a files, file gives you almost no info(it will give you info for executables and IIRC dyilibs, but not static libraries)

    To get the archs you can use the lipo command instead

    lipo -info /path/to/libfoo.a
     
  7. thread starter macrumors newbie

    Joined:
    Aug 29, 2011
    #7
    Okay, thanks for all the responses.

    Here are the results for file and lipo for a small selection of the library files:


    Code:
    bash-3.2$ file libhdf5.dylib
    libhdf5.dylib: Mach-O 64-bit dynamically linked shared library x86_64
    bash-3.2$ lipo -info libhdf5.a
    input file libhdf5.a is not a fat file
    Non-fat file: libhdf5.a is architecture: x86_64
    bash-3.2$ file libhdf5.la
    libhdf5.la: libtool library file

    Per the comment:

    Do I need to -l ALL of the libraries? This seems like it could get unwieldy pretty quickly. For the hdf5 case, here is a list of the related files in the /opt/local/lib directory:


    Code:
    libhdf5.7.dylib         libhdf5.settings        libhdf5_cpp.la          libhdf5_hl.la           libhdf5_hl_cpp.la
    libhdf5.a               libhdf5_cpp.7.dylib     libhdf5_hl.7.dylib      libhdf5_hl_cpp.7.dylib
    libhdf5.dylib           libhdf5_cpp.a           libhdf5_hl.a            libhdf5_hl_cpp.a
    libhdf5.la              libhdf5_cpp.dylib       libhdf5_hl.dylib        libhdf5_hl_cpp.dylib

    Do I need to -l all of these files? Thanks again for all of the quick comments.

    Nate
     
  8. jiminaus, Aug 30, 2011
    Last edited: Aug 30, 2011

    macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #8
    I can see that there's really only 4 libraries here: hdf5, hdf5_cpp, hdf5_hl, hdf5_hl_cpp. There are dynamic (.dylib, .la) and static (.a) variants of each. And there are version specific names (*.7.dylib), which I would guess the non-version specific names symlink to.

    Quote from the HDF5 documentation:
    And I would guess then that hdf5_hl_cpp is the C++ High Level APIS.

    You only need to link to the necessary library/libraries. Just start by linking to hdf5. If that don't satisfy the compiler, try linking in additional libraries.


    EDIT: BTW You might want to read Compiling your HDF5 Applications. The h5cc and h5c++ programs should have been installed into /opt/local/bin.
     
  9. thread starter macrumors newbie

    Joined:
    Aug 29, 2011
    #9
    Great, thank you. I can now compile my simple test code, thanks in part to your suggestion to look at the "compiling your hdf5 applications" documentation. Here is what worked via the command line:

    Code:
    bash-3.2$ g++ -pipe -02 -I /opt/local/include -L /opt/local/lib -lhdf5 hdf5test.cc -o hdf5test
    Similarly, my libkml test code was compiled via command line:

    Code:
    bash-3.2$ g++ -pipe -02 -I /opt/local/include -L /opt/local/lib -lkmldom kmltest.cc -o kmltest
    I suppose it may be irrelevant now, but I still don't understand why the fact that I wasn't telling the linker which libraries to link against generated an error message that seemed to imply an issue with the architecture...?

    Again, thank you so much for your help!

    Nate
     
  10. macrumors 603

    Joined:
    Aug 9, 2009
    #10
    I don't think the message was implying there was an architecture issue. I think it was simply telling you some added details.

    You may have inferred it was an arch issue, but I don't see why. The message plainly starts with the words Undefined symbols, so that seems like the primary issue to me. Naming the arch is simply an added detail, though a welcome one in my opinion.

    On gcc versions thru 10.6, the only way I know to get it to output the architecture is when there are multiple arch names in a single command, e.g.:
    Code:
    gcc -arch i386 -arch x86_64 something.c
    
    Maybe that was changed in your gcc version. Post the output of:
    Code:
    gcc --version
    
    Mine says 4.2.1.


    Here's the sample code I used:
    Code:
    #include <stdio.h>
    
    extern int notDefined;
    
    int main( int arcgc, char *argv[] )
    {
    	printf( "Undefined %d\n", notDefined );
    }
     
  11. macrumors 6502a

    Joined:
    Jan 15, 2007
    #11
    I think because the whole thing says xxx not defined for architecture yyy

    However, there is a simple way to determine whether or not its an architecture issue(MOST of the time), look for the following warning:

    ld: warning: in .//libthirtytwo.a, file is not of required architecture

    (libthirtytwo.a is a library i created to experiment with this)

    if you see that, it tells you that the linker sees a library file but that library file is not the same architecture that is being compiled.(if you are compiling for multiple architectures and the library contains at least those architectures you will not get the warning)
     
  12. thread starter macrumors newbie

    Joined:
    Aug 29, 2011
    #12
    Okay, I suppose we can mark this up as a simple lack of experience on my part. I completely misinterpreted the meaning of the error message which led me down a wild goose chase in terms of Google (actually Yahoo) searches. Lesson learned. Thanks for all of the help!
     

Share This Page