Skip to content
← Back

src/driver/path_config.ghul

1
namespace Driver is
2
use System.Runtime.InteropServices.RuntimeInformation
3
use System.Runtime.InteropServices.OSPlatform
4
use System.Runtime.InteropServices.Architecture
5
6
use IO.Std
7
8
use Collections.Iterable
9
use Collections.LIST
10
11
use Ghul.Pipes
12
13
class PATH_CONFIG is
14
_default_library_prefix: string
15
_library_prefix: string?
16
17
install_folder: string
18
19
// The .NET reference-assembly directory. Either supplied by the build
20
// via `--sdk-ref-path`, or filled in by auto-discovery when the
21
// compiler is invoked with source files alone. Only consulted when no
22
// assemblies are passed with `-a`; MSBuild builds pass the full
23
// resolved reference set and never reach either route. The
24
// auto-discovered value is written back here so the target-framework
25
// resolver can pick it up when generating `.runtimeconfig.json`.
26
sdk_reference_path: string? public
27
28
// Explicit override from the `--target-framework` flag, used when
29
// deriving the .runtimeconfig.json moniker beside the compiled binary.
30
// Wins over inference from `sdk_reference_path` and the host TFM.
31
target_framework: string? public
32
33
_host_target_framework: string?
34
_host_target_framework_resolved: bool
35
36
// The TFM the compiler was itself built for, read from its own
37
// .runtimeconfig.json (sibling of the executing assembly). Cached.
38
// Returns null when the file is missing or doesn't contain a "tfm"
39
// field — the resolver chain falls back to a hardcoded default.
40
host_target_framework: string? public is
41
if _host_target_framework_resolved then
42
return _host_target_framework
43
fi
44
45
_host_target_framework_resolved = true
46
47
let executing_assembly = System.Reflection.Assembly.get_executing_assembly()
48
let assembly_path = IO.Path.get_full_path(executing_assembly.location)
49
let directory = IO.Path.get_directory_name(assembly_path)
50
let name = IO.Path.get_file_name_without_extension(assembly_path)
51
let config_path = IO.Path.join(directory, "{name}.runtimeconfig.json")
52
53
if !IO.File.exists(config_path) then
54
return null
55
fi
56
57
try
58
_host_target_framework = TARGET_FRAMEWORK_RESOLVER().extract_tfm(IO.File.read_all_text(config_path))
59
catch ex: System.Exception
60
_host_target_framework = null
61
yrt
62
63
return _host_target_framework
64
si
65
66
library_prefix: string public =>
67
if _library_prefix? then
68
_library_prefix
69
else
70
_default_library_prefix
71
fi,
72
= value is
73
_library_prefix = value
74
75
if !library_prefix.ends_with('/') then
76
library_prefix = "{library_prefix}/"
77
fi
78
si
79
80
init() is
81
super.init()
82
83
let executing_assembly = System.Reflection.Assembly.get_executing_assembly()
84
85
let assembly_path = IO.Path.get_full_path(executing_assembly.location)
86
87
install_folder = IO.Path.get_directory_name(assembly_path) ?? "."
88
89
if !install_folder.ends_with('/') then
90
install_folder = "{install_folder}/"
91
fi
92
93
_default_library_prefix = "{install_folder}lib/"
94
95
si
96
97
98
get_library_location(directory: string mut) -> string is
99
if !directory.starts_with('/') then
100
directory = "{library_prefix}{directory}"
101
fi
102
103
if !directory.ends_with('/') then
104
directory = "{directory}/"
105
fi
106
107
return directory
108
si
109
110
111
// Auto-discover the .NET reference-assembly directory. Called when the
112
// compiler is invoked with source files but no -a or --sdk-ref-path, so
113
// a user can run `ghul-compiler hello.ghul` without a .ghulproj.
114
//
115
// The moniker is chosen in the same order the target-framework resolver
116
// uses when it writes the .runtimeconfig.json beside the binary, so the
117
// reference assemblies compiled against are the ones the program will
118
// then ask to run on. A requested framework with no matching ref pack
119
// resolves to nothing, and surfaces as the no-reference-assemblies
120
// error rather than a silent mismatch.
121
discover_sdk_reference_path() -> string? =>
122
SDK_REFERENCE_PATH_RESOLVER().resolve(
123
target_framework ?? host_target_framework ?? "net10.0")
124
si
125
si