Darwin: Refactor stack startup logic when creating a controller (#32845)

* Darwin: Don't stop/start the stack when creating a controller

* Keep refactorings in place but retain current behavior for now

* Darwin: Enable CHIP_CONFIG_GLOBALS_NO_DESTRUCT=1

This was missed in #32745 when adding -fno-c++-static-destructors, since that
flag does not carry through to lazily initialized chip::Global instances.
diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm
index 22d52cd..961b6f8 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceController.mm
+++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm
@@ -139,25 +139,15 @@
 {
     if (![parameters isKindOfClass:MTRDeviceControllerParameters.class]) {
         MTR_LOG_ERROR("Unsupported type of MTRDeviceControllerAbstractParameters: %@", parameters);
-
         if (error) {
             *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT];
         }
         return nil;
     }
+    auto * controllerParameters = static_cast<MTRDeviceControllerParameters *>(parameters);
 
-    __auto_type * factory = [MTRDeviceControllerFactory sharedInstance];
-    if (!factory.isRunning) {
-        auto * params = [[MTRDeviceControllerFactoryParams alloc] initWithoutStorage];
-
-        if (![factory startControllerFactory:params error:error]) {
-            return nil;
-        }
-    }
-
-    auto * parametersForFactory = static_cast<MTRDeviceControllerParameters *>(parameters);
-
-    return [factory initializeController:self withParameters:parametersForFactory error:error];
+    // MTRDeviceControllerFactory will auto-start in per-controller-storage mode if necessary
+    return [MTRDeviceControllerFactory.sharedInstance initializeController:self withParameters:controllerParameters error:error];
 }
 
 - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory
diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm
index 5941a79..b31003c 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm
+++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm
@@ -417,7 +417,14 @@
     return [NSArray arrayWithArray:fabricList];
 }
 
-- (BOOL)startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams error:(NSError * __autoreleasing *)error;
+- (BOOL)startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams error:(NSError * __autoreleasing *)error
+{
+    return [self _startControllerFactory:startupParams startingController:NO error:error];
+}
+
+- (BOOL)_startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams
+             startingController:(BOOL)startingController
+                          error:(NSError * __autoreleasing *)error
 {
     [self _assertCurrentQueueIsNotMatterQueue];
 
@@ -535,6 +542,7 @@
         // state is brought up live on factory init, and not when it comes time
         // to actually start a controller, and does not actually clean itself up
         // until its refcount (which starts as 0) goes to 0.
+        // TODO: Don't cause a stack shutdown and restart if startingController
         _controllerFactory->RetainSystemState();
         _controllerFactory->ReleaseSystemState();
 
@@ -597,11 +605,6 @@
 {
     [self _assertCurrentQueueIsNotMatterQueue];
 
-    if (![self checkIsRunning:error]) {
-        MTR_LOG_ERROR("Trying to start controller while Matter controller factory is not running");
-        return nil;
-    }
-
     id<MTRDeviceControllerStorageDelegate> _Nullable storageDelegate;
     dispatch_queue_t _Nullable storageDelegateQueue;
     NSUUID * uniqueIdentifier;
@@ -623,9 +626,28 @@
         otaProviderDelegateQueue = nil;
     } else {
         MTR_LOG_ERROR("Unknown kind of startup params: %@", startupParams);
+        if (error != nil) {
+            *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT];
+        }
         return nil;
     }
 
+    if (![self isRunning]) {
+        if (storageDelegate != nil) {
+            MTR_LOG_DEFAULT("Auto-starting Matter controller factory in per-controller storage mode");
+            auto * params = [[MTRDeviceControllerFactoryParams alloc] initWithoutStorage];
+            if (![self _startControllerFactory:params startingController:YES error:error]) {
+                return nil;
+            }
+        } else {
+            MTR_LOG_ERROR("Trying to start controller while Matter controller factory is not running");
+            if (error != nil) {
+                *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE];
+            }
+            return nil;
+        }
+    }
+
     if (_usingPerControllerStorage && storageDelegate == nil) {
         MTR_LOG_ERROR("Must have a controller storage delegate when we do not have storage for the controller factory");
         if (error != nil) {
diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj
index 1e54062..80c451c 100644
--- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj
+++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj
@@ -2256,6 +2256,7 @@
 				OTHER_CPLUSPLUSFLAGS = (
 					"$(OTHER_CFLAGS)",
 					"-fno-c++-static-destructors",
+					"-DCHIP_CONFIG_GLOBALS_NO_DESTRUCT=1",
 				);
 				OTHER_LDFLAGS = "";
 				"OTHER_LDFLAGS[sdk=*]" = (
@@ -2421,6 +2422,7 @@
 				OTHER_CPLUSPLUSFLAGS = (
 					"$(OTHER_CFLAGS)",
 					"-fno-c++-static-destructors",
+					"-DCHIP_CONFIG_GLOBALS_NO_DESTRUCT=1",
 				);
 				OTHER_LDFLAGS = "";
 				"OTHER_LDFLAGS[sdk=*]" = (