How to use juliac.jl?

I watched this talk on juliac which I am eager to try out but I can’t figure out how. I looked through the dev docs and the relevant PR, but no such luck, so am posting here.

To get started I ran this:

juliaup update nightly
juliaup default nightly

Then, the first (naive) thing I tried was the exact syntax from the talk

# main.jl
module MyApp
Base.@ccallable function myfunc()::Cint
    println(Core.stdout, "Hello, world!")
    return 0
end
end
julia juliac.jl --output-exe main --trim main.jl

to which I realised that juliac.jl is an actual file somewhere and not a special subcommand. I found it sitting in ~/.julia/juliaup/julia-nightly/share/julia/juliac.jl so went with that. Here’s the first error:

> julia ~/.julia/juliaup/julia-nightly/share/julia/juliac.jl \
    --output-exe main --trim main.jl

ERROR: julia: --trim is an experimental feature, you must enable it with --experimental

Failed to compile main.jl

Ok, so I tried adding --experimental on the end:

> julia ~/.julia/juliaup/julia-nightly/share/julia/juliac.jl \
    --output-exe main --trim --experimental main.jl

Unexpected argument `--experimental`

Weird. Where should --experimental go? Maybe as an argument to julia itself? This is what I tried next:

> julia --experimental \
    ~/.julia/juliaup/julia-nightly/share/julia/juliac.jl \
    --output-exe main --trim main.jl

ERROR: julia: --trim is an experimental feature, you must enable it with --experimental

Failed to compile main.jl

Even weirder. Maybe I am supposed to pass --trim to the julia binary too?

> julia --experimental --trim \
    ~/.julia/juliaup/julia-nightly/share/julia/juliac.jl \
    --output-exe main main.jl

ld: warning: ignoring duplicate libraries: '-ljulia'
Undefined symbols for architecture arm64:
  "_main", referenced from:
      <initial-undefines>
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Compilation failed.

I also tried putting all the flags in both spots, but got back to the first error:

> julia --experimental --trim \
    ~/.julia/juliaup/julia-nightly/share/julia/juliac.jl \
    --output-exe main --trim main.jl

ERROR: julia: --trim is an experimental feature, you must enable it with --experimental

Failed to compile main.jl

Does anybody know how to get this cool new feature working? Maybe it doesn’t yet support arm64, or perhaps it’s not compatible with juliaup, or perhaps I just need to do something like fix my $LD_LIBRARY_PATH to point to the right julia library files?


[disclaimer: I understand juliac is highly experimental etc and don’t expect full support on it yet; just was curious to check it out!]

6 Likes

See pass experimental flag in juliac script by baggepinnen · Pull Request #56602 · JuliaLang/julia · GitHub

For general juliac setup you might find Runic.jl/juliac at master · fredrikekre/Runic.jl · GitHub useful.

4 Likes

Oh @MilesCranmer , you may find this write-up I made earlier interesting: Pushing the Limits of Small Binary Creation

Here is the reproducible repo I set-up for that post: GitHub - TheCedarPrince/InteroperableJuliaBinaries: Experiments in making Julia binaries interoperable within other language C interfaces.

Also, something I haven’t had a chance to explore is this tweet from @jbytecode :

Seems like there may be some regressions compared to my last effort. I’d be curious what you find out, Miles!

2 Likes

Also, in my GitHub repo I linked, I discuss a little bit about LD_PATHing as at the time, something was breaking but I found a workaround.

2 Likes

Coming from this thread, I need to compile my Julia module .jl file to a DLL that I can later include in other programs.

I heard that juliac could do this. Can anybody please give me a step by step instruction on how to compile a Julia module to a DLL? I already downloaded Julia 1.12 beta and I am willing to try out experimental things. But I am a new user thus need a step by step instruction.

1 Like

Here is the link of my playground repository that includes examples from the very early times of the juliac compiler:

This repo includes a link for my initial blogpost, main discourse discussion, and my playground with examples of generating executables and shared libraries.

I copied and pasted the file args2.jl from somewhere else, but I don’t remember the link of this repo. Thank you for the author of this file, indeed, it’s very helpful on parsing command line arguments.

I know the examples hosted in the repo are quite basic and minimal. I just want to share my experiments for those who want to start working with juliac.

Edit: I’ve just found the aforementioned reference and added it to required files.

2 Likes

At this point I would say that juliac is still at the stage where it is a challenge for experienced Julia users to do non-trivial things (and sometimes trivial too) and we’re still trying to figure out what the step by steps even are beyond the most basic examples.

2 Likes

I found this blog very helpful: https://jbytecode.github.io/juliac/
It gives a step-by-step tutorial and worked with Julia 1.12 beta.

3 Likes

I tried it and it does not work. I installed Julia 1.12 beta1 and when i try then

julia juliac.jl

it cannot find the file juliac.jl. So one has to specify the complete paths. In my case it would be

J:\\Julia-1.12\\bin\julia.exe J:\\Julia-1.12\\share\\julia\\juliac.jl --output-exe hello --trim D:\\usti\\Julia\\JuliaC\\helloworld.jl

and the content of helloworld.jl is just:

module HelloWorld

Base.@ccallable function main()::Cint
    println(Core.stdout, "Hello, World!")
    return 0
end
end # End of module HelloWorld 

The error I get is

LoadError: IOError: could not spawn `cc -std=gnu11 '-IJ:\Julia-1.12\include\julia' -g -c -o 'C:\Users\Uwe\AppData\Local\Temp\jl_UOF4T3\init.a' 'C:\Users\Uwe\AppData\Local\Temp\jl_UOF4T3\init.c'`: no such file or directory (ENOENT)

But I have no info why init.a was not created.

I also wonder how I specify the path to the C compiler. I have Microsoft Visual Studio as C/C++ compiler. But how to I tell Julia its path?

I got the compiler working by following the steps here to install the MinGW-w64 toolchain.

If you’re on Windows, juliac will probably error. Someone else has been able to reproduce an exception I’ve been seeing while using --trim.

Ah, Juliac.jl has hardcoded the compiler cc,
for example in this line:

run(`cc $(cflags) -g -c -o $init_path $initsrc_path`)

Instead of cc, for the Visual Studio compiler, there must be probably the full path to the cl.exe.

However, why is a certain compiler hardcoded? There should be an option to specify the compiler.
I would even say, without this option juliac is not very useful. For desktop apps Windows is the main platform therefore a Linux-specific compiler-setting cannot be hardcoded.

It would certainly be better if Visual Studio could also be used and worked out of the box but I don’t agree that the current compiler is Linux-specific. MinGW-w64 is after all used to compile Julia and all C/C++ binary dependencies on Windows.

At some point when juliac is more mature than an experimental feature of a beta release, I’m sure things will be smoother, but for now there’s need for people to try it out, figure out how to get things working and make pull requests to improve the tools.

5 Likes

I have MinGW-w64 installed (via GitHub - niXman/mingw-builds-binaries: MinGW-W64 compiler binaries) but as juliac hardcodes cc, it won’t be used.

I first had to manually add the bath to the cc.exe of MinGW to Windows’ PATH environment variable.

So there should be something done, either an option to juliac to specify the path to the compiler executable or Julia’s installer gets an option to install MinGW and then sets up the environment variables directly.