Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
dc0ed73
[clr-ios] Enable Release builds and dynamic linking on Apple mobile
kotlarmilos Oct 27, 2025
146b3ce
Add comment
kotlarmilos Oct 29, 2025
7c072cd
Change build configuration from Checked to Release
kotlarmilos Oct 29, 2025
7abf417
Merge branch 'main' into improvement/clr-ios-release-build
kotlarmilos Oct 29, 2025
0a2ddd5
Enable FeatureInterpreter in clr.featuredefines.props
kotlarmilos Oct 29, 2025
e5f4df1
Merge branch 'improvement/clr-ios-release-build' of github.com:kotlar…
kotlarmilos Oct 29, 2025
6bb07e5
Don't install interpreter in the sharedFramework
kotlarmilos Oct 29, 2025
1a5d564
Merge branch 'main' into improvement/clr-ios-release-build
kotlarmilos Oct 29, 2025
8615e2f
Merge branch 'main' into improvement/clr-ios-release-build
kotlarmilos Oct 30, 2025
f25d9d2
Fix Thread__m_pInterpThreadContext offset
kotlarmilos Oct 30, 2025
64bb276
Remove CORECLR_TEST condition
kotlarmilos Oct 30, 2025
0455894
Merge branch 'main' into improvement/clr-ios-release-build
kotlarmilos Oct 31, 2025
9a862ea
Merge branch 'main' into improvement/clr-ios-release-build
kotlarmilos Nov 4, 2025
b421b0e
Merge branch 'main' into improvement/clr-ios-release-build
kotlarmilos Nov 4, 2025
7379801
Add environment variable for DOTNET_Interpreter and remove DOTNET_Int…
kotlarmilos Nov 4, 2025
7431165
Merge branch 'main' into improvement/clr-ios-release-build
kotlarmilos Nov 5, 2025
69228e9
Merge branch 'main' into improvement/clr-ios-release-build
kotlarmilos Nov 5, 2025
7d4aad8
Update runtime.yml to use Release build
kotlarmilos Nov 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ jobs:
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: Checked
buildConfig: Release
runtimeFlavor: coreclr
isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
isiOSLikeOnlyBuild: ${{ parameters.isiOSLikeOnlyBuild }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
buildConfig: checked
buildConfig: release
runtimeFlavor: coreclr
platforms:
- ios_arm64
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/clr.featuredefines.props
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
<FeatureObjCMarshal>true</FeatureObjCMarshal>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetsMacCatalyst)' == 'true' OR '$(TargetsiOS)' == 'true' OR '$(TargetstvOS)' == 'true'">
<FeatureInterpreter>true</FeatureInterpreter>
</PropertyGroup>

<PropertyGroup Condition="('$(Platform)' == 'x64' OR '$(Platform)' == 'arm64') AND ('$(Configuration)' == 'debug' OR '$(Configuration)' == 'checked') AND '$(TargetsAndroid)' != 'true'">
<FeatureInterpreter>true</FeatureInterpreter>
</PropertyGroup>
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/clrfeatures.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ if(NOT DEFINED FEATURE_INTERPRETER)
set(FEATURE_INTERPRETER 1)
set(FEATURE_PORTABLE_ENTRYPOINTS 1)
set(FEATURE_PORTABLE_HELPERS 1)
elseif(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_MACCATALYST)
set(FEATURE_INTERPRETER 1)
else()
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
set(FEATURE_INTERPRETER $<IF:$<CONFIG:Debug,Checked>,1,0>)
Expand Down
6 changes: 5 additions & 1 deletion src/coreclr/interpreter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,8 @@ target_link_libraries(clrinterpreter
${INTERPRETER_LINK_LIBRARIES}
)

install_clr(TARGETS clrinterpreter DESTINATIONS . sharedFramework COMPONENT runtime OPTIONAL)
if (CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_MACCATALYST)
install_clr(TARGETS clrinterpreter DESTINATIONS . COMPONENT runtime OPTIONAL)
else()
install_clr(TARGETS clrinterpreter DESTINATIONS . sharedFramework COMPONENT runtime OPTIONAL)
endif()
4 changes: 4 additions & 0 deletions src/coreclr/vm/arm64/asmconstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,11 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__ThreadLocalInfo__m_pThread == offsetof(ThreadLoc
ASMCONSTANTS_C_ASSERT(OFFSETOF__InterpMethod__pCallStub == offsetof(InterpMethod, pCallStub))

#ifdef TARGET_UNIX
#ifdef _DEBUG
#define OFFSETOF__Thread__m_pInterpThreadContext 0xb30
#else // _DEBUG
#define OFFSETOF__Thread__m_pInterpThreadContext 0x2c8
#endif // _DEBUG
#else // TARGET_UNIX
#define OFFSETOF__Thread__m_pInterpThreadContext 0xb58
#endif // TARGET_UNIX
Expand Down
9 changes: 0 additions & 9 deletions src/mono/sample/iOS/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,6 @@ private static void OnButtonClick()
{
SetText("OnButtonClick! #" + counter++);
}
#if CORECLR_TEST
public static int Main(string[] args)
{
Console.WriteLine("Done!");
Thread.Sleep(Timeout.Infinite);
return 42;
}
#else
#if CI_TEST
public static async Task<int> Main(string[] args)
#else
Expand Down Expand Up @@ -72,5 +64,4 @@ public static async Task Main(string[] args)
await Task.Delay(-1);
#endif
}
#endif
}
3 changes: 1 addition & 2 deletions src/mono/sample/iOS/Program.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<TargetOS Condition="'$(TargetOS)' == ''">iossimulator</TargetOS>
<RuntimeIdentifier>$(TargetOS)-$(TargetArchitecture)</RuntimeIdentifier>
<DefineConstants Condition="'$(ArchiveTests)' == 'true'">$(DefineConstants);CI_TEST</DefineConstants>
<DefineConstants Condition="'$(UseMonoRuntime)' != 'true'">$(DefineConstants);CORECLR_TEST</DefineConstants>
<AppName>HelloiOS</AppName>
<MainLibraryFileName>$(AssemblyName).dll</MainLibraryFileName>
<SelfContained>true</SelfContained>
Expand All @@ -31,7 +30,7 @@
<RuntimeComponents Condition="'$(DiagnosticPorts)' != ''" Include="diagnostics_tracing" />
<EnvironmentVariables Condition="'$(UseMonoRuntime)' != 'true'" Include="DOTNET_InterpMode=3" />
<EnvironmentVariables Condition="'$(UseMonoRuntime)' != 'true'" Include="DOTNET_ReadyToRun=0" />
<EnvironmentVariables Condition="'$(UseMonoRuntime)' != 'true'" Include="DOTNET_InterpDump=*!*" />
<EnvironmentVariables Condition="'$(UseMonoRuntime)' != 'true'" Include="DOTNET_InterpDump=%2A%21%2A" />
</ItemGroup>

<Import Project="$(MonoProjectRoot)\msbuild\apple\build\AppleBuild.props" />
Expand Down
2 changes: 1 addition & 1 deletion src/tasks/AppleAppBuilder/AppleAppBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ public override bool Execute()
{
extraLinkerArgs.Add("-rpath @executable_path");
}
shouldStaticLink = true;
shouldStaticLink = false;
}

var generator = new Xcode(Log, TargetOS, Arch);
Expand Down
27 changes: 23 additions & 4 deletions src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,32 @@ if("${HARDENED_RUNTIME}")
set_target_properties(%ProjectName% PROPERTIES XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "YES")
if("${HARDENED_RUNTIME_USE_ENTITLEMENTS_FILE}")
set_target_properties(%ProjectName% PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "app.entitlements")
add_custom_command(
TARGET %ProjectName% POST_BUILD
COMMAND if test \"$CODE_SIGN_IDENTITY\" && ls -1 $CODESIGNING_FOLDER_PATH/Contents/Resources/*.dylib 2>/dev/null | grep -q .\; then codesign -fs \"$CODE_SIGN_IDENTITY\" $CODESIGNING_FOLDER_PATH/Contents/Resources/*.dylib\; fi
)
endif()
endif()

# Sign any dylibs in the app bundle (required for iOS dynamic linking)
add_custom_command(
TARGET %ProjectName% POST_BUILD
COMMAND
if test \"$CODE_SIGN_IDENTITY\" && test \"$CODE_SIGN_IDENTITY\" != \"\"\; then
SIGN_IDENTITY=\"$EXPANDED_CODE_SIGN_IDENTITY\"\;
# This resolves the correct signing certificate by matching the identity name
# when multiple signing certificates are available
if test -z \"$SIGN_IDENTITY\" || test \"$SIGN_IDENTITY\" = \"$CODE_SIGN_IDENTITY\"\; then
CERT_HASH=`security find-identity -v -p codesigning | grep \"$CODE_SIGN_IDENTITY\" | head -1 | awk '{print $2}'`\;
SIGN_IDENTITY=\"$CERT_HASH\"\;
fi\;
if test -n \"$SIGN_IDENTITY\"\; then
if ls -1 $CODESIGNING_FOLDER_PATH/Contents/Resources/*.dylib 2>/dev/null | grep -q .\; then
codesign --force --sign \"$SIGN_IDENTITY\" --timestamp $CODESIGNING_FOLDER_PATH/Contents/Resources/*.dylib\;
fi\;
if ls -1 $CODESIGNING_FOLDER_PATH/*.dylib 2>/dev/null | grep -q .\; then
codesign --force --sign \"$SIGN_IDENTITY\" --timestamp $CODESIGNING_FOLDER_PATH/*.dylib\;
fi\;
fi\;
fi
)

# FIXME: `XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING` should not be NO

target_link_libraries(
Expand Down
12 changes: 0 additions & 12 deletions src/tasks/AppleAppBuilder/Templates/runtime-coreclr.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@
return strdup([joined UTF8String]);
}

// Forward declarations for System.Native
extern void SystemNative_Log(uint8_t* buffer, int32_t length);
extern void SystemNative_LogError(uint8_t* buffer, int32_t length);

void*
pinvoke_override (const char *libraryName, const char *entrypointName)
{
Expand All @@ -80,14 +76,6 @@
return dlsym (RTLD_DEFAULT, entrypointName);
}

if (!strcmp(libraryName, "libSystem.Native"))
{
if (!strcmp(entrypointName, "SystemNative_Log"))
return (void*)SystemNative_Log;
if (!strcmp(entrypointName, "SystemNative_LogError"))
return (void*)SystemNative_LogError;
}

return NULL;
}

Expand Down
79 changes: 41 additions & 38 deletions src/tasks/AppleAppBuilder/Xcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,12 @@ public string GenerateCMake(
{
predefinedExcludes.Add("libcoreclr.dylib");
}
else
{
// Interpreter is statically linked into the runtime already
predefinedExcludes.Add("libclrjit.dylib");
predefinedExcludes.Add("libclrinterpreter.dylib");
}

string[] resources = Directory.GetFileSystemEntries(workspace, "", SearchOption.TopDirectoryOnly)
.Where(f => !predefinedExcludes.Any(e => (!e.EndsWith('*') && f.EndsWith(e, StringComparison.InvariantCultureIgnoreCase)) || (e.EndsWith('*') && Path.GetFileName(f).StartsWith(e.TrimEnd('*'), StringComparison.InvariantCultureIgnoreCase) &&
Expand Down Expand Up @@ -386,52 +392,49 @@ public string GenerateCMake(
}
else
{
string[] allComponentLibs = Directory.GetFiles(workspace, "libmono-component-*-static.a");
string[] staticComponentStubLibs = Directory.GetFiles(workspace, "libmono-component-*-stub-static.a");

// by default, component stubs will be linked and depending on how mono runtime has been build,
// stubs can disable or dynamic load components.
foreach (string staticComponentStubLib in staticComponentStubLibs)
{
string componentLibToLink = staticComponentStubLib;
foreach (string runtimeComponent in runtimeComponents)
{
if (componentLibToLink.Contains(runtimeComponent, StringComparison.OrdinalIgnoreCase))
{
// static link component.
componentLibToLink = componentLibToLink.Replace("-stub-static.a", "-static.a", StringComparison.OrdinalIgnoreCase);
break;
}
}

// if lib doesn't exist (primarily due to runtime build without static lib support), fallback linking stub lib.
if (!File.Exists(componentLibToLink))
{
Logger.LogMessage(MessageImportance.High, $"\nCouldn't find static component library: {componentLibToLink}, linking static component stub library: {staticComponentStubLib}.\n");
componentLibToLink = staticComponentStubLib;
}

toLink += $" \"-force_load {componentLibToLink}\"{Environment.NewLine}";
}

if (targetRuntime == TargetRuntime.CoreCLR)
{
// Interpreter-FIXME: CoreCLR on iOS currently supports only static linking.
// The build system needs to be updated to conditionally initialize the compiler at runtime based on an environment variable.
// Tracking issue: https://github.com/dotnet/runtime/issues/119006
string[] staticLibPatterns = new string[] {
"libcoreclr_static.a",
"libbrotli*.a",
"libSystem*.a"
string[] dylibsPatterns = new string[] {
"libcoreclr.dylib",
"libbrotli*.dylib",
"libSystem*.dylib"
};
string[] staticLibs = staticLibPatterns.SelectMany(pattern => Directory.GetFiles(workspace, pattern)).ToArray();
foreach (string lib in staticLibs)
string[] dylibs = dylibsPatterns.SelectMany(pattern => Directory.GetFiles(workspace, pattern)).ToArray();
foreach (string lib in dylibs)
{
toLink += $" -Wl,-force_load,\"{lib}\"{Environment.NewLine}";
toLink += $" \"-force_load {lib}\"{Environment.NewLine}";
}
}
else
{
string[] allComponentLibs = Directory.GetFiles(workspace, "libmono-component-*-static.a");
string[] staticComponentStubLibs = Directory.GetFiles(workspace, "libmono-component-*-stub-static.a");

// by default, component stubs will be linked and depending on how mono runtime has been build,
// stubs can disable or dynamic load components.
foreach (string staticComponentStubLib in staticComponentStubLibs)
{
string componentLibToLink = staticComponentStubLib;
foreach (string runtimeComponent in runtimeComponents)
{
if (componentLibToLink.Contains(runtimeComponent, StringComparison.OrdinalIgnoreCase))
{
// static link component.
componentLibToLink = componentLibToLink.Replace("-stub-static.a", "-static.a", StringComparison.OrdinalIgnoreCase);
break;
}
}

// if lib doesn't exist (primarily due to runtime build without static lib support), fallback linking stub lib.
if (!File.Exists(componentLibToLink))
{
Logger.LogMessage(MessageImportance.High, $"\nCouldn't find static component library: {componentLibToLink}, linking static component stub library: {staticComponentStubLib}.\n");
componentLibToLink = staticComponentStubLib;
}

toLink += $" \"-force_load {componentLibToLink}\"{Environment.NewLine}";
}

string[] dylibs = Directory.GetFiles(workspace, "*.dylib");
// Sort the static libraries to link so the brotli libs are added to the list last (after the compression native libs)
List<string> staticLibsToLink = Directory.GetFiles(workspace, "*.a").OrderBy(libName => libName.Contains("brotli") ? 1 : 0).ToList();
Expand Down
Loading