diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1450454..36426c2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -3,18 +3,14 @@
name: Python Tests
-on:
- push:
- branches: [ master ]
- pull_request:
- branches: [ master ]
+on: [push, pull_request]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [ubuntu-latest, windows-latest] # macos-latest
+ os: [ubuntu-latest, windows-latest, macos-latest]
python: ['3.9', '3.8', '3.7', '3.6', pypy3]
steps:
diff --git a/clr_loader/__init__.py b/clr_loader/__init__.py
index 3616345..a67f4a9 100644
--- a/clr_loader/__init__.py
+++ b/clr_loader/__init__.py
@@ -50,7 +50,7 @@ def __getitem__(self, path):
return self.get_assembly(path)
-def get_mono(domain=None):
+def get_mono(domain=None, config_file=None, path=None, gc=None):
from .mono import Mono
impl = Mono(domain=domain)
diff --git a/clr_loader/ffi/__init__.py b/clr_loader/ffi/__init__.py
index 7befd2d..d1daa11 100644
--- a/clr_loader/ffi/__init__.py
+++ b/clr_loader/ffi/__init__.py
@@ -36,7 +36,9 @@ def load_hostfxr(dotnet_root):
def load_mono(path=None, gc=None):
# Preload C++ standard library, Mono needs that and doesn't properly link against it
- ffi.dlopen("stdc++", ffi.RTLD_GLOBAL)
+ if sys.platform.startswith("linux"):
+ ffi.dlopen("stdc++", ffi.RTLD_GLOBAL)
+
if path is None:
from ctypes.util import find_library
diff --git a/clr_loader/hostfxr.py b/clr_loader/hostfxr.py
index 00e6aa4..6709908 100644
--- a/clr_loader/hostfxr.py
+++ b/clr_loader/hostfxr.py
@@ -16,13 +16,28 @@ def __init__(self, runtime_config, dotnet_root=None):
if not dotnet_root:
dotnet_root = os.environ.get("DOTNET_ROOT", None)
+ if not dotnet_root and sys.platform == 'win32':
+ # On Windows, the host library is stored separately from dotnet.exe for x86
+ if sys.maxsize > 2 ** 32:
+ possible_root = os.path.join(os.environ.get("ProgramFiles"), "dotnet")
+ else:
+ possible_root = os.path.join(os.environ.get("ProgramFiles(x86)"), "dotnet")
+
+ if os.path.isdir(possible_root):
+ dotnet_root = possible_root
+
if not dotnet_root:
dotnet_path = shutil.which("dotnet")
if not dotnet_path:
raise RuntimeError("Can not determine dotnet root")
try:
- dotnet_tmp_path = os.readlink(dotnet_path)
+ # Pypy does not provide os.readlink right now
+ if hasattr(os, "readlink"):
+ dotnet_tmp_path = os.readlink(dotnet_path)
+ else:
+ dotnet_tmp_path = dotnet_path
+
if os.path.isabs(dotnet_tmp_path):
dotnet_path = dotnet_tmp_path
else:
diff --git a/clr_loader/mono.py b/clr_loader/mono.py
index f85f096..c5d2f6a 100644
--- a/clr_loader/mono.py
+++ b/clr_loader/mono.py
@@ -11,9 +11,9 @@
class Mono:
- def __init__(self, domain=None, config_file=None):
+ def __init__(self, domain=None, config_file=None, path=None, gc=None):
self._assemblies = {}
- initialize(config_file=config_file)
+ initialize(config_file=config_file, path=path, gc=gc)
if domain is None:
self._domain = _ROOT_DOMAIN
@@ -84,7 +84,7 @@ def initialize(config_file, path=None, gc=None):
global _MONO, _ROOT_DOMAIN
if _MONO is None:
_MONO = load_mono(path=path, gc=gc)
-
+
if config_file is None:
config_file = ffi.NULL
else:
diff --git a/example/example.csproj b/example/example.csproj
index d7763f1..f30cfb7 100644
--- a/example/example.csproj
+++ b/example/example.csproj
@@ -3,4 +3,10 @@
netcoreapp31;netstandard20
true
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
diff --git a/tests/test_common.py b/tests/test_common.py
index aa420e4..7788d34 100644
--- a/tests/test_common.py
+++ b/tests/test_common.py
@@ -1,33 +1,51 @@
import pytest
from subprocess import check_call
import os
-from cffi import FFI
-NULL = FFI().NULL
+import sys
+
+
+@pytest.fixture(scope="session")
+def example_netstandard(tmpdir_factory):
+ return build_example(tmpdir_factory, "netstandard20")
@pytest.fixture(scope="session")
-def example_dll(tmpdir_factory):
- out = str(tmpdir_factory.mktemp("example"))
+def example_netcore(tmpdir_factory):
+ return build_example(tmpdir_factory, "netcoreapp31")
+
+def build_example(tmpdir_factory, framework):
+ out = str(tmpdir_factory.mktemp(f"example-{framework}"))
proj_path = os.path.join(os.path.dirname(__file__), "../example")
- check_call(["dotnet", "build", proj_path, "-o", out, "-f", "netcoreapp31"])
+ check_call(["dotnet", "build", proj_path, "-o", out, "-f", framework])
return out
-def test_mono(example_dll):
+@pytest.mark.xfail
+def test_mono(example_netstandard):
from clr_loader import get_mono
mono = get_mono()
- asm = mono.get_assembly(os.path.join(example_dll, "example.dll"))
+ asm = mono.get_assembly(os.path.join(example_netstandard, "example.dll"))
run_tests(asm)
-def test_coreclr(example_dll):
+def test_coreclr(example_netcore):
from clr_loader import get_coreclr
- coreclr = get_coreclr(os.path.join(example_dll, "example.runtimeconfig.json"))
- asm = coreclr.get_assembly(os.path.join(example_dll, "example.dll"))
+ coreclr = get_coreclr(os.path.join(example_netcore, "example.runtimeconfig.json"))
+ asm = coreclr.get_assembly(os.path.join(example_netcore, "example.dll"))
+
+ run_tests(asm)
+
+
+@pytest.mark.skipif(sys.platform != 'win32', reason=".NET Framework only exists on Windows")
+def test_netfx(example_netstandard):
+ from clr_loader import get_netfx
+
+ netfx = get_netfx()
+ asm = netfx.get_assembly(os.path.join(example_netstandard, "example.dll"))
run_tests(asm)