How to use juliac.jl?

With the latest commit

the simple hello world is

function (@main)(args::Vector{String})::Cint
	println(Core.stdout, "Hello, world!")
	return 0
end

In that use, no module is needed and the args argument is passed as a Vector of strings rather than a Vector of Any.

# julia +nightly juliac.jl --experimental --output-exe hello --trim hello.jl

is required to compile a hello executable.

Note: Required files should be install manually. This would help:

# wget -nc https://raw.githubusercontent.com/JuliaLang/julia/refs/heads/master/contrib/juliac.jl
# wget -nc https://raw.githubusercontent.com/JuliaLang/julia/refs/heads/master/contrib/juliac-buildscript.jl
# wget -nc https://raw.githubusercontent.com/JuliaLang/julia/refs/heads/master/contrib/julia-config.jl
14 Likes

Thanks, this works!

ufechner@ufryzen:~/repos/juliac$ ls -lah
total 1,6M
drwxrwxr-x   2 ufechner ufechner 4,0K mei 23 11:59 .
drwxrwxr-x 118 ufechner ufechner 4,0K mei 23 11:50 ..
-rwxrwxr-x   1 ufechner ufechner 1,6M mei 23 11:59 hello
-rw-rw-r--   1 ufechner ufechner   97 mei 23 11:57 hello.jl
-rw-rw-r--   1 ufechner ufechner  12K mei 23 11:59 juliac-buildscript.jl
-rw-rw-r--   1 ufechner ufechner 5,5K mei 23 11:59 juliac.jl
-rw-rw-r--   1 ufechner ufechner 4,0K mei 23 11:59 julia-config.jl
3 Likes

Works on Windows too.

Any examples out there making use of 3rd party packages? Makie, DataFrames, etc. Even using something like DelimitedFiles I’m struggling to get it to compile.

6 Likes

I played around with it and specifically found issues with ssl if you try to use HTTP.jl (ill make an issue later). IIRC the certificate store was being looked for in the wrong place.

Forgive me for asking but what is the main usecase of juliac, given that the binaries produced are not portable to other machines? is it meant just for simplifying system images (which is very useful on its own)?

also, out of curiosity - why are the binaries so huge if julia isn’t bundled?

3 Likes

How do you come to the conclusion that the binaries are not portable? I mean, you have to make sure to compile using an instruction set that the target machine supports. I think this is possible using the correct command line parameters. And you need to make sure that paths to shared libraries or other resources are correct. This might have to be fixed in the packages if it does not work yet.

1 Like

Well, there’s quite a lot you have to do at the moment to make the binary run on another machine, unless it happens to have a very similar environment. Specifically on Linux,

$ readelf -a ./hello |grep RUNPATH
 0x000000000000001d (RUNPATH)            Library runpath: [/home/gunnar/.julia/juliaup/julia-nightly/lib/julia:/home/gunnar/.julia/juliaup/julia-nightly/lib]

This won’t run on another machine unless there is a user account of the same name with a matching Julia installation.

It is possible to make simple programs portable, I have at least managed that on Linux, but the tooling simply isn’t there yet to make it convenient and not require a certain amount of technical knowledge.

3 Likes

Well, even in Julia 1.12 (which is not yet released) juliac.jl is marked as experimental. I think the goal is to create portable binaries, but nobody should expect that this will be convenient before next year.

Of course not. But I think it’s uncontroversial to say that at this point in development, the binaries aren’t portable.

to be explicit about my own meaning;

when I think “portable”, it means something that can be run on a different machine that has the same system libraries but not julia+packages installed.

Obviously if i clone an exact copy of my entire filesystem/docker image everything should work but that’s a very narrow interpretation of portability. eg if you compile an sbcl image you get a self contained binary that would work on similar architectures regardless of preinstalled sbcl+packages - only ffi based libs are needed.

Since the compiled artifacts for rather trivial examples take hundreds of mb, i was surprised that they still require the entire toolchain and libraries separately. Hence the question.

I understand this is work in progress but was curious regarding intended scope/usecases for this project as envisioned for stable release. Is it mainly to improve TTFP on the same machine? Distributing closed source “apps” to “labs”? Dropping off my compiled artifacts on a server? Some other scenarios?

3 Likes

Being able to create and distribute FMU components (see: https://fmi-standard.org/) would be great. And if the size goes down from 1GB to 100MB many users would already be happy. These components are often simulation models of components of cars or airplanes, a zip file containing one or more dll/so files and an xml file with the interface description. A company that supplies the component gives it to the company that uses it.

And you can easily use the components in Modelica, Simulink, Python or whatever your prefered simulation environment is. If you could easily write these components in Julia this would open up a huge market.

To some degree this is already possible: GitHub - ThummeTo/FMIExport.jl: FMIExport.jl is a free-to-use software library for the Julia programming language which allows for the export of FMUs (fmi-standard.org) from any Julia-Code. FMIExport.jl is completely integrated into FMI.jl.

3 Likes

In the latest commits, some changes have been done to juliac scripts.

A new folder has been created in contrib folder and this folder includes juliac-buildscript.jl, juliac-trim-base.jl, juliac-trim-stdlib.jl, and juliac.jl.

I updated the makefile and the downloader script in repo GitHub - jbytecode/juliac: Examples for Julia's generating small binary executables and libraries feature. so

> make hello

compiles hello world with the latest changes.

fyi.

17 Likes

I’m very interested in applying a julia.c for Windows.
I face two problems when using juliac:

  1. Using julia 1.12-beta, and using my own compiler, clang, ld yields the error, that the option rpath would be unknown.
lld: error: unknown argument: -rpath

Setting rpath to "", it works.
Do I loose important features, when setting rpath to empty string (e.g. problems in using packages) ?

  1. Using julia-nightly, I had to find the right Artifact.toml first. I took it from here. Is this correct? I copied into the juliac-directory.
    Compiling worked, however the executable gave an error. I used the example program:
function (@main)(args::Vector{String})::Cint
    println(Core.stdout, "Hello, world!")
    return 0
end

Here is the error message:

Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x7ffef05dbf8e -- jl_svecref at C:/workdir/src\julia.h:1293 [inlined]
new_array at C:/workdir/src\array.c:80 [inlined]
ijl_alloc_array_1d at C:/workdir/src\array.c:149
in expression starting at none:0
jl_svecref at C:/workdir/src\julia.h:1293 [inlined]
new_array at C:/workdir/src\array.c:80 [inlined]
ijl_alloc_array_1d at C:/workdir/src\array.c:149
jl_restore_system_image_from_stream_ at C:/workdir/src\staticdata.c:3863
jl_restore_system_image_from_stream at C:/workdir/src\staticdata.c:4422 [inlined]
ijl_restore_system_image at C:/workdir/src\staticdata.c:4461
_finish_jl_init_ at C:/workdir/src\init.c:580
ijl_init_ at C:/workdir/src\init.c:778
ijl_init_with_image_handle at C:/workdir/src\jlapi.c:83
ijl_autoinit_and_adopt_thread at C:/workdir/src\threading.c:459
main at C:\jul\juliac\hello.exe (unknown line)
__tmainCRTStartup at C:\jul\juliac\hello.exe (unknown line)
.l_start at C:\jul\juliac\hello.exe (unknown line)
BaseThreadInitThunk at C:\Windows\System32\KERNEL32.DLL (unknown line)
RtlUserThreadStart at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
Allocations: 0 (Pool: 0; Big: 0); GC: 0

[24176] signal 11: SIGSEGV
in expression starting at none:0
crt_sig_handler at C:/workdir/src\signals-win.c:99
.text at C:\jul\juliac\hello.exe (unknown line)
_C_specific_handler at C:\Windows\System32\msvcrt.dll (unknown line)
_chkstk at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
RtlWow64GetCurrentCpuArea at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
KiUserExceptionDispatcher at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
jl_smallintset_lookup at C:/workdir/src\smallintset.c:122
jl_get_module_binding at C:/workdir/src\module.c:1495
ijl_get_global at C:/workdir/src\module.c:1548
ijl_atexit_hook at C:/workdir/src\init.c:254
ijl_exit at C:/workdir/src\init.c:198
jl_exception_handler at C:/workdir/src\signals-win.c:343 [inlined]
jl_exception_handler at C:/workdir/src\signals-win.c:235
__julia_personality at C:/workdir/src\win32_ucontext.c:28
_chkstk at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
RtlWow64GetCurrentCpuArea at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
KiUserExceptionDispatcher at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
jl_svecref at C:/workdir/src\julia.h:1293 [inlined]
new_array at C:/workdir/src\array.c:80 [inlined]
ijl_alloc_array_1d at C:/workdir/src\array.c:149
jl_restore_system_image_from_stream_ at C:/workdir/src\staticdata.c:3863
jl_restore_system_image_from_stream at C:/workdir/src\staticdata.c:4422 [inlined]
ijl_restore_system_image at C:/workdir/src\staticdata.c:4461
_finish_jl_init_ at C:/workdir/src\init.c:580
ijl_init_ at C:/workdir/src\init.c:778
ijl_init_with_image_handle at C:/workdir/src\jlapi.c:83
ijl_autoinit_and_adopt_thread at C:/workdir/src\threading.c:459
main at C:\jul\juliac\hello.exe (unknown line)
__tmainCRTStartup at C:\jul\juliac\hello.exe (unknown line)
.l_start at C:\jul\juliac\hello.exe (unknown line)
BaseThreadInitThunk at C:\Windows\System32\KERNEL32.DLL (unknown line)
RtlUserThreadStart at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
Allocations: 0 (Pool: 0; Big: 0); GC: 0

Could you please try it one more time using the nightly build Julia? I am not sure if the new entry point definition format works in v1.12.

Edit: Today @visr has sent a pull request about the Windows and Artifact stuff and looks like it is working:

3 Likes

I tried again, but I got the same error message.

Using julia 1.12-beta, I’m happy, juliac works fine on my machine.
How can I use arguments for the executable?

When compiling

module Test

  Base.@ccallable function main(args::Vector{String})::Cint
    println(Core.stdout, "Hello, world!")
    return 0
  end

end

the error occurs

ld.lld: error: undefined symbol: WinMain
2 Likes

IIRC this has to be function (@main)(args)? See Julia v1.12 Release Notes · The Julia Language

Note that this is new in 1.12-rc1, so don’t expect it to work with the beta releases.

Just sharing some experiences, I’ve compiled a 1000 lines program with StaticCompiler and juliac. The executable compiled with help of juliac is (only) around 10 times larger than the staticcompiler-executable (2.3 MB vs 220k), but around 25% faster.

8 Likes

I tried to compile the hello-world-program with juliac in 1.12-rc1, but I get kind of segmentation fault, working in Windows. The juliac in 1.12-beta it worked.
Does anybody has experience with it or can share similar results?

The code is:

function @main(args::Vector{String})::Cint
  println(Core.stdout, "Hello world")
  return 0
end

The error message is:

Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x7ffd391cbf8e -- jl_svecref at C:/workdir/src\julia.h:1293 [inlined]
new_array at C:/workdir/src\array.c:80 [inlined]
ijl_alloc_array_1d at C:/workdir/src\array.c:149
in expression starting at none:0
jl_svecref at C:/workdir/src\julia.h:1293 [inlined]
new_array at C:/workdir/src\array.c:80 [inlined]
ijl_alloc_array_1d at C:/workdir/src\array.c:149
jl_restore_system_image_from_stream_ at C:/workdir/src\staticdata.c:3863
jl_restore_system_image_from_stream at C:/workdir/src\staticdata.c:4422 [inlined]
ijl_restore_system_image at C:/workdir/src\staticdata.c:4461
_finish_jl_init_ at C:/workdir/src\init.c:580
ijl_init_ at C:/workdir/src\init.c:778
ijl_init_with_image_handle at C:/workdir/src\jlapi.c:83
ijl_autoinit_and_adopt_thread at C:/workdir/src\threading.c:459
main at C:\jul\juliac\test.exe (unknown line)
__tmainCRTStartup at C:\jul\juliac\test.exe (unknown line)
.l_start at C:\jul\juliac\test.exe (unknown line)
BaseThreadInitThunk at C:\Windows\System32\KERNEL32.DLL (unknown line)
RtlUserThreadStart at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
Allocations: 0 (Pool: 0; Big: 0); GC: 0

[16568] signal 11: SIGSEGV
in expression starting at none:0
crt_sig_handler at C:/workdir/src\signals-win.c:99
.text at C:\jul\juliac\test.exe (unknown line)
_C_specific_handler at C:\Windows\System32\msvcrt.dll (unknown line)
_chkstk at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
RtlWow64GetCurrentCpuArea at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
KiUserExceptionDispatcher at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
jl_smallintset_lookup at C:/workdir/src\smallintset.c:122
jl_get_module_binding at C:/workdir/src\module.c:1495
ijl_get_global at C:/workdir/src\module.c:1548
ijl_atexit_hook at C:/workdir/src\init.c:254
ijl_exit at C:/workdir/src\init.c:198
jl_exception_handler at C:/workdir/src\signals-win.c:343 [inlined]
jl_exception_handler at C:/workdir/src\signals-win.c:235
__julia_personality at C:/workdir/src\win32_ucontext.c:28
_chkstk at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
RtlWow64GetCurrentCpuArea at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
KiUserExceptionDispatcher at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
jl_svecref at C:/workdir/src\julia.h:1293 [inlined]
new_array at C:/workdir/src\array.c:80 [inlined]
ijl_alloc_array_1d at C:/workdir/src\array.c:149
jl_restore_system_image_from_stream_ at C:/workdir/src\staticdata.c:3863
jl_restore_system_image_from_stream at C:/workdir/src\staticdata.c:4422 [inlined]
ijl_restore_system_image at C:/workdir/src\staticdata.c:4461
_finish_jl_init_ at C:/workdir/src\init.c:580
ijl_init_ at C:/workdir/src\init.c:778
ijl_init_with_image_handle at C:/workdir/src\jlapi.c:83
ijl_autoinit_and_adopt_thread at C:/workdir/src\threading.c:459
main at C:\jul\juliac\test.exe (unknown line)
__tmainCRTStartup at C:\jul\juliac\test.exe (unknown line)
.l_start at C:\jul\juliac\test.exe (unknown line)
BaseThreadInitThunk at C:\Windows\System32\KERNEL32.DLL (unknown line)
RtlUserThreadStart at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
Allocations: 0 (Pool: 0; Big: 0); GC: 0
  
2 Likes

julia-nightly works, when using arguments in main(). Thank you!

2 Likes