1

I'm trying to compile a program on MAC OSX, originally written on the Linux OS. It is a big program with several makefiles. I have been working on it for weeks and now cannot seem to figure out why is causing undefined symbols errors. There is one overarching Makefile that calls upon the other makefiles so that the order of compilation is correct.

When you compile, it creates static libraries as well as multiple applications. Because this guys is so huge, the program creates these static libraries (.a files) first. Then when it compiles the source code specifically for the application, it links the static libraries. (hopefully that wasn't too confusing) .

I can get past the building of the static libraries just fine, but once i reach the point when the application is getting built, i receive tons, of undefined symbol errors telling me, for example

Undefined symbols: "_bagUpdateOptSurface", referenced from: _dbv_bag in libdbdbv6.a(dbv_bag.o)

When i check dbv_bag.o with nm, i get a lot of functions that are undefined with the header U .

i can trace back this function with nm and find that ...

bagUpdateOptSurface.c -->bagUpdateOptSurface.o -->libbag.a --->dbv_bag.c --->dbv_bag.o --->libdbdv6.a --->application

the function is defined through the static library libbag.a with the header T, but the object file dbb_bag.o has it as undefined with U. Somewhere in there the information is lost and i cannot seem to understand why.

if someone out there with more experience porting programs to mac can help shed some light on what is going on, i would very much grateful. Any ideas right or wrong, is welcome.

thanks in advance

Stanislav Pankevich
  • 11,044
  • 8
  • 69
  • 129
  • This looks very similar to the behavior that I am seeing (also porting a rather big Linux project to macOS). I have not found a solution but could create a minimal example: https://stackoverflow.com/questions/59687933/linking-a-dynamic-library-that-links-in-symbols-from-a-static-library-macos-vs. – Stanislav Pankevich Jan 11 '20 at 07:49

1 Answers1

0

Just out of curiosity, have you tried using gcc or g++ for linking instead of ld? Often these large projects use makefiles with defined variables and you can just say make LD=gcc target or some such thing.

Lots of "U" flags don't matter as long as there is a "T" version.

You might try producing a trivial example. Just a few short 1 or 2 line source files, compile to .o (with -c flag), put in libraries (ar -rv), and see if you can reproduce the problem. Once simplified, answers are often easier to find.

If it's not a linker flag problem, it may be an ordering problem (dependency hell) on the linking line. Or you may just be missing a library somewhere.

I suppose I should also inquire what version of gcc/g++ you are using, and what version of OSX...

Another possibility would be accidentally overloading functions with g++, and possibly different header signatures from the implementation.

You might try removing all .o and library files and recompiling the world (everything). Sometimes a .o file (or library) gets out of date from the source/header files and causes really ungodly amounts of pain and suffering...



Responding to comments:

As mentioned, though buried, above: Often problems like this refer to dependency hell and link ordering on the command line. At least they used to. I'm not sure if that's still the case.

You might copy the directory over, strip out as much code as you can (binary search debugging), make a trivial example, and the problem usually becomes easier to identify.

Linking with gcc/g++: You can compile file.c to file.o via gcc -c and then subsequently link file.o into an executable via ld. Or you can do gcc file.o -o file invoking gcc which will in turn invoke ld with the appropriate arguments. It's useful sometimes if you're not quite sure of the libraries you need, or the flags you need to pass into ld.

Gcc 4.2.1 and OSX 10.6.8 shouldn't be a problem. I was just curious if you were using something really outdated, as older compilers had interesting drawbacks/issues.

Although, now that I think about it, what compiler were you using to compile under Linux? It's possible you are using a newer/older gcc/g++ compiler under OSX, and your problems stem from "improvements" to the compiler.

Overloading functions: Gcc/g++ often determine C vs C++ compilation based on the filename suffix. OSX usually has a case insensitive filesystem. So gcc file.c and g++ file.C would both work regardless of whether the file is named file.c or file.C. However, there are differences in the C and C++ languages that could bite you. For example, if you defined foo(signed int) the type information would be incorporated (mangled) into the compiled function name under C++ compilation. Subsequently calling it from C code would not necessarily work (link properly).

Similarly if the header file says foo(short int) and the source code says foo(long int) you can get into interesting problems.

TooLazyToLogIn
  • 284
  • 2
  • 3
  • can you elaborate on what you mean by using gcc or g++ for linking? i didnt know that there are other options besides ld to use as linking. – user1483294 Nov 05 '12 at 17:22
  • sorry accidently clicked on "Enter" before finishing. oh and the gcc version is 4.2.1 and the OSX is 10.6.8. One more request , can you elaborate on overloading functions and different header signatures from the implementation? – user1483294 Nov 05 '12 at 17:26