Skip to content

Commit ddc5c0f

Browse files
committed
Change Pr slightly and add tests
1 parent 1dd04b4 commit ddc5c0f

File tree

6 files changed

+129
-39
lines changed

6 files changed

+129
-39
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
.DS_Store
2-
*Manifest.toml
2+
*Manifest*.toml
33
.vscode

src/compiling.jl

Lines changed: 73 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -79,51 +79,86 @@ function compile_products(recipe::ImageRecipe)
7979

8080
project_arg = recipe.project == "" ? Base.active_project() : recipe.project
8181
env_overrides = Dict{String,Any}("JULIA_LOAD_PATH"=>nothing)
82+
tmp_prefs_env = nothing
83+
if is_trim_enabled(recipe)
84+
# Create a temporary empty environment with a LocalPreferences.toml that will be added to JULIA_LOAD_PATH.
85+
tmp_prefs_env = mktempdir()
86+
# It needs to have a Project.toml so it is recognized as an environment
87+
open(joinpath(tmp_prefs_env, "Project.toml"), "w") do io
88+
# Empty project - just needs to exist for LOAD_PATH
89+
end
90+
# Write LocalPreferences.toml with the trim preferences
91+
open(joinpath(tmp_prefs_env, "LocalPreferences.toml"), "w") do io
92+
println(io, "[Preferences]")
93+
println(io, "trim_enabled = true")
94+
println(io, "")
95+
end
96+
# Prepend the temp env to JULIA_LOAD_PATH
97+
env_overrides["JULIA_LOAD_PATH"] = "$tmp_prefs_env:@:@stdlib"
98+
end
99+
82100
inst_cmd = addenv(`$(Base.julia_cmd(cpu_target=precompile_cpu_target)) --project=$project_arg -e "using Pkg; Pkg.instantiate(); Pkg.precompile()"`, env_overrides...)
83101
recipe.verbose && println("Running: $inst_cmd")
84102
precompile_time = time_ns()
85-
if !success(pipeline(inst_cmd; stdout, stderr))
86-
error("Error encountered during instantiate/precompile of app project.")
87-
end
88-
recipe.verbose && println("Precompilation took $((time_ns() - precompile_time)/1e9) s")
89-
# Compile the Julia code
90-
if recipe.img_path == ""
91-
tmpdir = mktempdir()
92-
recipe.img_path = joinpath(tmpdir, "image.o.a")
93-
end
94-
project_arg = recipe.project == "" ? Base.active_project() : recipe.project
95-
# Build command incrementally to guarantee proper token separation
96-
cmd = julia_cmd
97-
cmd = `$cmd --project=$project_arg $(image_arg) $(recipe.img_path) --output-incremental=no`
98-
for a in strip_args
99-
cmd = `$cmd $a`
100-
end
101-
for a in recipe.julia_args
102-
cmd = `$cmd $a`
103-
end
104-
cmd = `$cmd $(joinpath(JuliaC.SCRIPTS_DIR, "juliac-buildscript.jl")) --scripts-dir $(JuliaC.SCRIPTS_DIR) --source $(abspath(recipe.file)) $(recipe.output_type)`
105-
if recipe.add_ccallables
106-
cmd = `$cmd --compile-ccallable`
107-
end
108-
if recipe.use_loaded_libs
109-
cmd = `$cmd --use-loaded-libs`
110-
end
111-
112-
# Threading
113-
cmd = addenv(cmd, env_overrides...)
114-
recipe.verbose && println("Running: $cmd")
115-
# Show a spinner while the compiler runs
116-
spinner_done, spinner_task = _start_spinner("Compiling...")
117-
compile_time = time_ns()
118103
try
119-
if !success(pipeline(cmd; stdout, stderr))
120-
error("Failed to compile $(recipe.file)")
104+
if !success(pipeline(inst_cmd; stdout, stderr))
105+
error("Error encountered during instantiate/precompile of app project.")
106+
end
107+
recipe.verbose && println("Precompilation took $((time_ns() - precompile_time)/1e9) s")
108+
# Compile the Julia code
109+
if recipe.img_path == ""
110+
tmpdir = mktempdir()
111+
recipe.img_path = joinpath(tmpdir, "image.o.a")
112+
end
113+
project_arg = recipe.project == "" ? Base.active_project() : recipe.project
114+
# Build command incrementally to guarantee proper token separation
115+
cmd = julia_cmd
116+
cmd = `$cmd --project=$project_arg $(image_arg) $(recipe.img_path) --output-incremental=no`
117+
for a in strip_args
118+
cmd = `$cmd $a`
121119
end
120+
for a in recipe.julia_args
121+
cmd = `$cmd $a`
122+
end
123+
cmd = `$cmd $(joinpath(JuliaC.SCRIPTS_DIR, "juliac-buildscript.jl")) --scripts-dir $(JuliaC.SCRIPTS_DIR) --source $(abspath(recipe.file)) $(recipe.output_type)`
124+
if recipe.add_ccallables
125+
cmd = `$cmd --compile-ccallable`
126+
end
127+
if recipe.use_loaded_libs
128+
cmd = `$cmd --use-loaded-libs`
129+
end
130+
131+
# Threading
132+
cmd = addenv(cmd, env_overrides...)
133+
recipe.verbose && println("Running: $cmd")
134+
# Show a spinner while the compiler runs
135+
spinner_done, spinner_task = _start_spinner("Compiling...")
136+
compile_time = time_ns()
137+
try
138+
if !success(pipeline(cmd; stdout, stderr))
139+
error("Failed to compile $(recipe.file)")
140+
end
141+
finally
142+
spinner_done[] = true
143+
wait(spinner_task)
144+
end
145+
recipe.verbose && println("Compilation took $((time_ns() - compile_time)/1e9) s")
122146
finally
123-
spinner_done[] = true
124-
wait(spinner_task)
147+
# Cleanup LocalPreferences.toml if we created/modified it
148+
if local_prefs_file !== nothing
149+
try
150+
if local_prefs_backup !== nothing
151+
# Restore the original file
152+
write(local_prefs_file, local_prefs_backup)
153+
else
154+
# Remove the file we created
155+
rm(local_prefs_file; force=true)
156+
end
157+
catch e
158+
@warn "Failed to cleanup LocalPreferences.toml: $local_prefs_file" exception=e
159+
end
160+
end
125161
end
126-
recipe.verbose && println("Compilation took $((time_ns() - compile_time)/1e9) s")
127162
# Print compiled image size
128163
if recipe.verbose
129164
@assert isfile(recipe.img_path)

test/TrimPrefsProject/Project.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name = "TrimPrefsProject"
2+
uuid = "2685b477-6e63-411d-9143-facd9abab21c"
3+
version = "0.1.0"
4+
authors = ["Gabriel Baraldi <baraldigabriel@gmail.com>"]
5+
6+
[deps]
7+
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
8+
9+
[compat]
10+
Preferences = "1.5.0"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module TrimPrefsProject
2+
3+
using Preferences
4+
5+
# Read the trim_enabled preference at compile time from the Preferences package
6+
# This preference is set by JuliaC in the temporary depot during compilation
7+
const TRIM_ENABLED = Preferences.load_preference(Preferences, "trim_enabled", false)::Bool
8+
9+
function @main(ARGS)
10+
if TRIM_ENABLED
11+
println(Core.stdout, "TRIM_MODE_ENABLED")
12+
else
13+
println(Core.stdout, "TRIM_MODE_DISABLED")
14+
end
15+
return 0
16+
end
17+
18+
end # module TrimPrefsProject

test/programatic.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,29 @@ end
302302
# Print tree for debugging/inspection
303303
print_tree_with_sizes(outdir)
304304
end
305+
306+
@testset "Trim preference propagation" begin
307+
# Test that the trim_enabled preference is correctly propagated to packages
308+
# during precompilation and compilation when trim mode is enabled.
309+
# This verifies that LocalPreferences.toml is written and read correctly.
310+
outdir = mktempdir()
311+
exeout = joinpath(outdir, "trim_prefs_exe")
312+
img = JuliaC.ImageRecipe(
313+
file = TEST_TRIM_PREFS_PROJ,
314+
output_type = "--output-exe",
315+
trim_mode = "safe",
316+
verbose = true,
317+
)
318+
JuliaC.compile_products(img)
319+
link = JuliaC.LinkRecipe(image_recipe=img, outname=exeout)
320+
JuliaC.link_products(link)
321+
bun = JuliaC.BundleRecipe(link_recipe=link, output_dir=outdir)
322+
JuliaC.bundle_products(bun)
323+
actual_exe = Sys.iswindows() ? joinpath(outdir, "bin", basename(exeout) * ".exe") : joinpath(outdir, "bin", basename(exeout))
324+
@test isfile(actual_exe)
325+
output = read(`$actual_exe`, String)
326+
# When trim is enabled, the package should see trim_enabled = true
327+
@test occursin("TRIM_MODE_ENABLED", output)
328+
# Verify LocalPreferences.toml was cleaned up
329+
@test !isfile(joinpath(TEST_TRIM_PREFS_PROJ, "LocalPreferences.toml"))
330+
end

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const TEST_PROJ = abspath(joinpath(@__DIR__, "AppProject"))
88
const TEST_SRC = joinpath(TEST_PROJ, "src", "test.jl")
99
const TEST_LIB_PROJ = abspath(joinpath(@__DIR__, "lib_project"))
1010
const TEST_LIB_SRC = joinpath(TEST_LIB_PROJ, "src", "libtest.jl")
11+
const TEST_TRIM_PREFS_PROJ = abspath(joinpath(@__DIR__, "TrimPrefsProject"))
1112

1213
include("utils.jl")
1314
include("programatic.jl")

0 commit comments

Comments
 (0)