Question

I'm trying to link a Qt program I have cross-compiled for a MacOS target on a Linux host. I followed the instructions found here (https://github.com/Tatsh/xchain) to succesfully build gcc, and I can compile and link both simple test programs as on that page to produce executables which run fine on MacOS.

I have built my own Qt from source using this gcc, and I can compile my Qt program without a hitch. The problem comes at the linking stage, when the object files of my program should be linked to the Qt libs, it almost seems as if the Qt libs can't be found at all, or are ignored because they are somehow incompatible.

The object files of my program and the Qt libs I built both seem to be ok:

$ file MainWindow.o
MainWindow.o: Mach-O object i386

$ file /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib.4.8.2
/usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib.4.8.2: Mach-O dynamically linked shared library i386

The g++ invocation goes like this:

$ i686-apple-darwin10-g++ -o myapp.app/Contents/MacOS/myapp 
     main.o MainWindow.o ... 
     -L/usr/local/myqt/mac32/Qt-4.8.2/lib -lQtCore -lQtGui ...

Of course there are many more object files and many more Qt libs, I have left them out for brevity.

The errors I get are typical of simply not adding an object or lib to the command line, for example:

...
  "QMainWindow::event(QEvent*)", referenced from:
      vtable for MainWindowin moc_MainWindow.o
  "QDir::~QDir()", referenced from:
      _main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

and it seems that basically every Qt lib is not being found.

I have also tried specifying the lib files directly instead of the -L/path and -lQtFoo combo, and I even tried renaming them from .dylib to .so :)

If I run g++ with -v to see the linker call, then also add -v to that, I can see that the paths being checked for libs look ok:

$ i686-apple-darwin10-ld64 -dynamic -arch i386 -headerpad_max_install_names 
     -macosx_version_min 10.4 -syslibroot /usr/i686-apple-darwin10 
     -weak_reference_mismatches non-weak -o myapp.app/Contents/MacOS/myapp
     -lcrt1.o /usr/i686-apple-darwin10/SDKs/MacOSX10.6.sdk/usr/bin/../lib/gcc/i686-apple-darwin10/4.2.1/crt3.o 
     main.o MainWindow.o 
     ... 
     -L/usr/local/myqt/mac32/Qt-4.8.2/lib -lQtCore -lQtGui ...
     -v
@(#)PROGRAM:ld64  PROJECT:odcctools-622.3od16
Library search paths:
    /usr/local/myqt/mac32/Qt-4.8.2/lib
    /usr/i686-apple-darwin10/usr/X11/lib
    /usr/local/myqt/mac32/Qt-4.8.2/lib
    /usr/i686-apple-darwin10/usr/lib/i686-apple-darwin10/4.2.1
    /usr/i686-apple-darwin10/usr/lib
    /usr/i686-apple-darwin10/SDKs/MacOSX10.6.sdk/usr/lib/gcc/i686-apple-darwin10/4.2.1
    /usr/i686-apple-darwin10/SDKs/MacOSX10.6.sdk/usr/lib/gcc
    /usr/i686-apple-darwin10/usr/lib/gcc/i686-apple-darwin10/4.2.1
    /usr/i686-apple-darwin10/SDKs/MacOSX10.6.sdk/usr/i686-apple-darwin10/lib
    /usr/i686-apple-darwin10/SDKs/MacOSX10.6.sdk/usr/i686-apple-darwin10/lib
    /usr/i686-apple-darwin10/usr/lib
    /usr/local/lib
Framework search paths:
    /usr/i686-apple-darwin10/Library/Frameworks/
    /usr/i686-apple-darwin10/System/Library/Frameworks/

The lib location and setup looks ok:

$ ls -lh /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib*
lrwxrwxrwx. 1 root root   21 Aug  7 05:22 /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib -> libQtCore.dylib.4.8.2
lrwxrwxrwx. 1 root root   21 Aug  7 05:22 /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib.4 -> libQtCore.dylib.4.8.2
lrwxrwxrwx. 1 root root   21 Aug  7 05:22 /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib.4.8 -> libQtCore.dylib.4.8.2
-rwxr-xr-x. 1 root root 2.7M Aug  7 05:22 /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib.4.8.2

The lib contents also seem to be ok, but I am not too familiar with this part... actually I just discovered 'nm' on another question here just now.

$ i686-apple-darwin10-nm /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtGui.dylib.4.8.2 | grep event
     U __ZN16QCoreApplication5eventEP6QEvent
     U __ZN16QEventTransition5eventEP6QEvent
     U __ZN16QEventTransition9eventTestEP6QEvent
     U __ZN17QVariantAnimation5eventEP6QEvent
     U __ZN19QAbstractTransition5eventEP6QEvent
     U __ZN23QCoreApplicationPrivate15eventDispatcherE
     U __ZN7QObject11eventFilterEPS_P6QEvent
     U __ZN7QObject5eventEP6QEvent

I am also not too familiar with 'name mangling', but I get the feeling it may have something to do with this.

It has been quite a long journey so far with this whole cross-compiling thing, so it sucks to be this close to the end and hit something that really stumps me this much - any advice would be greatly appreciated!

** EDIT ***

I found that if I take out the -dynamic flag for the ld64 call, different function names are shown as missing. For example the missing reference to "QMainWindow::event(QEvent*)" mentioned above becomes:

  "__ZN11QMainWindow5eventEP6QEvent", referenced from:
      __ZTV10MainWindow in moc_MainWindow.o

And now I can see that these names are indeed, NOT found in the Qt libs I built (configuration issue...?). This didn't enlighten me much as to what should be done to fix the problem, but perhaps it might give somebody else a clue.

Was it helpful?

Solution 2

I managed to get past this problem, although without totally understanding the details of it. Originally I had these two lines in the mkspecs file and although they did not cause any errors when building Qt, commenting them out fixed the problem:

QMAKE_RANLIB    = i686-apple-darwin10-ranlib
QMAKE_STRIP     = i686-apple-darwin10-strip

I had set these to the cross-compiler executables like this thinking it was necessary, but it seems that everything in the tool-chain is taken care of simply by specifying the correct gcc and g++.

OTHER TIPS

I don't have a full answer for you, but I can tell you that the 'U' in your nm output means the symbol is not defined in that executable (or library in this case) but is expected to be defined in an externally linked library, suggesting that something may actually be wrong with that library.

As a side note, you can use the -C argument to nm to have it demangle your C++ symbols.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top