-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Hello-NativeAOTFromJNI] Add NativeAOT sample #1153
Merged
Merged
Changes from all commits
Commits
Show all changes
52 commits
Select commit
Hold shift + click to select a range
007317b
[Hello-NativeAOTFromJNI] Add NativeAOT sample
jonpryor db84cc3
Try to create a JreRuntime
jonpryor a32e244
icanhaz blittable method registration?
jonpryor 4c30ab5
Linux builds require -Wl,-soname to be set properly.
jonpryor a08dce8
Fix build break.
jonpryor da9f188
Use [UnmanagedFunctionPointer]
jonpryor 69c90ba
"Full(er)" sample
jonpryor 1fc0af5
Use JniTransition.
jonpryor a499a1d
Allow init from JNIEnv*, not just JavaVM*
jonpryor e1822f0
Make it (mostly) work!
jonpryor 9027591
Fix Java.Interop.Export-Tests
jonpryor 1d422da
Merge remote-tracking branch 'origin/main' into dev/jonp/jonp-hello-f…
jonpryor 902fe28
Remove more `n_`s?!
jonpryor 0392169
Enable activation
jonpryor 93a901a
Allow marking constructors as callable from Java.
jonpryor a50457b
Partially revert 9027591c41232c82a582f8ab16ddaa783795582c
jonpryor ce850ca
Rethink `Type.GetType()` alternatives
jonpryor 6920e6c
Remove need for NativeAotValueManager.
jonpryor 4ceaa34
Merge remote-tracking branch 'origin/main' into dev/jonp/jonp-hello-f…
jonpryor cf73d77
Merge remote-tracking branch 'origin/main' into dev/jonp/jonp-hello-f…
jonpryor 986f0c4
Reduce patch size.
jonpryor 17a4403
Work with .NET 8 GA (…?)
jonpryor 1b86f9a
Use `net.dot.jni` package prefix
jonpryor f71cadb
Forgot to fix up a header path…
jonpryor b5fc4cf
Don't add new public API
jonpryor 4741dc9
Reduce patch size.
jonpryor 8eb2850
Remove more unneeded bits.
jonpryor c3e4870
Merge remote-tracking branch 'origin/main' into dev/jonp/jonp-hello-f…
jonpryor aeed449
Merge remote-tracking branch 'origin/main' into dev/jonp/jonp-hello-f…
jonpryor 1e71988
Remove GetTypeFromAssemblyQualifiedName()
jonpryor 1b7be6c
Merge remote-tracking branch 'origin/main' into dev/jonp/jonp-hello-f…
jonpryor 14f6713
Cleanup.
jonpryor 508dcde
Merge remote-tracking branch 'origin/main' into dev/jonp/jonp-hello-f…
jonpryor 74248fb
Merge remote-tracking branch 'origin/main' into dev/jonp/jonp-hello-f…
jonpryor 12e187e
Fix spelling of JNI_OnUnload
jonpryor cfdfeaf
Reduce unnecessary changes.
jonpryor 0803048
Integrate Hello-NativeAOTFromJNI.csproj into Java.Interop.sln
jonpryor f8bb97f
Cleanup.
jonpryor 12cda04
Run the sample on CI!
jonpryor 3861773
Reduce manual string duplication.
jonpryor adf5773
Remove unnecessary line.
jonpryor 65f7d90
Set publishWebProjects: false.
jonpryor 429bb4d
Try setting workingDirectory.
jonpryor b4cddb7
Setting workingDirectory didn't fix things.
jonpryor 42c7251
$CWD isn't what I expect, so use a rooted WorkingDirectory.
jonpryor f656870
MOAR PRINTFS
jonpryor 1b8b1af
Avoid DotNetCoreCLI@2
jonpryor 59314fc
Cleanup.
jonpryor 2a012c7
Fix some `dotnet publish` linker warnings.
jonpryor f79d3e1
Quote `$(DotnetToolPath)`, as it will contain spaces on Windows.
jonpryor 213a57b
$(Standalone) by default, and prefer `native-library` loader in JreRu…
jonpryor cf240f9
Run the Hello-NativeAOT tests on Windows, too
jonpryor File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using System.Runtime.InteropServices; | ||
|
||
using Java.Interop; | ||
|
||
namespace Hello_NativeAOTFromJNI; | ||
|
||
static class App { | ||
|
||
// symbol name from `$(IntermediateOutputPath)obj/Release/osx-x64/h-classes/net_dot_jni_hello_App.h` | ||
[UnmanagedCallersOnly (EntryPoint="Java_net_dot_jni_hello_App_sayHello")] | ||
static IntPtr sayHello (IntPtr jnienv, IntPtr klass) | ||
{ | ||
var envp = new JniTransition (jnienv); | ||
try { | ||
var s = $"Hello from .NET NativeAOT!"; | ||
Console.WriteLine (s); | ||
var h = JniEnvironment.Strings.NewString (s); | ||
var r = JniEnvironment.References.NewReturnToJniRef (h); | ||
JniObjectReference.Dispose (ref h); | ||
return r; | ||
} | ||
catch (Exception e) { | ||
Console.Error.WriteLine ($"Error in App.sayHello(): {e.ToString ()}"); | ||
envp.SetPendingException (e); | ||
} | ||
finally { | ||
envp.Dispose (); | ||
} | ||
return nint.Zero; | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>$(DotNetTargetFramework)</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<Import Project="..\..\TargetFrameworkDependentValues.props" /> | ||
|
||
<PropertyGroup> | ||
<RootNamespace>Hello_NativeAOTFromJNI</RootNamespace> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<PublishAot>true</PublishAot> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
<NativeLib>Shared</NativeLib> | ||
<!-- Needed for cross-compilation, e.g. build osx-x64 from osx-arm64 --> | ||
<PlatformTarget>AnyCPU</PlatformTarget> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\Java.Interop\Java.Interop.csproj" /> | ||
<ProjectReference Include="..\..\src\Java.Runtime.Environment\Java.Runtime.Environment.csproj" /> | ||
<ProjectReference Include="..\..\src\Java.Base\Java.Base.csproj" /> | ||
<ProjectReference Include="..\..\src\Java.Interop.Export\Java.Interop.Export.csproj" /> | ||
<ProjectReference | ||
Include="..\..\tools\jcw-gen\jcw-gen.csproj" | ||
ReferenceOutputAssembly="false" | ||
/> | ||
<ProjectReference | ||
Include="..\..\tools\jnimarshalmethod-gen\Xamarin.Android.Tools.JniMarshalMethodGenerator.csproj" | ||
ReferenceOutputAssembly="false" | ||
/> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<TrimmerRootAssembly Include="Hello-NativeAOTFromJNI" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Content Include="$(OutputPath)hello-from-java.jar" CopyToPublishDirectory="PreserveNewest" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<HelloNativeAOTFromJNIJar Include="$(MSBuildThisFileDirectory)java\**\*.java" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup Condition=" $([MSBuild]::IsOSPlatform('linux')) Or $([MSBuild]::IsOSPlatform('FreeBSD')) Or $([MSBuild]::IsOSPlatform('Android')) "> | ||
<CustomLinkerArg Include="-Wl,-soname,lib$(NativeBinary)$(NativeBinaryExt)" /> | ||
</ItemGroup> | ||
|
||
<Import Project="Hello-NativeAOTFromJNI.targets" /> | ||
</Project> |
106 changes: 106 additions & 0 deletions
106
samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.targets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
<Project> | ||
|
||
<PropertyGroup> | ||
<DotnetToolPath>"$(DOTNET_HOST_PATH)"</DotnetToolPath> | ||
</PropertyGroup> | ||
|
||
<Target Name="_CreateJavaCallableWrappers" | ||
Condition=" '$(TargetPath)' != '' " | ||
BeforeTargets="BuildNativeAOTFromJNIJar" | ||
Inputs="$(TargetPath)" | ||
Outputs="$(IntermediateOutputPath)java\.stamp"> | ||
<RemoveDir Directories="$(IntermediateOutputPath)java" /> | ||
<MakeDir Directories="$(IntermediateOutputPath)java" /> | ||
<ItemGroup> | ||
<!-- I can't find a good way to trim the trailing `\`, so append with `.` so we can sanely quote for $(_Libpath) --> | ||
<_JcwGenRefAsmDirs Include="@(ReferencePathWithRefAssemblies->'%(RootDir)%(Directory).'->Distinct())" /> | ||
</ItemGroup> | ||
<PropertyGroup> | ||
<_JcwGen>"$(UtilityOutputFullPath)/jcw-gen.dll"</_JcwGen> | ||
<_Target>--codegen-target JavaInterop1</_Target> | ||
<_Output>-o "$(IntermediateOutputPath)/java"</_Output> | ||
<_Libpath>@(_JcwGenRefAsmDirs->'-L "%(Identity)"', ' ')</_Libpath> | ||
</PropertyGroup> | ||
<Exec Command="$(DotnetToolPath) $(_JcwGen) "$(TargetPath)" $(_Target) $(_Output) $(_Libpath)" /> | ||
<Touch Files="$(IntermediateOutputPath)java\.stamp" AlwaysCreate="True" /> | ||
</Target> | ||
|
||
<Target Name="_AddMarshalMethods" | ||
Condition=" '$(TargetPath)' != '' " | ||
Inputs="$(TargetPath)" | ||
Outputs="$(IntermediateOutputPath).added-marshal-methods" | ||
AfterTargets="_CreateJavaCallableWrappers"> | ||
<ItemGroup> | ||
<!-- I can't find a good way to trim the trailing `\`, so append with `.` so we can sanely quote for $(_Libpath) --> | ||
<_JnimmRefAsmDirs Include="@(RuntimePackAsset->'%(RootDir)%(Directory).'->Distinct())" /> | ||
</ItemGroup> | ||
<PropertyGroup> | ||
<_JnimarshalmethodGen>"$(UtilityOutputFullPath)/jnimarshalmethod-gen.dll"</_JnimarshalmethodGen> | ||
<_Verbosity>-v -v --keeptemp</_Verbosity> | ||
<_Libpath>-L "$(TargetDir)" @(_JnimmRefAsmDirs->'-L "%(Identity)"', ' ')</_Libpath> | ||
<!-- <_Output>-o "$(IntermediateOutputPath)/jonp"</_Output> --> | ||
</PropertyGroup> | ||
|
||
<Exec Command="$(DotnetToolPath) $(_JnimarshalmethodGen) "$(TargetPath)" $(_Verbosity) $(_Libpath)" /> | ||
|
||
<!-- the IlcCompile target uses files from `$(IntermediateOutputPath)`, not `$(TargetPath)`, so… update both? --> | ||
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(IntermediateOutputPath)" /> | ||
|
||
<Touch Files="$(IntermediateOutputPath).added-marshal-methods" AlwaysCreate="True" /> | ||
</Target> | ||
|
||
<Target Name="BuildNativeAOTFromJNIJar" | ||
AfterTargets="Build" | ||
Inputs="@(HelloNativeAOTFromJNIJar)" | ||
Outputs="$(OutputPath)hello-from-java.jar"> | ||
<MakeDir Directories="$(IntermediateOutputPath)h-classes" /> | ||
<ItemGroup> | ||
<_JcwSource Include="$(IntermediateOutputPath)java\**\*.java" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<_Source Include="@(_JcwSource->Replace('%5c', '/'))" /> | ||
<_Source Include="@(HelloNativeAOTFromJNIJar->Replace('%5c', '/'))" /> | ||
</ItemGroup> | ||
<WriteLinesToFile | ||
File="$(IntermediateOutputPath)_java_sources.txt" | ||
Lines="@(_Source)" | ||
Overwrite="True" | ||
/> | ||
<ItemGroup> | ||
<_JavacOpt Include="$(_JavacSourceOptions)" /> | ||
<_JavacOpt Include="-d "$(IntermediateOutputPath)h-classes" " /> | ||
<_JavacOpt Include="-classpath "$(OutputPath)java-interop.jar" " /> | ||
<_JavacOpt Include=""@$(IntermediateOutputPath)_java_sources.txt"" /> | ||
<_JavacOpt Include="-h "$(IntermediateOutputPath)h-classes" " /> | ||
</ItemGroup> | ||
<Exec Command=""$(JavaCPath)" @(_JavacOpt, ' ')" /> | ||
<Delete Files="$(IntermediateOutputPath)_java_sources.txt" /> | ||
<Exec Command=""$(JarPath)" cf "$(OutputPath)hello-from-java.jar" -C "$(IntermediateOutputPath)h-classes" ." /> | ||
</Target> | ||
|
||
<Target Name="_NativeLibRequiresLibPrefix" | ||
AfterTargets="Publish"> | ||
<Copy | ||
Condition=" '$(OS)' != 'Windows_NT' " | ||
SourceFiles="$(PublishDir)$(AssemblyName).dylib" | ||
DestinationFiles="$(PublishDir)lib$(AssemblyName).dylib" | ||
/> | ||
<Copy SourceFiles="$(OutputPath)hello-from-java.jar" DestinationFolder="$(PublishDir)" /> | ||
</Target> | ||
|
||
<Target Name="RunJavaSample"> | ||
<ItemGroup> | ||
<_Classpath Include="hello-from-java.jar" /> | ||
<_Classpath Include="java-interop.jar" /> | ||
</ItemGroup> | ||
<PropertyGroup> | ||
<_CPSep Condition=" '$(OS)' == 'Windows_NT' ">;</_CPSep> | ||
<_CPSep Condition=" '$(_CPSep)' == '' ">:</_CPSep> | ||
<_CP>@(_Classpath, '$(_CPSep)')</_CP> | ||
</PropertyGroup> | ||
<Exec | ||
Command=""$(JavaPath)" -classpath "$(_CP)" net/dot/jni/hello/App" | ||
WorkingDirectory="$(MSBuildThisFileDirectory)$(PublishDir)" | ||
/> | ||
</Target> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using System.Runtime.InteropServices; | ||
|
||
using Java.Interop; | ||
|
||
namespace Hello_NativeAOTFromJNI; | ||
|
||
static class JavaInteropRuntime | ||
{ | ||
static JniRuntime? runtime; | ||
|
||
[UnmanagedCallersOnly (EntryPoint="JNI_OnLoad")] | ||
static int JNI_OnLoad (IntPtr vm, IntPtr reserved) | ||
{ | ||
return (int) JniVersion.v1_6; | ||
} | ||
|
||
[UnmanagedCallersOnly (EntryPoint="JNI_OnUnload")] | ||
static void JNI_OnUnload (IntPtr vm, IntPtr reserved) | ||
{ | ||
runtime?.Dispose (); | ||
} | ||
|
||
// symbol name from `$(IntermediateOutputPath)obj/Release/osx-arm64/h-classes/net_dot_jni_hello_JavaInteropRuntime.h` | ||
[UnmanagedCallersOnly (EntryPoint="Java_net_dot_jni_hello_JavaInteropRuntime_init")] | ||
static void init (IntPtr jnienv, IntPtr klass) | ||
{ | ||
Console.WriteLine ($"C# init()"); | ||
try { | ||
var options = new JreRuntimeOptions { | ||
EnvironmentPointer = jnienv, | ||
TypeManager = new NativeAotTypeManager (), | ||
UseMarshalMemberBuilder = false, | ||
}; | ||
runtime = options.CreateJreVM (); | ||
} | ||
catch (Exception e) { | ||
Console.Error.WriteLine ($"JavaInteropRuntime.init: error: {e}"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
namespace Example; | ||
|
||
using Java.Interop; | ||
|
||
[JniTypeSignature (JniTypeName)] | ||
class ManagedType : Java.Lang.Object { | ||
internal const string JniTypeName = "example/ManagedType"; | ||
|
||
[JavaCallableConstructor(SuperConstructorExpression="")] | ||
public ManagedType (int value) | ||
{ | ||
this.value = value; | ||
} | ||
|
||
int value; | ||
|
||
[JavaCallable ("getString")] | ||
public Java.Lang.String GetString () | ||
{ | ||
return new Java.Lang.String ($"Hello from C#, via Java.Interop! Value={value}"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using Java.Interop; | ||
|
||
namespace Hello_NativeAOTFromJNI; | ||
|
||
class NativeAotTypeManager : JniRuntime.JniTypeManager { | ||
|
||
#pragma warning disable IL2026 | ||
Dictionary<string, Type> typeMappings = new () { | ||
[Example.ManagedType.JniTypeName] = typeof (Example.ManagedType), | ||
}; | ||
#pragma warning restore IL2026 | ||
|
||
|
||
protected override IEnumerable<Type> GetTypesForSimpleReference (string jniSimpleReference) | ||
{ | ||
if (typeMappings.TryGetValue (jniSimpleReference, out var target)) | ||
yield return target; | ||
foreach (var t in base.GetTypesForSimpleReference (jniSimpleReference)) | ||
yield return t; | ||
} | ||
|
||
protected override IEnumerable<string> GetSimpleReferences (Type type) | ||
{ | ||
return base.GetSimpleReferences (type) | ||
.Concat (CreateSimpleReferencesEnumerator (type)); | ||
} | ||
|
||
IEnumerable<string> CreateSimpleReferencesEnumerator (Type type) | ||
{ | ||
if (typeMappings == null) | ||
yield break; | ||
foreach (var e in typeMappings) { | ||
if (e.Value == type) | ||
yield return e.Key; | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these actually need to be
powershell
or can they bescript
? I thinkscript
would be the same as cmd on Windows and bash on macOS.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea, I'm just going with @akoeplinger 's suggestion on Discord.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are only testing
osx-x64
here. Should this PR work on Windows?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conditioning this off a display name seems brittle, we probably want:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
script
would work since the command is the same i.e. it doesn't matter whether cmd or bash is used but I agree that this should probably only execute on Mac.