Skip to content

Commit 9c95556

Browse files
gh-110: Link extensions against a shared runtime DLL.
1 parent 6b70c2e commit 9c95556

File tree

3 files changed

+222
-14
lines changed

3 files changed

+222
-14
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Ignore binaries (both executables and libraries)
22
*.exe
33
*.app
4+
*.lib
45
*.dll
56
*.so
67
*.dylib

build.ps1

Lines changed: 74 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<#
22
build.ps1
3-
Compiles the interpreter in a temporary directory and copies the resulting EXE
4-
back into this repo. Also discovers extension C sources under ext/ and lib/
5-
and compiles each one into a dynamic library next to its source file.
3+
Compiles the Prefix runtime into a shared DLL, links the interpreter EXE
4+
against that DLL's import library, and compiles each discovered extension
5+
against the same shared runtime.
66
77
Requires: run from a Developer Command Prompt for Visual Studio where cl.exe is on PATH.
88
Usage (from Prefix-C folder):
@@ -11,6 +11,13 @@ Usage (from Prefix-C folder):
1111

1212
$script = Split-Path -Parent $MyInvocation.MyCommand.Definition
1313
$src = Join-Path $script "src"
14+
$runtimeDef = Join-Path $src "prefix_runtime.def"
15+
$runtimeDllName = "prefix_runtime.dll"
16+
$runtimeLibName = "prefix_runtime.lib"
17+
$runtimePdbName = "prefix_runtime.pdb"
18+
$runtimeDllDest = Join-Path $script $runtimeDllName
19+
$runtimeLibDest = Join-Path $script $runtimeLibName
20+
$runtimePdbDest = Join-Path $script $runtimePdbName
1421
$extRoots = @(
1522
(Join-Path $script "ext"),
1623
(Join-Path $script "lib"),
@@ -37,6 +44,26 @@ if ($cFiles.Count -eq 0) {
3744
exit 1
3845
}
3946

47+
if (-not (Test-Path $runtimeDef)) {
48+
Write-Error "Runtime export definition not found: $runtimeDef"
49+
Remove-Item -Recurse -Force $buildDir -ErrorAction SilentlyContinue
50+
exit 1
51+
}
52+
53+
$mainSource = Join-Path $src "main.c"
54+
if (-not (Test-Path $mainSource)) {
55+
Write-Error "Main source not found: $mainSource"
56+
Remove-Item -Recurse -Force $buildDir -ErrorAction SilentlyContinue
57+
exit 1
58+
}
59+
60+
$runtimeSources = @($cFiles | Where-Object { $_ -ne $mainSource })
61+
if ($runtimeSources.Count -eq 0) {
62+
Write-Error "No runtime sources found after excluding '$mainSource'"
63+
Remove-Item -Recurse -Force $buildDir -ErrorAction SilentlyContinue
64+
exit 1
65+
}
66+
4067
$platform = [System.Runtime.InteropServices.RuntimeInformation]
4168
$extSuffix = ".dll"
4269
if ($platform::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Linux)) {
@@ -47,11 +74,50 @@ if ($platform::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Linux))
4774

4875
Push-Location $buildDir
4976
try {
77+
$runtimeArgs = @(
78+
"/std:c17", "/Gd", "/O2", "/Gy", "/GF", "/GL", "/W4", "/WX", "/MP", "/nologo",
79+
"/LD", "/I$src",
80+
"/Fe:$runtimeDllName"
81+
)
82+
$runtimeArgs += $runtimeSources
83+
$runtimeArgs += @(
84+
"/link",
85+
"/DEF:$runtimeDef",
86+
"/IMPLIB:$runtimeLibName"
87+
)
88+
89+
Write-Host "Invoking: cl.exe $($runtimeArgs -join ' ')"
90+
& cl.exe @runtimeArgs
91+
if ($LASTEXITCODE -ne 0) {
92+
throw "cl.exe returned exit code $LASTEXITCODE while building shared runtime"
93+
}
94+
95+
$runtimeDllPath = Join-Path $buildDir $runtimeDllName
96+
$runtimeLibPath = Join-Path $buildDir $runtimeLibName
97+
$runtimePdbPath = Join-Path $buildDir $runtimePdbName
98+
99+
if (-not (Test-Path $runtimeDllPath)) {
100+
throw "Expected runtime DLL not found: $runtimeDllPath"
101+
}
102+
if (-not (Test-Path $runtimeLibPath)) {
103+
throw "Expected runtime import library not found: $runtimeLibPath"
104+
}
105+
106+
Copy-Item -Path $runtimeDllPath -Destination $runtimeDllDest -Force
107+
Copy-Item -Path $runtimeLibPath -Destination $runtimeLibDest -Force
108+
if (Test-Path $runtimePdbPath) {
109+
Copy-Item -Path $runtimePdbPath -Destination $runtimePdbDest -Force
110+
}
111+
Write-Host "Copied runtime DLL to: $runtimeDllDest"
112+
Write-Host "Copied runtime import library to: $runtimeLibDest"
113+
50114
$exeArgs = @(
51115
"/std:c17", "/Gd", "/O2", "/Gy", "/GF", "/GL", "/W4", "/WX", "/MP", "/nologo",
52-
"/Fe:prefix.exe"
116+
"/I$src",
117+
"/Fe:prefix.exe",
118+
$mainSource,
119+
$runtimeLibPath
53120
)
54-
$exeArgs += $cFiles
55121

56122
Write-Host "Invoking: cl.exe $($exeArgs -join ' ')"
57123
& cl.exe @exeArgs
@@ -95,16 +161,10 @@ try {
95161
"/std:c17", "/Gd", "/O2", "/W4", "/WX", "/nologo", "/LD", "/LTCG",
96162
"/I$src",
97163
"/Fe:$extOutName",
98-
$extSourcePath
164+
$extSourcePath,
165+
$runtimeLibPath
99166
)
100167

101-
# Link the object files produced when building the main interpreter
102-
# so extensions can resolve internal runtime symbols (value_* helpers).
103-
$objFiles = Get-ChildItem -Path $buildDir -Filter *.obj -File -Recurse | ForEach-Object { $_.FullName }
104-
if ($objFiles.Count -gt 0) {
105-
$extArgs += $objFiles
106-
}
107-
108168
Write-Host "Invoking: cl.exe $($extArgs -join ' ')"
109169
& cl.exe @extArgs
110170
if ($LASTEXITCODE -ne 0) {
@@ -132,5 +192,5 @@ try {
132192
Remove-Item -Recurse -Force $buildDir -ErrorAction SilentlyContinue
133193
}
134194

135-
Write-Host "Build succeeded and exe copied to: $(Join-Path $script 'prefix.exe')"
195+
Write-Host "Build succeeded and artifacts copied to: $(Join-Path $script 'prefix.exe'), $runtimeDllDest, $runtimeLibDest"
136196
exit 0

src/prefix_runtime.def

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
LIBRARY prefix_runtime
2+
EXPORTS
3+
expr_bool
4+
expr_int
5+
expr_flt
6+
expr_str
7+
expr_ptr
8+
expr_ident
9+
expr_typed_ident
10+
expr_call
11+
call_kw_add
12+
expr_tns
13+
expr_async
14+
expr_map
15+
expr_index
16+
expr_range
17+
expr_wildcard
18+
expr_lambda
19+
expr_list_add
20+
stmt_block
21+
stmt_async
22+
stmt_expr
23+
stmt_assign
24+
stmt_decl
25+
stmt_if
26+
stmt_while
27+
stmt_for
28+
stmt_parfor
29+
stmt_func
30+
stmt_return
31+
stmt_pop
32+
stmt_break
33+
stmt_continue
34+
stmt_thr
35+
stmt_try
36+
stmt_goto
37+
stmt_gotopoint
38+
stmt_list_add
39+
param_list_add
40+
stmt_set_src
41+
free_expr
42+
free_stmt
43+
builtins_init
44+
builtins_set_argv
45+
builtin_lookup
46+
is_builtin
47+
builtins_register_operator
48+
builtins_reset_dynamic
49+
env_create
50+
env_retain
51+
env_free
52+
env_define
53+
env_assign
54+
env_get
55+
env_delete
56+
env_exists
57+
env_get_entry
58+
env_set_alias
59+
env_set_alias_cross
60+
env_entry_initialized
61+
env_entry_value_copy
62+
env_entry_frozen_state_local
63+
env_freeze
64+
env_thaw
65+
env_permafreeze
66+
env_frozen_state
67+
env_permafrozen
68+
env_define_direct
69+
env_assign_direct
70+
env_delete_direct
71+
env_set_alias_direct
72+
env_freeze_direct
73+
env_thaw_direct
74+
env_permafreeze_direct
75+
extensions_set_runtime_dirs
76+
extensions_load_library
77+
extensions_load_named
78+
extensions_shutdown
79+
interpreter_init
80+
interpreter_destroy
81+
exec_program
82+
exec_program_in_env
83+
exec_program_in_env_as_function
84+
interpreter_format_traceback
85+
interpreter_reset_traceback
86+
eval_expr
87+
value_truthiness
88+
clear_error
89+
assign_index_chain
90+
interpreter_restart_thread
91+
module_register
92+
module_register_alias
93+
module_env_lookup
94+
lexer_init
95+
lexer_next_token
96+
lexer_get_line
97+
ns_buffer_init
98+
ns_buffer_shutdown
99+
ns_buffer_active
100+
ns_buffer_is_prepare_thread
101+
ns_buffer_read_lock
102+
ns_buffer_read_unlock
103+
ns_buffer_define
104+
ns_buffer_assign
105+
ns_buffer_assign_index
106+
ns_buffer_delete
107+
ns_buffer_set_alias
108+
ns_buffer_freeze
109+
ns_buffer_thaw
110+
ns_buffer_permafreeze
111+
parser_init
112+
parser_parse
113+
token_type_to_string
114+
free_token
115+
value_tns_new
116+
value_tns_from_values
117+
value_tns_get
118+
value_tns_slice
119+
value_map_new
120+
value_map_set
121+
value_map_get
122+
value_map_delete
123+
value_map_set_self
124+
value_map_get_ptr
125+
value_tns_get_ptr
126+
value_null
127+
value_bool
128+
value_int
129+
value_flt
130+
value_int_base
131+
value_flt_base
132+
value_flt_nan_base
133+
value_str
134+
value_func
135+
value_thr_new
136+
value_thr_is_running
137+
value_thr_set_finished
138+
value_thr_get_finished
139+
value_thr_set_paused
140+
value_thr_get_paused
141+
value_thr_set_started
142+
value_thr_get_started
143+
value_copy
144+
value_alias
145+
value_deep_copy
146+
value_free
147+
value_type_name

0 commit comments

Comments
 (0)