[CMake] False positives with CheckFunctionExists and dynamic linking

Louis Opter louis at opter.org
Tue Oct 4 22:12:33 EDT 2016


Hello,

My laptop is running on Mac OS 10.11 with the latest Xcode 8 release.

This version of Xcode ships the Mac OS 10.12 API/SDKs which includes
the clock_gettime function which I check for availability using
check_function_exists.

Even though clock_gettime doesn’t exist on Mac OS 10.11,
check_function_exists successfully finds it because clock_gettime is
defined in headers, and is then dynamically linked. So, try_compile
works but the executable simply can’t run:

---8<---

tessa:0:/tmp/louis/tmp% xcodebuild -version ; sw_vers -productVersion
Xcode 8.0
Build version 8A218a
10.11.6
tessa:0:/tmp/louis/tmp% clang -Wall -Wextra -o test test.c
tessa:0:/tmp/louis/tmp% ./test
dyld: lazy symbol binding failed: Symbol not found: _clock_gettime
  Referenced from: /private/tmp/louis/tmp/./test (which was built for Mac OS X 10.12) Expected in: /usr/lib/libSystem.B.dylib

dyld: Symbol not found: _clock_gettime
  Referenced from: /private/tmp/louis/tmp/./test (which was built for Mac OS X 10.12) Expected in: /usr/lib/libSystem.B.dylib

zsh: trace trap (core dumped)  ./test
tessa:0:/tmp/louis/tmp% cat test.c
#include <time.h>

int
main(void)
{
    struct timespec tp;
    return clock_gettime(CLOCK_MONOTONIC, &tp);
}
tessa:0:/tmp/louis/tmp% 

--->8---

(clang is shipped with Xcode).

IMO, it’s an issue on Apple side, I don’t even know why it’s building
10.12 executables while I’m running 10.11, this broke on me when Xcode
upgraded itself and I didn’t configure anything.

I have worked around the issue by forcing static linking for that
particular function before calling check_function_exists:

---8<---

IF (APPLE)
    # Hopefully my intuition is right and this fixes false positives on
    # mac os < 10.12 with X Code >= 8 (where clock_gettime is defined
    # in the SDKs but actually doesn't exists so dyld blows up at run
    # time).
    # -u symbol_name
    #         Specified that symbol symbol_name must be defined for the
    #         link to succeed.  This is useful to force selected
    #         functions to be loaded from a static library.
    SET(CMAKE_REQUIRED_FLAGS "-Wl,-u=clock_gettime")
ENDIF ()

--->8---

This fix works for me, but it doesn’t feel like a very durable nor
generic solution to the problem.

I wonder if we could something in CMake to handle that weird aspect of
Mac OS.

I can’t think of anything better than the linker flag I used to solve
the problem.

Best

-- 
Louis Opter


More information about the CMake mailing list