macOS 10.12 introduced support for clock_gettime() but when compiling
with Xcode 8 (or later) and targeting 10.11 (or older) the clock_gettime
symbol is now found at configure/compile time but referenced weakly.
Running the created binary on 10.11 results in a "dyld: lazy symbol
binding failed: Symbol not found: _clock_gettime" error.
This drama has played out across other projects:
- https://github.com/Homebrew/homebrew-core/issues/2674
- https://github.com/curl/curl/issues/1069
- https://svn.filezilla-project.org/filezilla?view=revision&revision=7824OO
- https://github.com/mesonbuild/meson/pull/949
- https://github.com/Homebrew/homebrew-core/issues?utf8=%E2%9C%93&q=label%3Aclock_gettime%20
Options for working around this issue include:
1. Turn references to functions that might be weak into compilation
errors (-Werror=partial-availability).
2. Disable visibility of functions that might be weak at compile link
time (-Wl,-no_weak_imports).
3. Change configure tests to directly check the targeted OSX version and
fail the test if it is too old to have the required function.
4. Make an empty function declaration marked with
__attribute__((weak_import)) that is used if the symbol would
otherwise be unavailable. It is then possible to check if the symbol
is NULL at runtime to determine availability.
This commit does 2. when targeting the Darwin platform after checking if
the compiler/linker work with that option. It also changes the clockid_t
configure test to no longer use clock_gettime() because targeting OSX
10.11 when using the 10.12 SDK results in having the clockid_t typedef
without having the clock_gettime function. The combination of these
fixes should solve https://github.com/axboe/fio/issues/305 .
Signed-off-by: Sitsofe Wheeler <sitsofe@yahoo.com>
if test -z "$cpu" && test "$(sysctl -n hw.optional.x86_64)" = "1"; then
cpu="x86_64"
fi
if test -z "$cpu" && test "$(sysctl -n hw.optional.x86_64)" = "1"; then
cpu="x86_64"
fi
+ # Error at compile time linking of weak/partial symbols if possible...
+cat > $TMPC <<EOF
+int main(void)
+{
+ return 0;
+}
+EOF
+ if compile_prog "" "-Wl,-no_weak_imports" "disable weak symbols"; then
+ echo "Disabling weak symbols"
+ LDFLAGS="$LDFLAGS -Wl,-no_weak_imports"
+ fi
;;
SunOS)
# `uname -m` returns i86pc even on an x86_64 box, so default based on isainfo
;;
SunOS)
# `uname -m` returns i86pc even on an x86_64 box, so default based on isainfo
# clockid_t probe
clockid_t="no"
cat > $TMPC << EOF
# clockid_t probe
clockid_t="no"
cat > $TMPC << EOF
-#include <stdio.h>
-#include <string.h>
#include <time.h>
int main(int argc, char **argv)
{
#include <time.h>
int main(int argc, char **argv)
{
+ volatile clockid_t cid;
memset(&cid, 0, sizeof(cid));
memset(&cid, 0, sizeof(cid));
- return clock_gettime(cid, NULL);
}
EOF
if compile_prog "" "$LIBS" "clockid_t"; then
}
EOF
if compile_prog "" "$LIBS" "clockid_t"; then