Self-contained juliac demonstration

I was looking for a completely self-contained tutorial or demonstration on how to use the juliac command line from JuliaC.jl and did not find one. I created this short demonstration below.

Steps

Step 1: Install Julia 1.12 or greater
Step 2: Save the script below to “create_multiply_numbers.jl” and then run julia create_multiply_numbers.jl
Step 3: Run build/bin/multiply_numbers.exe 1 2 3 to test your new program itself.

create_multiply_numbers.jl

#!/usr/bin/env -S julia
using Pkg

if !contains(ENV["PATH"], DEPOT_PATH[1]*"/bin")
    @warn "The environment variable PATH does not contain $(DEPOT_PATH[1]*"/bin"). Consider modifying your shell startup."
    @info "Adding $(DEPOT_PATH[1])/bin to \$PATH" ENV["PATH"]
    ENV["PATH"] = "$(DEPOT_PATH[1])/bin:$(ENV["PATH"])"
end

if isnothing(Sys.which("juliac"))
    @info "Installing JuliaC"
    Pkg.Apps.add("JuliaC")
end

if !isdir("multiply_numbers")
    @info "Generating multiply_numbers package"
    Pkg.generate("multiply_numbers")
end

code_file::String = "multiply_numbers/src/multiply_numbers.jl"
if !isfile(code_file) || !contains("@main", read(code_file))
    @info "Writing $code_file"
    program = """
    module multiply_numbers

    function (@main)(args::Vector{String})
        numbers = parse.(Int, args)
        println(Core.stdout, prod(numbers))
        return 0
    end

    end # module multiply_numbers
    """
    println(program)
    write("multiply_numbers/src/multiply_numbers.jl", program)
end

@info "Compiling multiply_numbers.exe with juliac multiply_numbers --output-exe multiply_numbers.exe --bundle build --trim"
run(`juliac multiply_numbers --output-exe multiply_numbers.exe --bundle build --trim`)

@info "The size of build/bin/multiply_numbers.exe is $(filesize("build/bin/multiply_numbers.exe")/1024^2) MiB"

@info "Running build/bin/multiply_numbers.exe 5 9 10"
run(`build/bin/multiply_numbers.exe 5 9 10`)

This script does the following:

  1. Checks to see if you have your ~/.julia/bin folder on your environment’s PATH. Adds it temporarily if not.
  2. Checks to see if you have juliac installed. Installs JuliaC.jl as an app if not.
  3. Generates a minimal “multiply_numbers” package if it does not exist.
  4. Writes the “multiply_numbers.jl” program if it does not exist or does contain a @main function.
  5. Compiles “multiply_numbers.jl” into “build/bin/multiply_numbers.exe”
  6. Reports the size of build/bin/multiply_numbers.exe
  7. Executes build/bin/multiply_numbers.exe 5 9 10
8 Likes

Nice! I got this to work on Windows (Julia 1.12.2), and the total bundled directory was 117MB. Looking at the content, it seemed like a lot of unnecessary pieces… fortran and BLAS and PCRE… Copied one at a time to a new directory and ended with just the .exe, libjulia and libjulia-internal, and libopenlibm for it to work (total of 17MB). Isn’t trim supposed to be doing this?

1 Like