From f8a94b9decf4c76c217342ce31a05ec30cfb77e8 Mon Sep 17 00:00:00 2001 From: Nikhil Marathe Date: Mon, 29 Jun 2020 01:43:00 -0700 Subject: [PATCH] Restore macOS 10.10 version compatibility to Bazel This is part of the fixes for #11442. (Not a complete fix because it does not address the bazel 2 branch). It makes the macOS deployment target 10.10. Then it wraps the calls to the macOS logging infrastructure so they only execute on macOS 10.12+. I've tested this change and a similar cherry-pick on tag 2.2.0 and confirmed this results in a functioning Bazel (at least for the targets we build) on macOS 10.10. I have questions around what I can do better: 1. I have just added a universal .bazelrc entry. Is there some way to gate this to just macOS in the Bazel infrastructure? Is that even necessary? 2. The Bazel tagged versions are just tags and not branches, which means I cannot submit a PR for a backport to Bazel 2.2. How would you like to handle this? Closes #11565. PiperOrigin-RevId: 318770522 --- .bazelrc | 4 +++ src/main/native/unix_jni_darwin.cc | 44 ++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/.bazelrc b/.bazelrc index 35e52ce3c27814..10a5a1f8a79ec5 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,3 +1,5 @@ +common --enable_platform_specific_config + # Shared configuration flags to build and test Bazel on RBE. build:remote_shared --define=EXECUTOR=remote build:remote_shared --remote_instance_name=projects/bazel-untrusted/instances/default_instance @@ -39,5 +41,7 @@ build:ubuntu1604_java8 --config=remote_shared # Alias build:remote --config=ubuntu1604_java8 +build:macos --macos_minimum_os=10.10 + # User-specific .bazelrc try-import user.bazelrc diff --git a/src/main/native/unix_jni_darwin.cc b/src/main/native/unix_jni_darwin.cc index 53088f8962e3ea..03c7958cb4a8b9 100644 --- a/src/main/native/unix_jni_darwin.cc +++ b/src/main/native/unix_jni_darwin.cc @@ -144,16 +144,34 @@ static dispatch_queue_t JniDispatchQueue() { // Log used for all of our anomaly logging. // Logging can be traced using: // `log stream -level debug --predicate '(subsystem == "build.bazel")'` +// +// This may return NULL if `os_log_create` is not supported on this version of +// macOS. Use `log_if_possible` to log when supported. static os_log_t JniOSLog() { static dispatch_once_t once_token; - static os_log_t log; - dispatch_once(&once_token, ^{ - log = os_log_create("build.bazel", "jni"); - CHECK(log); - }); + static os_log_t log = NULL; + // On macOS < 10.12, os_log_create is not available. Since we target 10.10, + // this will be weakly linked and can be checked for availability at run + // time. + if (&os_log_create != NULL) { + dispatch_once(&once_token, ^{ + log = os_log_create("build.bazel", "jni"); + CHECK(log); + }); + } return log; } +// The macOS implementation asserts that `msg` be a string literal (not just a +// const char*), so we cannot use a function. +#define log_if_possible(msg) \ + do { \ + os_log_t log = JniOSLog(); \ + if (log != NULL) { \ + os_log_debug(log, msg); \ + } \ + } while (0); + // Protects all of the g_sleep_state_* statics. // value is "leaked" intentionally because std::mutex is not trivially // destructible at this time, g_sleep_state_mutex is a singleton, and @@ -177,7 +195,7 @@ int portable_push_disable_sleep() { kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, reasonForActivity, &g_sleep_state_assertion); assert(success == kIOReturnSuccess); - os_log_debug(JniOSLog(), "sleep assertion created"); + log_if_possible("sleep assertion created"); } g_sleep_state_stack += 1; return 0; @@ -192,7 +210,7 @@ int portable_pop_disable_sleep() { IOReturn success = IOPMAssertionRelease(g_sleep_state_assertion); assert(success == kIOReturnSuccess); g_sleep_state_assertion = kIOPMNullAssertionID; - os_log_debug(JniOSLog(), "sleep assertion released"); + log_if_possible("sleep assertion released"); } return 0; } @@ -216,16 +234,14 @@ static void SleepCallBack(void *refcon, io_service_t service, break; case kIOMessageSystemWillSleep: - os_log_debug(JniOSLog(), - "suspend anomaly due to kIOMessageSystemWillSleep"); + log_if_possible("suspend anomaly due to kIOMessageSystemWillSleep"); ++state->suspend_count; // This needs to be acknowledged to allow sleep. IOAllowPowerChange(state->connect_port, (intptr_t)message_argument); break; case kIOMessageSystemWillNotSleep: - os_log_debug( - JniOSLog(), + log_if_possible( "suspend anomaly cancelled due to kIOMessageSystemWillNotSleep"); --state->suspend_count; break; @@ -284,7 +300,7 @@ int portable_suspend_count() { dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGCONT, 0, queue); CHECK(signal_source != NULL); dispatch_source_set_event_handler(signal_source, ^{ - os_log_debug(JniOSLog(), "suspend anomaly due to SIGCONT"); + log_if_possible("suspend anomaly due to SIGCONT"); ++suspend_state.suspend_count; }); dispatch_resume(signal_source); @@ -307,7 +323,7 @@ int portable_memory_pressure_warning_count() { dispatch_source_memorypressure_flags_t pressureLevel = dispatch_source_get_data(source); if (pressureLevel == DISPATCH_MEMORYPRESSURE_WARN) { - os_log_debug(JniOSLog(), "memory pressure warning anomaly"); + log_if_possible("memory pressure warning anomaly"); ++warning_count; } }); @@ -331,7 +347,7 @@ int portable_memory_pressure_critical_count() { dispatch_source_memorypressure_flags_t pressureLevel = dispatch_source_get_data(source); if (pressureLevel == DISPATCH_MEMORYPRESSURE_CRITICAL) { - os_log_debug(JniOSLog(), "memory pressure critical anomaly"); + log_if_possible("memory pressure critical anomaly"); ++critical_count; } });