Skip to content

Commit

Permalink
[AppleAppBuilder] Entitlements to run tests on catalyst using the JIT (
Browse files Browse the repository at this point in the history
…#50637)

* [catalyst] Add jit entitlements to AppleAppBuilder

to use the JIT on MacCatalyst we need the hardened runtime and the JIT
entitlement.  Otherwise mmap() with a MAP_JIT argument fails with EINVAL.

* [catalyst] also add disable library validation entitlement

To load libSystem.Native.dylib from the Resources/ directory in the .app
bundle.  (And possibly to load libicu from homebrew)

* [AppleAppBuilder] cleanup entitlements generation a little

Use a list in the builder instead of hardcoding in the template.

* [mono] update iOS sample to run on Catalyst too

use `make run-catalyst`

* fix typos and address feedback
  • Loading branch information
lambdageek authored Apr 5, 2021
1 parent 59c592c commit b7a1648
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 6 deletions.
16 changes: 16 additions & 0 deletions src/mono/sample/iOS/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,21 @@ run: clean appbuilder
$(DOTNET) publish -c $(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) \
/p:UseLLVM=$(USE_LLVM) /p:ForceAOT=$(AOT)

run-sim: clean appbuilder
$(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=iOSSimulator /p:TargetArchitecture=$(MONO_ARCH) \
/p:UseLLVM=$(USE_LLVM) /p:ForceAOT=$(AOT)

run-catalyst:
$(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=MacCatalyst /p:TargetArchitecture=$(MONO_ARCH) \
/p:UseLLVM=False /p:ForceAOT=False

run-sim-interp: clean appbuilder
$(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=iOSSimulator /p:TargetArchitecture=$(MONO_ARCH) \
/p:UseLLVM=$(USE_LLVM) /p:ForceAOT=$(AOT) /p:MonoForceInterpreter=true

run-catalyst-interp:
$(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=MacCatalyst /p:TargetArchitecture=$(MONO_ARCH) \
/p:UseLLVM=False /p:ForceAOT=False /p:MonoForceInterpreter=true

clean:
rm -rf bin
19 changes: 16 additions & 3 deletions src/mono/sample/iOS/Program.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@
<MicrosoftNetCoreAppRuntimePackDir>$(ArtifactsBinDir)microsoft.netcore.app.runtime.$(TargetOS.ToLower())-$(TargetArchitecture)\$(Configuration)\runtimes\$(TargetOS.ToLower())-$(TargetArchitecture)\</MicrosoftNetCoreAppRuntimePackDir>
<EnableTargetingPackDownload>false</EnableTargetingPackDownload>
<RuntimeIdentifier>$(TargetOS.ToLower())-$(TargetArchitecture)</RuntimeIdentifier>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>Link</TrimMode>
<DefineConstants Condition="'$(ArchiveTests)' == 'true'">$(DefineConstants);CI_TEST</DefineConstants>
</PropertyGroup>

<PropertyGroup>
<!-- FIXME: for some reason trimming is throwing errors about something in System.Diagnostics. -->
<!-- <PublishTrimmed>true</PublishTrimmed> -->
<!-- <TrimMode>Link</TrimMode> -->
</PropertyGroup>

<PropertyGroup Condition="'$(TargetOS)' == 'MacCatalyst'">
<DevTeamProvisioning Condition="'$(TargetOS)' == 'MacCatalyst' and '$(DevTeamProvisioning)' == ''">-</DevTeamProvisioning>
</PropertyGroup>

<!-- Redirect 'dotnet publish' to in-tree runtime pack -->
<Target Name="TrickRuntimePackLocation" AfterTargets="ProcessFrameworkReferences">
<ItemGroup>
Expand All @@ -35,7 +43,7 @@
<AppDir>$(MSBuildThisFileDirectory)$(PublishDir)\app</AppDir>
<IosSimulator Condition="'$(TargetsiOSSimulator)' == 'true'">iPhone 11</IosSimulator>
<Optimized Condition="'$(Configuration)' == 'Release'">True</Optimized>
<RunAOTCompilation Condition="'$(IosSimulator)' == '' or '$(ForceAOT)' == 'true'">true</RunAOTCompilation>
<RunAOTCompilation Condition="('$(TargetsMacCatalyst)' == 'false' and '$(IosSimulator)' == '') or '$(ForceAOT)' == 'true'">true</RunAOTCompilation>
</PropertyGroup>

<RemoveDir Directories="$(AppDir)" />
Expand Down Expand Up @@ -83,11 +91,16 @@
<Message Importance="High" Text="Xcode: $(XcodeProjectPath)"/>
<Message Importance="High" Text="App: $(AppBundlePath)"/>

<!-- install and run on ios simulator -->
<Exec Condition="'$(IosSimulator)' != '' and '$(ArchiveTests)' != 'true'" Command="xcrun simctl shutdown &quot;$(IosSimulator)&quot;" ContinueOnError="WarnAndContinue" />
<Exec Condition="'$(IosSimulator)' != '' and '$(ArchiveTests)' != 'true'" Command="xcrun simctl boot &quot;$(IosSimulator)&quot;" />
<Exec Condition="'$(IosSimulator)' != '' and '$(ArchiveTests)' != 'true'" Command="open -a Simulator" />
<Exec Condition="'$(IosSimulator)' != '' and '$(ArchiveTests)' != 'true'" Command="xcrun simctl install &quot;$(IosSimulator)&quot; $(AppBundlePath)" />
<Exec Condition="'$(IosSimulator)' != '' and '$(ArchiveTests)' != 'true'" Command="xcrun simctl launch --console booted net.dot.HelloiOS" />

<!-- run on MacCatalyst -->
<Exec Condition="'$(TargetOS)' == 'MacCatalyst'" Command="dotnet xharness apple run --app=$(AppBundlePath) --targets=maccatalyst --output-directory=/tmp/out" />

</Target>

<Target Name="CopySampleAppToHelixTestDir"
Expand Down
15 changes: 15 additions & 0 deletions src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ set_target_properties(%ProjectName% PROPERTIES
RESOURCE "${APP_RESOURCES}"
)

set(HARDENED_RUNTIME
%HardenedRuntime%
)

set(HARDENED_RUNTIME_USE_ENTITLEMENTS_FILE
%HardenedRuntimeUseEntitlementsFile%
)

if("${HARDENED_RUNTIME}")
set_target_properties(%ProjectName% PROPERTIES XCODE_ATTRIBUTE_HARDENED_RUNTIME "YES")
if("${HARDENED_RUNTIME_USE_ENTITLEMENTS_FILE}")
set_target_properties(%ProjectName% PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "app.entitlements")
endif()
endif()

# FIXME: `XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING` should not be NO

target_link_libraries(
Expand Down
7 changes: 7 additions & 0 deletions src/tasks/AppleAppBuilder/Templates/app.entitlements.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
%Entitlements%
</dict>
</plist>
4 changes: 2 additions & 2 deletions src/tasks/AppleAppBuilder/Templates/runtime.m
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,14 @@
const char *appctx_keys [] = {
"RUNTIME_IDENTIFIER",
"APP_CONTEXT_BASE_DIRECTORY",
#ifndef INVARIANT_GLOBALIZATION
#if !defined(INVARIANT_GLOBALIZATION) && !TARGET_OS_MACCATALYST
"ICU_DAT_FILE_PATH"
#endif
};
const char *appctx_values [] = {
APPLE_RUNTIME_IDENTIFIER,
bundle,
#ifndef INVARIANT_GLOBALIZATION
#if !defined(INVARIANT_GLOBALIZATION) && !TARGET_OS_MACCATALYST
icu_dat_path
#endif
};
Expand Down
30 changes: 29 additions & 1 deletion src/tasks/AppleAppBuilder/Xcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,24 @@ public string GenerateXCode(
}
}

var entitlements = new List<KeyValuePair<string, string>>();

bool hardenedRuntime = false;
if (Target == TargetNames.MacCatalyst && !(forceInterpreter || forceAOT)) {
hardenedRuntime = true;

/* for mmmap MAP_JIT */
entitlements.Add (KeyValuePair.Create ("com.apple.security.cs.allow-jit", "<true/>"));
/* for loading unsigned dylibs like libicu from outside the bundle or libSystem.Native.dylib from inside */
entitlements.Add (KeyValuePair.Create ("com.apple.security.cs.disable-library-validation", "<true/>"));
}

string cmakeLists = Utils.GetEmbeddedResource("CMakeLists.txt.template")
.Replace("%ProjectName%", projectName)
.Replace("%AppResources%", string.Join(Environment.NewLine, resources.Select(r => " " + r)))
.Replace("%MainSource%", nativeMainSource)
.Replace("%MonoInclude%", monoInclude);
.Replace("%MonoInclude%", monoInclude)
.Replace("%HardenedRuntime%", hardenedRuntime ? "TRUE" : "FALSE");


string[] dylibs = Directory.GetFiles(workspace, "*.dylib");
Expand Down Expand Up @@ -152,8 +165,23 @@ public string GenerateXCode(
.Replace("%BundleIdentifier%", projectName);

File.WriteAllText(Path.Combine(binDir, "Info.plist"), plist);

var needEntitlements = entitlements.Count != 0;
cmakeLists = cmakeLists.Replace("%HardenedRuntimeUseEntitlementsFile%",
needEntitlements ? "TRUE" : "FALSE");

File.WriteAllText(Path.Combine(binDir, "CMakeLists.txt"), cmakeLists);

if (needEntitlements) {
var ent = new StringBuilder();
foreach ((var key, var value) in entitlements) {
ent.AppendLine ($"<key>{key}</key>");
ent.AppendLine (value);
}
string entitlementsTemplate = Utils.GetEmbeddedResource("app.entitlements.template");
File.WriteAllText(Path.Combine(binDir, "app.entitlements"), entitlementsTemplate.Replace("%Entitlements%", ent.ToString()));
}

string targetName;
switch (Target)
{
Expand Down

0 comments on commit b7a1648

Please sign in to comment.