diff --git a/clr_loader/__init__.py b/clr_loader/__init__.py index 43bbba3..e5fca2a 100644 --- a/clr_loader/__init__.py +++ b/clr_loader/__init__.py @@ -11,7 +11,6 @@ "get_mono", "get_netfx", "get_coreclr", - "get_coreclr_command_line", "find_dotnet_root", "find_libmono", "find_runtimes", @@ -94,6 +93,7 @@ def get_mono( def get_coreclr( *, runtime_config: Optional[StrOrPath] = None, + entry_dll: Optional[StrOrPath] = None, dotnet_root: Optional[StrOrPath] = None, properties: Optional[Dict[str, str]] = None, runtime_spec: Optional[DotnetCoreRuntimeSpec] = None, @@ -106,9 +106,13 @@ def get_coreclr( the first function object is retrieved. :param runtime_config: - Pass to a ``runtimeconfig.json`` as generated by + Path to a ``runtimeconfig.json`` as generated by ``dotnet publish``. If this parameter is not given, a temporary runtime config will be generated. + :param entry_dll: + The path to the entry dll. If this parameter is given, the runtime will + be initialized using the command line hosting API instead of using the + runtime config. :param dotnet_root: The root directory of the .NET Core installation. If this is not specified, we try to discover it using :py:func:`find_dotnet_root`. @@ -119,6 +123,7 @@ def get_coreclr( If the ``runtime_config`` is not specified, the concrete runtime to use can be controlled by passing this parameter. Possible values can be retrieved using :py:func:`find_runtimes`.""" + from .hostfxr import DotnetCoreRuntime dotnet_root = _maybe_path(dotnet_root) @@ -127,7 +132,9 @@ def get_coreclr( temp_dir = None runtime_config = _maybe_path(runtime_config) - if runtime_config is None: + entry_dll = _maybe_path(entry_dll) + + if runtime_config is None and entry_dll is None: if runtime_spec is None: candidates = [ rt for rt in find_runtimes() if rt.name == "Microsoft.NETCore.App" @@ -144,7 +151,12 @@ def get_coreclr( with open(runtime_config, "w") as f: runtime_spec.write_config(f) - impl = DotnetCoreRuntime(runtime_config=runtime_config, dotnet_root=dotnet_root) + if entry_dll is not None: + entry_dll = _maybe_path(entry_dll) + impl = DotnetCoreRuntime(entry_dll=entry_dll, dotnet_root=dotnet_root) + else: + impl = DotnetCoreRuntime(runtime_config=runtime_config, dotnet_root=dotnet_root) + if properties: for key, value in properties.items(): impl[key] = value @@ -155,41 +167,6 @@ def get_coreclr( return impl -def get_coreclr_command_line( - *, - entry_dll: StrOrPath, - dotnet_root: Optional[StrOrPath] = None, - properties: Optional[Dict[str, str]] = None, -) -> Runtime: - """Get a CoreCLR (.NET Core) runtime instance - The returned ``DotnetCoreRuntimeCommandLine`` also acts as a mapping of the config - properties. They can be retrieved using the index operator and can be - written until the runtime is initialized. The runtime is initialized when - the first function object is retrieved. - :param entry_dll: - The path to the entry dll. - :param dotnet_root: - The root directory of the .NET Core installation. If this is not - specified, we try to discover it using :py:func:`find_dotnet_root`. - :param properties: - Additional runtime properties. These can also be passed using the - ``configProperties`` section in the runtime config.""" - from .hostfxr import DotnetCoreCommandRuntime - - dotnet_root = _maybe_path(dotnet_root) - if dotnet_root is None: - dotnet_root = find_dotnet_root() - - impl = DotnetCoreCommandRuntime( - entry_dll=_maybe_path(entry_dll), dotnet_root=dotnet_root - ) - if properties: - for key, value in properties.items(): - impl[key] = value - - return impl - - def get_netfx( *, domain: Optional[str] = None, config_file: Optional[StrOrPath] = None ) -> Runtime: diff --git a/clr_loader/hostfxr.py b/clr_loader/hostfxr.py index 60ad6b6..e32423c 100644 --- a/clr_loader/hostfxr.py +++ b/clr_loader/hostfxr.py @@ -1,20 +1,27 @@ import sys from pathlib import Path -from typing import Generator, Tuple +from typing import Generator, Tuple, Optional from .ffi import ffi, load_hostfxr from .types import Runtime, RuntimeInfo, StrOrPath from .util import check_result -__all__ = ["DotnetCoreRuntime", "DotnetCoreCommandRuntime"] +__all__ = ["DotnetCoreRuntime"] _IS_SHUTDOWN = False -class DotnetCoreRuntimeBase(Runtime): +class DotnetCoreRuntime(Runtime): _version: str - def __init__(self, dotnet_root: Path): + def __init__( + self, + *, + dotnet_root: Path, + runtime_config: Optional[Path] = None, + entry_dll: Optional[Path] = None, + **params: str, + ): self._handle = None if _IS_SHUTDOWN: @@ -24,6 +31,23 @@ def __init__(self, dotnet_root: Path): self._dll = load_hostfxr(self._dotnet_root) self._load_func = None + if runtime_config is not None: + self._handle = _get_handle_for_runtime_config( + self._dll, self._dotnet_root, runtime_config + ) + elif entry_dll is not None: + self._handle = _get_handle_for_dotnet_command_line( + self._dll, self._dotnet_root, entry_dll + ) + else: + raise ValueError("Either runtime_config or entry_dll must be provided") + + for key, value in params.items(): + self[key] = value + + # TODO: Get version + self._version: str = "" + @property def dotnet_root(self) -> Path: return self._dotnet_root @@ -117,34 +141,6 @@ def info(self): ) -class DotnetCoreRuntime(DotnetCoreRuntimeBase): - def __init__(self, runtime_config: Path, dotnet_root: Path, **params: str): - super().__init__(dotnet_root) - self._handle = _get_handle_for_runtime_config( - self._dll, self._dotnet_root, runtime_config - ) - - for key, value in params.items(): - self[key] = value - - # TODO: Get version - self._version = "" - - -class DotnetCoreCommandRuntime(DotnetCoreRuntimeBase): - def __init__(self, entry_dll: Path, dotnet_root: Path, **params: str): - super().__init__(dotnet_root) - self._handle = _get_handle_for_dotnet_command_line( - self._dll, self._dotnet_root, entry_dll - ) - - for key, value in params.items(): - self[key] = value - - # TODO: Get version - self._version = "" - - def _get_handle_for_runtime_config( dll, dotnet_root: StrOrPath, runtime_config: StrOrPath ): diff --git a/tests/test_common.py b/tests/test_common.py index cf8f400..6561650 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -97,9 +97,9 @@ def test_coreclr_command_line(example_netcore: Path): def _do_test_coreclr_command_line(example_netcore: Path): - from clr_loader import get_coreclr_command_line + from clr_loader import get_coreclr - coreclr = get_coreclr_command_line(entry_dll=example_netcore / "example.dll") + coreclr = get_coreclr(entry_dll=example_netcore / "example.dll") asm = coreclr.get_assembly(example_netcore / "example.dll") run_tests(asm)