Static Compilation in Julia

Hello all, I am new to Julia, and I am planning to develop some projects with the language in my own free time. Reading the docs, I saw that Julia is a JIT language, as such it does not natively support AOT compilation. However, I’ve also seen two major packages for static compilation to a binary. With the ongoing development to support static compilation, is a full-fledged compiler a future feature I can expect? Or rather, is the focus on developing support for static compilation via packages such as those.

2 Likes

Here’s a nice talk on the current state of the art and the direction things are going for AOT compilation of julia: https://www.youtube.com/watch?v=R0DEG-ddBZA

5 Likes

It depends a bit on your goal. Very small programs can already be statically compiled using GitHub - tshort/StaticCompiler.jl: Compiles Julia code to a standalone library (experimental), but you will lack a lot of language features.

Larger projects can also be AOT compiled (well, a few packages might fail, but it mostly works) using PackageCompiler.jl But you end up with large binaries, for a GUI program at least 300 MB for example. My main program that uses 500 packages compiles to 1.3 GB. Julia 1.12 will provide the option to create smaller binaries, but again with some limitations of the language features that you can use.

Cross compilation is another feature that is still missing, but planned, and there are some work-arounds.

3 Likes

Thank you very much, I appreciate it!

Thank you for your response, would I be correct in supposing that it is something that it is being actively working on and likely to see improvements upon as the year progresses? On your point about limitations of the language features you can use; is that something that will be worked upon over time as well? I am looking to build a GUI application for myself, so the latter package would be more applicable to be.

To some degree this cannot be improved: If you want to use a garbage collector, you need to include the code of the garbage collector which increases the binary size. Not much we can do about it.

If you do not know all combinations of types with which a function can be called you have to include the compiler in your binary, which increases the size a lot. Again not much we can do about.

You want to have an easy life → large binaries
You need small binaries → you need to invest more time and effort

Your choice. Well, at least when Julia 1.12 is released, for now it will in many cases not be possible to achieve small binaries.

3 Likes

This has been really helpful for me, thank you for your help!

Here’s an example of static compilation, adapted from the instructions here. A small program requiring GC compiles to 18 MB on my Linux machine (libc x86_64).

First, I install the Julia nightly channel:

#> juliaup add nightly

Then I cloned the Julia git repo to get the juliac scripts:

#> git clone https://github.com/JuliaLang/julia.git

Here’s a small program try.jl which stores the squares of the numbers 1, 2, … ,100 into a dictionary (GC is needed for this data structure). Then it prints out the value for the key 10.

module Try

Base.@ccallable function main()::Cint
    square_dict = Dict(i => i^2 for i in 1:100)
    println(Core.stdout, square_dict[10])
    return 0
end

end # End of module Try

I compile the program with

#> julia +nightly julia/contrib/juliac.jl --output-exe try --experimental --trim try.jl

This took about 22 seconds and produced the binary try with a size 18 MB. Executing the produced binary took about 37 milliseconds.

#> time ./try
100

real	0m0.037s
user	0m0.014s
sys     0m0.027s

P.S. since this is experimental stuff, it goes without saying that the information could become outdated very quickly.

7 Likes

Not sure to what extend https://www.youtube.com/watch?v=4CV5SG3OLMw is adding value here.

1 Like