pythonnet / clr-loader

Loader for different .NET runtimes
MIT License
32 stars 22 forks source link

Implement support for self-contained .NET project #20

Open filmor opened 2 years ago

filmor commented 2 years ago

Example project available in previous pythonnet issue.

filmor commented 2 years ago

Related issues and PRs:

https://github.com/dotnet/runtime/issues/35465 https://github.com/dotnet/runtime/issues/39167 https://github.com/dotnet/runtime/pull/36990

vgibilmanno commented 1 year ago

I found a neat workaround to run .NET projects in a self-contained manner which could suffice for most people encountering this issue. What we need to do is to bring dotnet by ourselves.

Example:

Because we are bringing all dotnet libraries already, we don't need to build our project as self-contained. Normally building the project is enough. This is how I call it in pythonnet

import os
from pythonnet import load

dotnet_root = os.path.abspath('./my-dotnet-directory')
runtime_config = os.path.abspath('runtimeconfig.json')
load("coreclr", dotnet_root=dotnet_root, runtime_config=runtime_config)

import clr
import os

clr.AddReference(os.path.abspath('./my-project/my-project.dll'))

from MyProject import Program
program = Program()
program.ExecuteSync()

This way I'm able to run my application as 'self-contained'

runtimeconfig.json:

{"runtimeOptions": {"tfm": "net6.0", "framework": {"name": "Microsoft.NETCore.App", "version": "6.0.11"}}}
rishky-msft commented 1 year ago

I found a neat workaround to run .NET projects in a self-contained manner which could suffice for most people encountering this issue. What we need to do is to bring dotnet by ourselves.

Example:

  • my-dotnet-directory

    • libhostfxr.so

    • shared

    • Microsoft.NETCore.App

      • 6.0.11

      • ...files

Because we are bringing all dotnet libraries already, we don't need to build our project as self-contained. Normally building the project is enough. This is how I call it in pythonnet

import os
from pythonnet import load

dotnet_root = os.path.abspath('./my-dotnet-directory')
runtime_config = os.path.abspath('runtimeconfig.json')
load("coreclr", dotnet_root=dotnet_root, runtime_config=runtime_config)

import clr
import os

clr.AddReference(os.path.abspath('./my-project/my-project.dll'))

from MyProject import Program
program = Program()
program.ExecuteSync()

This way I'm able to run my application as 'self-contained'

runtimeconfig.json:

{"runtimeOptions": {"tfm": "net6.0", "framework": {"name": "Microsoft.NETCore.App", "version": "6.0.11"}}}

@vgibilmanno Are you able to run this in linux? I am trying in Ubuntu

vgibilmanno commented 1 year ago

@rishky-msft I'm able to run this on Debian 11 and Windows 11. It should work on Ubuntu too since it is based on Debian

sherryyshi commented 1 year ago

Why is this only a "workaround"? What are the limitations/risks of doing this?

adwenn commented 2 months ago

I just wanted to add a note about this workaround that was working fine in the past but now it seemed to stop working on my macbook M1. I did the test with NET8. I was getting an error. It was complaining that it couldn't find the dotnet-root folder. So after some trail and error i noticed an issue with the folder structure. see the example below. Example:

• my-dotnet-directory

    • libhostfxr.so

    • shared

        • shared

            • Microsoft.NETCore.App

                • 6.0.11

                    ...files

As you can see there is a 'shared' directory within the 'shared' directory in my case this works now.

The runtimeconfig.json is still the same:

{"runtimeOptions": {"tfm": "net8.0", "framework": {"name": "Microsoft.NETCore.App", "version": "8.0.1"}}}

If anyone has a better solution to this. Please let us know.