Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

nh12

macrumors newbie
Original poster
Aug 29, 2011
5
0
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
 
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
 
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?
 
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
 
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.
 
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.

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
 
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:

You need to add a -l (lowercase L) option for each library file you want to link against.

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
 
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?

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:
libhdf5 - HDF5 C Library
libhdf5_cpp - HDF5 C++ APIs (if included)
libhdf5_hl - HDF5 High Level APIs (if included)

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.
 
Last edited:
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
 
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...?

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 );
}
 
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 );
}

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)
 
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!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.