Skip to content

Commit f3c7f77

Browse files
committed
features_cpu, rcheevos: shim clock_gettime on pre-10.12 macOS
clock_gettime() was added to Darwin in macOS 10.12 Sierra / iOS 10.0 (2016). On Leopard (10.5) and every other pre-10.12 macOS target, the symbol doesn't exist in libSystem and the link fails: undefined reference to 'clock_gettime' Two call sites in the current build: libretro-common/features/features_cpu.c: Already has an ra_clock_gettime shim that falls back to gettimeofday(), but the gate is iOS-only: #if __IPHONE_OS_VERSION_MIN_REQUIRED < 100000 On macOS the shim is bypassed and ra_clock_gettime is #define'd to clock_gettime, producing the link error. FIX: introduce RA_NEEDS_CLOCK_GETTIME_SHIM defined when either iOS deployment target < 10.0 or macOS deployment target < 10.12, and use that flag instead of the iOS-only check. Add the required #include <AvailabilityMacros.h>. deps/rcheevos/src/rc_client.c: Direct call in rc_client_clock_get_now_millisecs(), guarded by #if defined(CLOCK_MONOTONIC). The function has a perfectly good #else fallback using clock()+time(). FIX: #undef CLOCK_MONOTONIC at file scope on pre-10.12 macOS so the function's #if cascade falls through to the clock()+time() path. <time.h> is transitively included through rc_api_info.h at the top of the file, so the #undef takes effect. No rcheevos logic changed - this is a preprocessor-level selector flip. Both gates use MIN_REQUIRED (deployment target) rather than MAX_ALLOWED (SDK version). That's correct here: Apple weak-links clock_gettime when the deployment target is < 10.12, even when compiling against a modern SDK where the declaration is visible. The question is "can this binary run on a pre-10.12 system," which is exactly what MIN_REQUIRED answers. audio/librsound.c's clock_gettime call is already fenced behind a __MACH__ check that routes macOS through host_get_clock_service instead, so no change needed there. No behavioral change on 10.12+ macOS, iOS 10.0+, or any other platform: the shim is only compiled in when the deployment target predates those versions.
1 parent f8774b4 commit f3c7f77

2 files changed

Lines changed: 33 additions & 5 deletions

File tree

deps/rcheevos/src/rc_client.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@
2121
#endif
2222
#endif
2323

24+
/* clock_gettime() was added to Darwin in iOS 10.0 / macOS 10.12. On
25+
* earlier deployment targets the symbol doesn't exist in libSystem
26+
* and rc_client_clock_get_now_millisecs() below fails to link.
27+
* Disable the CLOCK_MONOTONIC branch there so the function falls
28+
* through to the clock()+time() #else fallback. MIN_REQUIRED is
29+
* the deployment target - what the binary must be able to run on -
30+
* which is the right version to gate on here. */
31+
#if defined(__APPLE__) && defined(__MACH__)
32+
#include <AvailabilityMacros.h>
33+
#if (defined(MAC_OS_X_VERSION_MIN_REQUIRED) \
34+
&& MAC_OS_X_VERSION_MIN_REQUIRED < 101200) \
35+
|| (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) \
36+
&& __IPHONE_OS_VERSION_MIN_REQUIRED < 100000)
37+
#ifdef CLOCK_MONOTONIC
38+
#undef CLOCK_MONOTONIC
39+
#endif
40+
#endif
41+
#endif
42+
2443
#define RC_CLIENT_UNKNOWN_GAME_ID (uint32_t)-1
2544
#define RC_CLIENT_RECENT_UNLOCK_DELAY_SECONDS (10 * 60) /* ten minutes */
2645

libretro-common/features/features_cpu.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
/* iOS/OSX specific. Lacks clock_gettime(), so implement it. */
116116
#ifdef __MACH__
117117
#include <sys/time.h>
118+
#include <AvailabilityMacros.h>
118119

119120
#ifndef CLOCK_MONOTONIC
120121
#define CLOCK_MONOTONIC 0
@@ -124,10 +125,18 @@
124125
#define CLOCK_REALTIME 0
125126
#endif
126127

127-
/**
128-
* TODO/FIXME: clock_gettime function is part of iOS 10 now
129-
**/
130-
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 100000
128+
/* clock_gettime() was added in iOS 10.0 / macOS 10.12 Sierra.
129+
* On deployment targets below those versions the symbol doesn't
130+
* exist in libSystem and the link fails, so fall back to a
131+
* gettimeofday() shim. Gated on MIN_REQUIRED (deployment target)
132+
* rather than MAX_ALLOWED (SDK) because the binary needs to run on
133+
* the deployment target, and Apple weak-links clock_gettime when
134+
* targeting < 10.12 even from a newer SDK. */
135+
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) \
136+
&& __IPHONE_OS_VERSION_MIN_REQUIRED < 100000) \
137+
|| (defined(MAC_OS_X_VERSION_MIN_REQUIRED) \
138+
&& MAC_OS_X_VERSION_MIN_REQUIRED < 101200)
139+
#define RA_NEEDS_CLOCK_GETTIME_SHIM 1
131140
static int ra_clock_gettime(int clk_ik, struct timespec *t)
132141
{
133142
struct timeval now;
@@ -141,7 +150,7 @@ static int ra_clock_gettime(int clk_ik, struct timespec *t)
141150
#endif
142151
#endif
143152

144-
#if defined(__MACH__) && __IPHONE_OS_VERSION_MIN_REQUIRED < 100000
153+
#if defined(__MACH__) && defined(RA_NEEDS_CLOCK_GETTIME_SHIM)
145154
#else
146155
#define ra_clock_gettime clock_gettime
147156
#endif

0 commit comments

Comments
 (0)