summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@lindenlab.com>2026-06-17 11:46:23 -0400
committerGitHub <noreply@github.com>2026-06-17 11:46:23 -0400
commit34c308ebdb219c8c3e5cdc5a1192db8a51ef0c44 (patch)
treeb4323eb1fe5ac13ca6e5227a10056779e9f35b01 /indra
parentdace31455ca4b382f94a03d3c7c244d805bd85fd (diff)
macOS 27 build fixes + transition to UTType for file pickers (#5937)
* Get the viewer building on macOS 27 * Strip -mmacosx-version-min when we're below an SDK supported version. Substitutes an actual SDK supported minimum version. * Move kIOMainPortDefault behind an SDK compatibility check. * Update llwindowmacosx_iokit.h * Update llwindowmacosx_iokit.h
Diffstat (limited to 'indra')
-rw-r--r--indra/cmake/00-Common.cmake11
-rw-r--r--indra/cmake/Linking.cmake2
-rw-r--r--indra/cmake/Variables.cmake33
-rw-r--r--indra/llwindow/CMakeLists.txt1
-rw-r--r--indra/llwindow/llwindowmacosx.cpp4
-rw-r--r--indra/llwindow/llwindowmacosx_iokit.h35
-rw-r--r--indra/newview/llappviewermacosx.cpp3
-rw-r--r--indra/newview/llfilepicker_mac.mm63
-rw-r--r--indra/newview/llmachineid.cpp4
9 files changed, 140 insertions, 16 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 99ea22ab4b..72347446b9 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -18,6 +18,17 @@ include(Variables)
# We go to some trouble to set LL_BUILD to the set of relevant compiler flags.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}")
+
+if (DARWIN)
+ # LL_BUILD carries a literal -mmacosx-version-min=<ver> from
+ # viewer-build-variables. We derive the macOS deployment target in
+ # Variables.cmake (clamping up to the SDK's supported minimum when needed)
+ # and let CMAKE_OSX_DEPLOYMENT_TARGET emit the flag to both compiler and
+ # linker. Strip the verbatim flag here so it can't conflict with the
+ # clamped deployment target.
+ string(REGEX REPLACE "-mmacosx-version-min=[0-9.]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+endif (DARWIN)
+
# Given that, all the flags you see added below are flags NOT present in
# https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables.
# Before adding new ones here, it's important to ask: can this flag really be
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index 900a64e2dd..5d4e8d8634 100644
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -77,6 +77,7 @@ else()
find_library(COREAUDIO_LIBRARY CoreAudio)
find_library(COREGRAPHICS_LIBRARY CoreGraphics)
find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox)
+ find_library(UNIFORMTYPEIDENTIFIERS_LIBRARY UniformTypeIdentifiers)
target_link_libraries( ll::oslibraries INTERFACE
${COCOA_LIBRARY}
@@ -87,6 +88,7 @@ else()
${COREAUDIO_LIBRARY}
${AUDIOTOOLBOX_LIBRARY}
${COREGRAPHICS_LIBRARY}
+ ${UNIFORMTYPEIDENTIFIERS_LIBRARY}
)
endif()
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 22c2156bb8..baa93bd128 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -144,7 +144,38 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(DARWIN 1)
string(REGEX MATCH "-mmacosx-version-min=([^ ]+)" scratch "$ENV{LL_BUILD}")
- set(CMAKE_OSX_DEPLOYMENT_TARGET "${CMAKE_MATCH_1}" CACHE STRING "macOS Deploy Target" FORCE)
+ set(LL_REQUESTED_DEPLOYMENT_TARGET "${CMAKE_MATCH_1}")
+
+ # Determine the lowest deployment target the active macOS SDK still supports.
+ # We aim for 11.0 in our public builds, but newer Xcode/SDK releases
+ # periodically raise this floor (e.g. Xcode 26 -> 13.3, Xcode 27 -> 14), and
+ # linking against a deployment target below the SDK's minimum fails. Read the
+ # supported minimum from the SDK and clamp our requested target up to it when
+ # necessary, so the build tracks whatever the SDK allows automatically.
+ set(LL_SDK_MINIMUM_DEPLOYMENT_TARGET "")
+ execute_process(
+ COMMAND xcrun --sdk macosx --show-sdk-path
+ OUTPUT_VARIABLE LL_MACOS_SDK_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+ if (LL_MACOS_SDK_PATH AND EXISTS "${LL_MACOS_SDK_PATH}/SDKSettings.plist")
+ execute_process(
+ COMMAND /usr/libexec/PlistBuddy -c
+ "Print :SupportedTargets:macosx:MinimumDeploymentTarget"
+ "${LL_MACOS_SDK_PATH}/SDKSettings.plist"
+ OUTPUT_VARIABLE LL_SDK_MINIMUM_DEPLOYMENT_TARGET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+ endif ()
+
+ set(LL_EFFECTIVE_DEPLOYMENT_TARGET "${LL_REQUESTED_DEPLOYMENT_TARGET}")
+ if (LL_SDK_MINIMUM_DEPLOYMENT_TARGET AND
+ LL_REQUESTED_DEPLOYMENT_TARGET VERSION_LESS LL_SDK_MINIMUM_DEPLOYMENT_TARGET)
+ message(STATUS "Requested macOS deploy target ${LL_REQUESTED_DEPLOYMENT_TARGET} is below the SDK minimum ${LL_SDK_MINIMUM_DEPLOYMENT_TARGET}; clamping to ${LL_SDK_MINIMUM_DEPLOYMENT_TARGET}")
+ set(LL_EFFECTIVE_DEPLOYMENT_TARGET "${LL_SDK_MINIMUM_DEPLOYMENT_TARGET}")
+ endif ()
+
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "${LL_EFFECTIVE_DEPLOYMENT_TARGET}" CACHE STRING "macOS Deploy Target" FORCE)
message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET = '${CMAKE_OSX_DEPLOYMENT_TARGET}'")
# Use dwarf symbols for most libraries for compilation speed
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 13a7592e8f..3dae2d1067 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -60,6 +60,7 @@ set(macosx_HEADER_FILES
llkeyboardmacosx.h
llwindowmacosx.h
llwindowmacosx-objc.h
+ llwindowmacosx_iokit.h
llopenglview-objc.h
llappdelegate-objc.h
)
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index f8920318d3..1dd795cd3a 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -44,7 +44,7 @@
#include <CoreGraphics/CGDisplayConfiguration.h>
#include <IOKit/IOCFPlugIn.h>
-#include <IOKit/IOKitLib.h>
+#include "llwindowmacosx_iokit.h"
#include <IOKit/IOMessage.h>
#include <IOKit/hid/IOHIDUsageTables.h>
#include <IOKit/hid/IOHIDLib.h>
@@ -2379,7 +2379,7 @@ bool LLWindowMacOSX::getInputDevices(U32 device_type_filter,
io_iterator_t io_iter = 0;
// create an IO object iterator
- result = IOServiceGetMatchingServices( kIOMasterPortDefault, device_dict_ref, &io_iter );
+ result = IOServiceGetMatchingServices( kLLIOMainPort, device_dict_ref, &io_iter );
if ( kIOReturnSuccess != result )
{
LL_WARNS("Joystick") << "IOServiceGetMatchingServices failed" << LL_ENDL;
diff --git a/indra/llwindow/llwindowmacosx_iokit.h b/indra/llwindow/llwindowmacosx_iokit.h
new file mode 100644
index 0000000000..a6be2c86ef
--- /dev/null
+++ b/indra/llwindow/llwindowmacosx_iokit.h
@@ -0,0 +1,35 @@
+/**
+ * @file llwindowmacosx_iokit.h
+ * @brief IOKit compatibility for macOS deployment target differences
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+#include <IOKit/IOKitLib.h>
+
+// kIOMainPortDefault is the macOS 12+ rename of kIOMasterPortDefault.
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000
+static const mach_port_t kLLIOMainPort = kIOMainPortDefault;
+#else
+static const mach_port_t kLLIOMainPort = kIOMasterPortDefault;
+#endif
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 1c01d06852..c188bb459f 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -49,6 +49,7 @@
#include "llerrorcontrol.h"
#include "llvoavatarself.h" // for gAgentAvatarp->getFullname()
#include <ApplicationServices/ApplicationServices.h>
+#include "llwindowmacosx_iokit.h"
#ifdef LL_CARBON_CRASH_HANDLER
#include <Carbon/Carbon.h>
#endif
@@ -441,7 +442,7 @@ std::string LLAppViewerMacOSX::generateSerialNumber()
// JC: Sample code from http://developer.apple.com/technotes/tn/tn1103.html
CFStringRef serialNumber = NULL;
- io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
+ io_service_t platformExpert = IOServiceGetMatchingService(kLLIOMainPort,
IOServiceMatching("IOPlatformExpertDevice"));
if (platformExpert)
{
diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm
index 99e93bafbf..3a0bc4005e 100644
--- a/indra/newview/llfilepicker_mac.mm
+++ b/indra/newview/llfilepicker_mac.mm
@@ -26,15 +26,28 @@
#ifdef LL_DARWIN
#import <Cocoa/Cocoa.h>
+#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
#include <iostream>
#include "llfilepicker_mac.h"
+// Convert a file extension or UTI string into a UTType for use with
+// NSOpenPanel/NSSavePanel's allowedContentTypes.
+static UTType *contentTypeForString(NSString *typeString)
+{
+ UTType *type = [UTType typeWithFilenameExtension:typeString];
+ if (!type)
+ {
+ type = [UTType typeWithIdentifier:typeString];
+ }
+ return type;
+}
+
NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned int flags)
{
int i;
NSOpenPanel *panel = [NSOpenPanel openPanel];
- NSMutableArray *fileTypes = nil;
+ NSMutableArray<UTType *> *fileTypes = nil;
if ( allowed_types && !allowed_types->empty())
@@ -43,9 +56,13 @@ NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned
for (i=0;i<allowed_types->size();++i)
{
- [fileTypes addObject:
- [NSString stringWithCString:(*allowed_types)[i].c_str()
- encoding:[NSString defaultCStringEncoding]]];
+ NSString *typeString = [NSString stringWithCString:(*allowed_types)[i].c_str()
+ encoding:[NSString defaultCStringEncoding]];
+ UTType *type = contentTypeForString(typeString);
+ if (type)
+ {
+ [fileTypes addObject:type];
+ }
}
}
@@ -57,9 +74,9 @@ NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned
[panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
- if (fileTypes)
+ if (fileTypes && fileTypes.count > 0)
{
- [panel setAllowedFileTypes:fileTypes];
+ [panel setAllowedContentTypes:fileTypes];
}
else
{
@@ -196,12 +213,25 @@ std::unique_ptr<std::string> doSaveDialog(const std::string* file,
NSSavePanel *panel = [NSSavePanel savePanel];
NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
- NSArray *fileType = [extensionns componentsSeparatedByString:@","];
+ NSArray *extensions = [extensionns componentsSeparatedByString:@","];
+
+ NSMutableArray<UTType *> *fileType = [[NSMutableArray alloc] init];
+ for (NSString *ext in extensions)
+ {
+ UTType *type = contentTypeForString(ext);
+ if (type)
+ {
+ [fileType addObject:type];
+ }
+ }
//[panel setMessage:@"Save Image File"];
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
[panel setCanSelectHiddenExtension:true];
- [panel setAllowedFileTypes:fileType];
+ if (fileType.count > 0)
+ {
+ [panel setAllowedContentTypes:fileType];
+ }
NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
NSURL* url = [NSURL fileURLWithPath:fileName];
@@ -231,12 +261,25 @@ void doSaveDialogModeless(const std::string* file,
NSSavePanel *panel = [NSSavePanel savePanel];
NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
- NSArray *fileType = [extensionns componentsSeparatedByString:@","];
+ NSArray *extensions = [extensionns componentsSeparatedByString:@","];
+
+ NSMutableArray<UTType *> *fileType = [[NSMutableArray alloc] init];
+ for (NSString *ext in extensions)
+ {
+ UTType *type = contentTypeForString(ext);
+ if (type)
+ {
+ [fileType addObject:type];
+ }
+ }
//[panel setMessage:@"Save Image File"];
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
[panel setCanSelectHiddenExtension:true];
- [panel setAllowedFileTypes:fileType];
+ if (fileType.count > 0)
+ {
+ [panel setAllowedContentTypes:fileType];
+ }
NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
NSURL* url = [NSURL fileURLWithPath:fileName];
diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp
index 0a90cf0699..0373b25143 100644
--- a/indra/newview/llmachineid.cpp
+++ b/indra/newview/llmachineid.cpp
@@ -34,7 +34,7 @@
#include <Wbemidl.h>
#elif LL_DARWIN
#include <CoreFoundation/CoreFoundation.h>
-#include <IOKit/IOKitLib.h>
+#include "llwindowmacosx_iokit.h"
#endif
unsigned char static_unique_id[] = {0,0,0,0,0,0};
unsigned char static_legacy_id[] = {0,0,0,0,0,0};
@@ -350,7 +350,7 @@ bool LLWMIMethods::getGenericSerialNumber(const BSTR &select, const LPCWSTR &var
bool getSerialNumber(unsigned char *unique_id, size_t len)
{
CFStringRef serial_cf_str = NULL;
- io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
+ io_service_t platformExpert = IOServiceGetMatchingService(kLLIOMainPort,
IOServiceMatching("IOPlatformExpertDevice"));
if (platformExpert)
{