Jutting Bytes

Digressions of a research engineer

QMake: The Maverick's Case

| Comments

I’ve just spent hours figuring why after upgrading my Xcode to version 5, building projects using cmake goes fine while I have lots of undefined symbols using qmake. Let’s take an example.

1
2
3
4
5
6
7
8
9
10
Undefined symbols for architecture x86_64:
  "___sincos_stret", referenced from:
      _q_make in libquat.a(quat.c.o)
      _q_from_axis_angle in libquat.a(quat.c.o)
      _q_from_two_vecs in libquat.a(quat.c.o)
      _q_from_euler in libquat.a(quat.c.o)
      _q_euler_to_col_matrix in libquat.a(matrix.c.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [bin/is-calibrator] Error 1

sincos_stret looks very much like a libmath symbol, even though not defined.

1
$ nm /usr/lib/libm.dylib | c++filt | grep sincos_stret

Clang-LLVM performs system optimization, so with this very new version of Xcode, many math functions end up in libsystem_m.

1
2
$ nm /usr/lib/system/libsystem_m.dylib | c++filt | grep sincos_stret
    0000000000014143 T ___sincos_stret

However using 10.8 SDK, the latter does not contain our symbol.

1
nm /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/lib/system/libsystem_m.dylib | c++filt | grep sincos_stret

But on 10.9 SDK, here it is.

1
2
nm /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/lib/system/libsystem_m.dylib | c++filt | grep sincos_stret
    0000000000014143 T ___sincos_stret

So why don’t we touch it when linking ? Well, here is the reason. Using qmake, (whatever the version of qt, tried with 5.1.x, 5.2.x), qmake’s macx-clang spec uses MacOS 10.8 SDK. Here comes qmake -d, a nice option logging what happens behind the scenes.

1
DEBUG 1: QMAKE_MAC_SDK.macosx.path := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdK

We want to use 10.9, so that linking on math gives us our symbol definition. Overriding qmake’s mac sdk is not something you easily find in the (however brilliant) qt docsets. If the debug output gives us some hints, we also want to set the deployment target flag. The project file snippet is as follows.

1
2
macx:QMAKE_MAC_SDK.macosx.path = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdK
macx:QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9

Enjoy and save some time!


Comments