Skip to content

Commit 39f4921

Browse files
authored
[iOS] Remove cmake build dependency for library mode (#89869)
This change removes cmake as a build dependency and instead uses clang directly when building for iOS/tvOS/Macatalyst library mode.
1 parent 3e293bc commit 39f4921

File tree

14 files changed

+775
-275
lines changed

14 files changed

+775
-275
lines changed

Directory.Build.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
- src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
5858
- src/installer/pkg/sfx/bundle/shared-framework-distribution-template-x64.xml
5959
- src/installer/pkg/sfx/bundle/shared-framework-distribution-template-arm64.xml
60+
- src/tasks/MobileBuildTasks/Apple/AppleProject.cs
6061
-->
6162
<AndroidApiLevelMin>21</AndroidApiLevelMin>
6263
<iOSVersionMin>11.0</iOSVersionMin>

src/mono/msbuild/apple/build/AppleBuild.targets

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
<PropertyGroup>
33
<AppleGenerateAppBundle Condition="'$(AppleGenerateAppBundle)' == '' and '$(GenerateAppBundle)' != ''">$(GenerateAppBundle)</AppleGenerateAppBundle>
44
<AppleGenerateAppBundle Condition="'$(AppleGenerateAppBundle)' == ''">true</AppleGenerateAppBundle>
5-
<!-- Unable to properly integrate nativelib into app build, so not supported for now. -->
6-
<AppleGenerateAppBundle Condition="'$(_IsLibraryMode)' == 'true'">false</AppleGenerateAppBundle>
5+
<AppleGenerateAppBundle Condition="'$(_IsLibraryMode)' == 'true' and '$(ForceLibraryModeGenerateAppBundle)' != 'true'">false</AppleGenerateAppBundle>
76
<_ProcessRuntimeComponentsForLibraryMode Condition="'$(_IsLibraryMode)' == 'true'">_ProcessRuntimeComponentsForLibraryMode</_ProcessRuntimeComponentsForLibraryMode>
87
<EnableDefaultAssembliesToBundle Condition="'$(EnableDefaultAssembliesToBundle)' == ''">false</EnableDefaultAssembliesToBundle>
98
</PropertyGroup>
@@ -53,10 +52,23 @@
5352
<AppName Condition="'$(AppName)' == ''">$(AssemblyName)</AppName>
5453
</PropertyGroup>
5554

55+
<PropertyGroup>
56+
<RuntimeComponents Condition="'$(RuntimeComponents)' == ''">marshal-ilgen</RuntimeComponents>
57+
</PropertyGroup>
58+
5659
<!-- common linker arguments for app and library builds -->
5760
<ItemGroup>
5861
<_CommonLinkerArgs Condition="'$(_IsLibraryMode)' == 'true' and '$(TargetOS)' != 'tvos' and '$(TargetOS)' != 'tvossimulator'" Include="-framework GSS" />
5962
</ItemGroup>
63+
64+
<ItemGroup Condition="'$(_IsLibraryMode)' == 'true'">
65+
<_CommonLinkerArgs Include="-lz" />
66+
<_CommonLinkerArgs Include="-lc++" />
67+
<_CommonLinkerArgs Include="-liconv" />
68+
<_CommonLinkerArgs Include="-framework Foundation" />
69+
<_CommonLinkerArgs Include="-framework Security" />
70+
<_CommonLinkerArgs Include="-framework UIKit" />
71+
</ItemGroup>
6072
</Target>
6173

6274
<Target Name="_BeforeAppleBuild">
@@ -262,36 +274,41 @@
262274
<ExtraAppLinkerArgs Include="@(_CommonLinkerArgs)" />
263275
</ItemGroup>
264276

277+
<ItemGroup Condition="'$(_IsLibraryMode)' == 'true'">
278+
<NativeDependencies Include="$(LibraryOutputPath)" />
279+
</ItemGroup>
280+
265281
<Error Condition="'$(NativeMainSource)' != '' and !Exists('$(NativeMainSource)')" Text="Project property NativeMainSource is defined, but the specified file: '$(NativeMainSource)' does not exist." />
266282

267283
<AppleAppBuilderTask
268-
UseNativeAOTRuntime="$(UseNativeAOTRuntime)"
269-
NativeDependencies="$(NativeDependencies)"
270284
AppDir="$(AppleBuildDir)"
271285
Arch="$(TargetArchitecture)"
272286
Assemblies="@(_AssembliesToBundleInternal)"
273287
BuildAppBundle="$(GenerateXcodeProject)"
274288
DevTeamProvisioning="$(DevTeamProvisioning)"
275289
DiagnosticPorts="$(DiagnosticPorts)"
276290
EnableAppSandbox="$(EnableAppSandbox)"
291+
ExcludeFromAppDir="@(_ExcludeFromAppDir)"
277292
ExtraLinkerArguments="@(ExtraAppLinkerArgs)"
278293
ForceAOT="$(RunAOTCompilation)"
279294
ForceInterpreter="$(MonoForceInterpreter)"
280295
GenerateCMakeProject="$(GenerateCMakeProject)"
281296
GenerateXcodeProject="$(GenerateXcodeProject)"
282-
InvariantGlobalization="$(InvariantGlobalization)"
283297
HybridGlobalization="$(HybridGlobalization)"
298+
InvariantGlobalization="$(InvariantGlobalization)"
299+
IsLibraryMode="$(_IsLibraryMode)"
284300
MainLibraryFileName="$(MainLibraryFileName)"
285301
MonoRuntimeHeaders="$(_MonoHeaderPath)"
286302
NativeMainSource="$(NativeMainSource)"
303+
NativeDependencies="@(NativeDependencies)"
287304
Optimized="$(Optimized)"
288305
OutputDirectory="$(AppleBundleDir)"
289306
ProjectName="$(AppName)"
290307
RuntimeComponents="$(RuntimeComponents)"
291-
TargetOS="$(TargetOS)"
292308
StripSymbolTable="$(StripDebugSymbols)"
293-
ExcludeFromAppDir="@(_ExcludeFromAppDir)"
294-
UseConsoleUITemplate="$(UseConsoleUITemplate)">
309+
TargetOS="$(TargetOS)"
310+
UseConsoleUITemplate="$(UseConsoleUITemplate)"
311+
UseNativeAOTRuntime="$(UseNativeAOTRuntime)">
295312
<Output TaskParameter="AppBundlePath" PropertyName="AppBundlePath" />
296313
<Output TaskParameter="XcodeProjectPath" PropertyName="XcodeProjectPath" />
297314
</AppleAppBuilderTask>

src/tasks/AppleAppBuilder/AppleAppBuilder.cs

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ public string TargetOS
186186
/// </summary>
187187
public string[] NativeDependencies { get; set; } = Array.Empty<string>();
188188

189+
/// <summary>
190+
/// Mode to control whether runtime is a self-contained library or not
191+
/// </summary>
192+
public bool IsLibraryMode { get; set; }
193+
189194
public void ValidateRuntimeSelection()
190195
{
191196
if (UseNativeAOTRuntime)
@@ -260,39 +265,38 @@ public override bool Execute()
260265
List<string> assemblerFiles = new List<string>();
261266
List<string> assemblerDataFiles = new List<string>();
262267
List<string> assemblerFilesToLink = new List<string>();
263-
foreach (ITaskItem file in Assemblies)
264-
{
265-
// use AOT files if available
266-
string obj = file.GetMetadata("AssemblerFile");
267-
string llvmObj = file.GetMetadata("LlvmObjectFile");
268-
string dataFile = file.GetMetadata("AotDataFile");
269268

270-
if (!string.IsNullOrEmpty(obj))
269+
if (!IsLibraryMode)
270+
{
271+
foreach (ITaskItem file in Assemblies)
271272
{
272-
assemblerFiles.Add(obj);
273-
}
273+
// use AOT files if available
274+
string obj = file.GetMetadata("AssemblerFile");
275+
string llvmObj = file.GetMetadata("LlvmObjectFile");
276+
string dataFile = file.GetMetadata("AotDataFile");
274277

275-
if (!string.IsNullOrEmpty(dataFile))
276-
{
277-
assemblerDataFiles.Add(dataFile);
278+
if (!string.IsNullOrEmpty(obj))
279+
{
280+
assemblerFiles.Add(obj);
281+
}
282+
283+
if (!string.IsNullOrEmpty(dataFile))
284+
{
285+
assemblerDataFiles.Add(dataFile);
286+
}
287+
288+
if (!string.IsNullOrEmpty(llvmObj))
289+
{
290+
assemblerFilesToLink.Add(llvmObj);
291+
}
278292
}
279293

280-
if (!string.IsNullOrEmpty(llvmObj))
294+
if (!ForceInterpreter && (shouldStaticLink || ForceAOT) && (assemblerFiles.Count == 0 && !UseNativeAOTRuntime))
281295
{
282-
assemblerFilesToLink.Add(llvmObj);
296+
throw new InvalidOperationException("Need list of AOT files for static linked builds.");
283297
}
284298
}
285299

286-
foreach (var nativeDependency in NativeDependencies)
287-
{
288-
assemblerFilesToLink.Add(nativeDependency);
289-
}
290-
291-
if (!ForceInterpreter && (shouldStaticLink || ForceAOT) && (assemblerFiles.Count == 0 && !UseNativeAOTRuntime))
292-
{
293-
throw new InvalidOperationException("Need list of AOT files for static linked builds.");
294-
}
295-
296300
if (!string.IsNullOrEmpty(DiagnosticPorts))
297301
{
298302
bool validDiagnosticsConfig = false;
@@ -313,6 +317,11 @@ public override bool Execute()
313317
throw new ArgumentException("DevTeamProvisioning must be set to a valid value when App Sandbox is enabled, using '-' is not supported.");
314318
}
315319

320+
foreach (var nativeDependency in NativeDependencies)
321+
{
322+
assemblerFilesToLink.Add(nativeDependency);
323+
}
324+
316325
List<string> extraLinkerArgs = new List<string>();
317326
foreach(ITaskItem item in ExtraLinkerArguments)
318327
{
@@ -324,7 +333,7 @@ public override bool Execute()
324333
if (GenerateXcodeProject)
325334
{
326335
XcodeProjectPath = generator.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles, assemblerDataFiles, assemblerFilesToLink, extraLinkerArgs, excludes,
327-
AppDir, binDir, MonoRuntimeHeaders, !shouldStaticLink, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, HybridGlobalization, Optimized, EnableRuntimeLogging, EnableAppSandbox, DiagnosticPorts, RuntimeComponents, NativeMainSource, UseNativeAOTRuntime);
336+
AppDir, binDir, MonoRuntimeHeaders, !shouldStaticLink, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, HybridGlobalization, Optimized, EnableRuntimeLogging, EnableAppSandbox, DiagnosticPorts, RuntimeComponents, NativeMainSource, UseNativeAOTRuntime, IsLibraryMode);
328337

329338
if (BuildAppBundle)
330339
{
@@ -350,7 +359,7 @@ public override bool Execute()
350359
else if (GenerateCMakeProject)
351360
{
352361
generator.GenerateCMake(ProjectName, MainLibraryFileName, assemblerFiles, assemblerDataFiles, assemblerFilesToLink, extraLinkerArgs, excludes,
353-
AppDir, binDir, MonoRuntimeHeaders, !shouldStaticLink, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, HybridGlobalization, Optimized, EnableRuntimeLogging, EnableAppSandbox, DiagnosticPorts, RuntimeComponents, NativeMainSource, UseNativeAOTRuntime);
362+
AppDir, binDir, MonoRuntimeHeaders, !shouldStaticLink, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, HybridGlobalization, Optimized, EnableRuntimeLogging, EnableAppSandbox, DiagnosticPorts, RuntimeComponents, NativeMainSource, UseNativeAOTRuntime, IsLibraryMode);
354363
}
355364

356365
return true;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
3+
project(%ProjectName%)
4+
enable_language(OBJC ASM)
5+
6+
set(APP_RESOURCES
7+
%AppResources%
8+
lib%ProjectName%.dylib
9+
)
10+
11+
add_executable(
12+
%ProjectName%
13+
%MainSource%
14+
${APP_RESOURCES}
15+
)
16+
17+
if(NOT %UseNativeAOTRuntime%)
18+
target_sources(
19+
%ProjectName%
20+
PRIVATE
21+
runtime.m)
22+
endif()
23+
24+
%Defines%
25+
26+
if(NOT %UseNativeAOTRuntime%)
27+
include_directories("%MonoInclude%")
28+
endif()
29+
30+
#set_target_properties(%ProjectName% %AotTargetsList% PROPERTIES
31+
# XCODE_ATTRIBUTE_SUPPORTS_MACCATALYST "YES"
32+
#)
33+
34+
set_target_properties(%ProjectName% PROPERTIES
35+
MACOSX_BUNDLE TRUE
36+
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
37+
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
38+
XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING "NO"
39+
XCODE_EMIT_EFFECTIVE_PLATFORM_NAME "YES"
40+
XCODE_EMBED_FRAMEWORKS "%DYLIB_PATH%"
41+
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks"
42+
RESOURCE "${APP_RESOURCES}"
43+
)
44+
45+
set(HARDENED_RUNTIME
46+
%HardenedRuntime%
47+
)
48+
49+
set(HARDENED_RUNTIME_USE_ENTITLEMENTS_FILE
50+
%HardenedRuntimeUseEntitlementsFile%
51+
)
52+
53+
if("${HARDENED_RUNTIME}")
54+
set_target_properties(%ProjectName% PROPERTIES XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "YES")
55+
if("${HARDENED_RUNTIME_USE_ENTITLEMENTS_FILE}")
56+
set_target_properties(%ProjectName% PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "app.entitlements")
57+
add_custom_command(
58+
TARGET %ProjectName% POST_BUILD
59+
COMMAND if test \"$CODE_SIGN_IDENTITY\"\; then codesign -fs \"$CODE_SIGN_IDENTITY\" $CODESIGNING_FOLDER_PATH/Contents/Resources/*.dylib\; fi
60+
)
61+
endif()
62+
endif()
63+
64+
# FIXME: `XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING` should not be NO
65+
66+
target_link_libraries(
67+
%ProjectName%
68+
PRIVATE
69+
"-framework Foundation"
70+
"-framework Security"
71+
"-framework UIKit"
72+
"-lz"
73+
"-lc++"
74+
"-liconv"
75+
%NativeLibrariesToLink%
76+
%APP_LINK_LIBRARIES%
77+
)
78+
79+
set_target_properties(
80+
%ProjectName%
81+
PROPERTIES LINK_FLAGS
82+
%EXTRA_LINKER_ARGS%
83+
)
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
#import <Foundation/Foundation.h>
5+
#include <mono/utils/mono-publib.h>
6+
#include <mono/utils/mono-logger.h>
7+
#include <mono/metadata/assembly.h>
8+
#include <mono/metadata/appdomain.h>
9+
#include <mono/metadata/class.h>
10+
#include <mono/metadata/mono-debug.h>
11+
#include <mono/metadata/mono-gc.h>
12+
#include <mono/metadata/exception.h>
13+
#include <mono/metadata/object.h>
14+
#include <mono/jit/jit.h>
15+
#include <mono/jit/mono-private-unstable.h>
16+
#include <TargetConditionals.h>
17+
#import <os/log.h>
18+
#include <sys/stat.h>
19+
#include <sys/mman.h>
20+
#include <stdlib.h>
21+
#include <stdio.h>
22+
23+
#import "util.h"
24+
25+
static char *bundle_path;
26+
27+
int SayHello (void);
28+
29+
int invoke_netlibrary_entrypoints (void)
30+
{
31+
return SayHello ();
32+
}
33+
34+
const char *
35+
get_bundle_path (void)
36+
{
37+
if (bundle_path)
38+
return bundle_path;
39+
NSBundle* main_bundle = [NSBundle mainBundle];
40+
NSString* path = [main_bundle bundlePath];
41+
42+
#if TARGET_OS_MACCATALYST
43+
path = [path stringByAppendingString:@"/Contents/Resources"];
44+
#endif
45+
46+
bundle_path = strdup ([path UTF8String]);
47+
48+
return bundle_path;
49+
}
50+
51+
void
52+
mono_ios_runtime_init (void)
53+
{
54+
#if INVARIANT_GLOBALIZATION
55+
setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1", TRUE);
56+
#endif
57+
58+
#if HYBRID_GLOBALIZATION
59+
setenv ("DOTNET_SYSTEM_GLOBALIZATION_HYBRID", "1", TRUE);
60+
#endif
61+
62+
#if ENABLE_RUNTIME_LOGGING
63+
setenv ("MONO_LOG_LEVEL", "debug", TRUE);
64+
setenv ("MONO_LOG_MASK", "all", TRUE);
65+
#endif
66+
67+
// build using DiagnosticPorts property in AppleAppBuilder
68+
// or set DOTNET_DiagnosticPorts env via mlaunch, xharness when undefined.
69+
// NOTE, using DOTNET_DiagnosticPorts requires app build using AppleAppBuilder and RuntimeComponents=diagnostics_tracing
70+
#ifdef DIAGNOSTIC_PORTS
71+
setenv ("DOTNET_DiagnosticPorts", DIAGNOSTIC_PORTS, true);
72+
#endif
73+
74+
// When not bundling, this will make sure the runtime can access all the assemblies
75+
const char* bundle = get_bundle_path ();
76+
chdir (bundle);
77+
78+
int res = invoke_netlibrary_entrypoints ();
79+
80+
exit (res);
81+
}

0 commit comments

Comments
 (0)