Skip to content

Commit

Permalink
Merge pull request #161 from iuribrindeiro/dotnet-platform-example
Browse files Browse the repository at this point in the history
Dotnet platform example
  • Loading branch information
Anton-4 authored Mar 20, 2024
2 parents 510d4ce + 7bf509e commit bfc3bfc
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ examples/Tuples/main
roc_nightly/

# macOS directory attributes
.DS_Store
.DS_Store
3 changes: 3 additions & 0 deletions ci_scripts/all_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,6 @@ cd ./examples/GoPlatform
go build ./platform/main.go
cd ../..
expect ci_scripts/expect_scripts/GoPlatform.exp

$ROC build ./examples/DotNetPlatform/main.roc --lib --output ./examples/DotNetPlatform/platform/interop
expect ci_scripts/expect_scripts/DotNetPlatform.exp
20 changes: 20 additions & 0 deletions ci_scripts/expect_scripts/DotNetPlatform.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/expect

# uncomment line below for debugging
# exp_internal 1

set timeout 25

cd "./examples/DotNetPlatform/platform/"

spawn dotnet run

expect "Hello from .NET!\r\n" {
expect "Hi from roc! (in a .NET platform) 🔥🦅🔥\r\n" {
expect eof
exit 0
}
}

puts stderr "\nError: output was different from expected value."
exit 1
6 changes: 6 additions & 0 deletions examples/DotNetPlatform/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# publish and debug artifacts
bin
obj
platform/publish

interop.*
60 changes: 60 additions & 0 deletions examples/DotNetPlatform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# DotNet Platform

A minimal .NET platform

## Full Code

main.roc:
```roc
file:main.roc
```

platform/main.roc:
```
file:platform/main.roc
```

platform/DotNetRocPlatform.csproj:
```
file:platform/DotNetRocPlatform.csproj
```

platform/Program.cs:
```
file:platform/Program.cs
```

## Build & Run

1. Build the roc app that is using the dotnet platform:

```cli
cd examples/DotNetPlatform/
roc build main.roc --lib --output ./platform/interop
```
> _use `arch -arm64` if you are running in a Apple Silicon mac._
This will produce a shared library file that we'll be able to import from a .NET context.

To run:
```cli
cd platform
dotnet run
```
This should print "Hello from .NET".


## Build & Run Binary

If you want to build a binary for the app using native AOT:

1. Publish the dotnet app
```cli
dotnet publish -c Release
```
> _use `arch -arm64` if you are running in a Apple Silicon mac._
2. `cd` into the into the `publish` folder and run the binary:
```cli
./DotNetRocPlatform
```
6 changes: 6 additions & 0 deletions examples/DotNetPlatform/main.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
app "dotnetapp"
packages { platform: "./platform/main.roc" }
imports []
provides [main] to platform

main = "Hi from roc! (in a .NET platform) 🔥🦅🔥"
16 changes: 16 additions & 0 deletions examples/DotNetPlatform/platform/DotNetRocPlatform.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PublishAot>true</PublishAot>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<None Update="interop.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
46 changes: 46 additions & 0 deletions examples/DotNetPlatform/platform/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using static System.Console;
using static Platform;

NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), CustomResolver);

WriteLine("Hello from .NET!");

MainFromRoc(out var rocStr);

WriteLine(rocStr);

//Load native library even when the name doesn't exactly match the name of the library defined in `LibraryImport`
//eg: `interop.so.1.0` instead of `interop.so`
static IntPtr CustomResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
var libFile = Directory
.EnumerateFiles(Directory.GetCurrentDirectory())
.FirstOrDefault(e => e.Contains(libraryName));

if (libFile != null)
{
return NativeLibrary.Load(libFile, assembly, searchPath);
}

return IntPtr.Zero;
}

public static partial class Platform
{
[LibraryImport("interop", EntryPoint = "roc__mainForHost_1_exposed_generic")]
internal static partial void MainFromRoc(out RocStr rocStr);
}

public unsafe struct RocStr
{
public byte* Bytes;
public UIntPtr Len;
public UIntPtr Capacity;

public override string ToString() => Encoding.UTF8.GetString(Bytes, (int)Len.ToUInt32());

public static implicit operator string(RocStr rocStr) => rocStr.ToString();
}
9 changes: 9 additions & 0 deletions examples/DotNetPlatform/platform/main.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
platform "dotnetplatform"
requires {} { main : Str }
exposes []
packages {}
imports []
provides [mainForHost]

mainForHost : Str
mainForHost = main
5 changes: 5 additions & 0 deletions examples/GoPlatform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ main.roc:
file:main.roc
```

platform/main.roc:
```
file:platform/main.roc
```

platform/go.mod:
```
file:platform/go.mod
Expand Down
1 change: 1 addition & 0 deletions examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ You can find the source code for all of these at [github.com/roc-lang/examples](
- [Record Builder](/RecordBuilder/README.html)
- [Multi-line Comments](/MultiLineComments/README.html)
- [Go Platform](/GoPlatform/README.html)
- [.NET Platform](/DotNetPlatform/README.html)

## External examples

Expand Down
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
customRust # for static-site-gen platform
perl # for ci/update_basic_cli_url.sh
go # for GoPlatform example
dotnet-sdk_8 # for DotnetPlatform example
] ++ linuxInputs;

# nix does not store libs in /usr/lib or /lib
Expand Down

0 comments on commit bfc3bfc

Please sign in to comment.