[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