Skip to content

Commit d66c9c6

Browse files
committed
merge files from static-julia
2 parents d25c0a5 + d405ce4 commit d66c9c6

File tree

7 files changed

+598
-7
lines changed

7 files changed

+598
-7
lines changed

.gitignore

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ deps.jl
55
*.csv
66
snoopy.jl
77
precompile.jl
8-
*.so
8+
sysimg
99
*.ji
10-
*.dll
11-
*.dylib
1210
*.o
13-
sysimg
11+
*.so
12+
*.so.*
13+
*.dylib
14+
*.dll
15+
hello
16+
hello.exe

.mailmap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Luca Trevisani <lucatrv@users.noreply.github.com> <lucatrv@users.noreply.github.com>
2+
Luca Trevisani <lucatrv@users.noreply.github.com> <lucatrv@hotmail.com>
3+
4+
Simon Danisch <simondanisch@users.noreply.github.com> <sdanisch@gmail.com>
5+
6+
Viral B. Shah <viral@mayin.org> <viral@mayin.org>
7+
Viral B. Shah <viral@mayin.org> <viral@juliacomputing.com>
8+
Viral B. Shah <viral@mayin.org> <viralbshah@anubis.juliacomputing.io>

README.md

Lines changed: 124 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# PackageCompiler
2-
32
[![Build Status](https://travis-ci.org/SimonDanisch/PackageCompiler.jl.svg?branch=master)](https://travis-ci.org/SimonDanisch/PackageCompiler.jl)
43

54
[![Coverage Status](https://coveralls.io/repos/SimonDanisch/PackageCompiler.jl/badge.svg?branch=master&service=github)](https://coveralls.io/github/SimonDanisch/PackageCompiler.jl?branch=master)
@@ -15,7 +14,7 @@ using PackageCompiler
1514

1615
# This command will use the runtest.jl of Matcha + UnicodeFun to find out what functions to precompile!
1716
# force = false to not force overwriting julia's current system image
18-
compile_package("Matcha", "UnicodeFun", force = false, reuse = false)
17+
compile_package("Matcha", "UnicodeFun", force = false, reuse = false)
1918

2019
# build again, reusing the snoop file
2120
compile_package("Matcha", "UnicodeFun", force = false, reuse = true)
@@ -28,7 +27,7 @@ compile_package("Matcha", "relative/path/for_snooping.jl")
2827
revert()
2928

3029
# Or if you simply want to get a native system image e.g. when you have downloaded the generic Julia install:
31-
build_clean_image()
30+
build_clean_image()
3231
```
3332

3433

@@ -46,3 +45,125 @@ build_clean_image()
4645
- I used julia-debug to uncover most bugs, but actually, the last errors I was trying to uncover where due to using julia-debug!
4746

4847
- you’re pretty much on your own and need to use gdb to find the issues and I still don’t know what the underlying julia issues are and when they will get fixed :wink: See: https://github.com/JuliaLang/julia/issues/24533. Hopefully we look at a better story with Julia 1.0!
48+
49+
50+
# Static Julia Compiler
51+
52+
Building shared libraries and executables from Julia code.
53+
54+
Run `juliac.jl -h` for help:
55+
56+
```
57+
usage: juliac.jl [-v] [-q] [-c] [-J <file>]
58+
[--compile {yes|no|all|min}] [-C <target>]
59+
[-O {0,1,2,3}] [-g {0,1,2}] [--inline {yes|no}]
60+
[--check-bounds {yes|no}] [--math-mode {ieee,fast}]
61+
[--depwarn {yes|no|error}] [-a] [-o] [-s] [-e] [-j]
62+
[--version] [-h] juliaprog [cprog] [builddir]
63+
64+
Static Julia Compiler
65+
66+
positional arguments:
67+
juliaprog Julia program to compile
68+
cprog C program to compile (required only when
69+
building an executable; if not provided a
70+
minimal standard program is used)
71+
builddir build directory, either absolute or relative
72+
to the Julia program directory (default:
73+
"builddir")
74+
75+
optional arguments:
76+
-v, --verbose increase verbosity
77+
-q, --quiet suppress non-error messages
78+
-c, --clean delete builddir
79+
-J, --sysimage <file>
80+
start up with the given system image file
81+
--compile {yes|no|all|min}
82+
enable or disable JIT compiler, or request
83+
exhaustive compilation
84+
-C, --cpu-target <target>
85+
limit usage of CPU features up to <target>
86+
-O, --optimize {0,1,2,3}
87+
set optimization level (type: Int64)
88+
-g {0,1,2} set debugging information level (type: Int64)
89+
--inline {yes|no} control whether inlining is permitted
90+
--check-bounds {yes|no}
91+
emit bounds checks always or never
92+
--math-mode {ieee,fast}
93+
set floating point optimizations
94+
--depwarn {yes|no|error}
95+
set syntax and method deprecation warnings
96+
-a, --autodeps automatically build required dependencies
97+
-o, --object build object file
98+
-s, --shared build shared library
99+
-e, --executable build executable file
100+
-j, --julialibs sync Julia libraries to builddir
101+
--version show version information and exit
102+
-h, --help show this help message and exit
103+
104+
examples:
105+
juliac.jl -vae hello.jl # verbose, build executable and deps
106+
juliac.jl -vae hello.jl prog.c # embed into user defined C program
107+
juliac.jl -qo hello.jl # quiet, build object file only
108+
juliac.jl -vosej hello.jl # build all and sync Julia libs
109+
```
110+
111+
### Notes
112+
113+
1. The `juliac.jl` script uses the `ArgParse` package, make sure it is installed.
114+
115+
3. On Windows install `Cygwin` and the `mingw64-x86_64-gcc-core` package, see:\
116+
https://github.com/JuliaLang/julia/blob/master/README.windows.md
117+
118+
2. A shared library containing the system image `libhello.so`, and a
119+
driver binary `hello` are created in the `builddir` directory.
120+
Running `hello` produces the following output:
121+
122+
```
123+
$ ./hello
124+
hello, world
125+
f() = -0.37549581296986956
126+
┌─────────────────────────────────────────────────┐
127+
100 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠎│
128+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀│
129+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠊⠀⠀⠀│
130+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠀│
131+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠀⠀⠀│
132+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀│
133+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
134+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
135+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠤⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
136+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠔⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
137+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠤⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
138+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠤⠒⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
139+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠔⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
140+
│⠀⠀⠀⠀⠀⠀⢀⣀⠤⠔⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
141+
0 │⣀⠤⠤⠔⠒⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
142+
└─────────────────────────────────────────────────┘
143+
1 10
144+
```
145+
146+
## Under the hood
147+
148+
The `juliac.jl` script uses the `--output-o` switch to compile the user
149+
script into object code, and then builds it into the system image
150+
specified by the `-J` switch. This prepares an object file, which is
151+
then linked into a shared library containing the system image and user
152+
code. A driver script such as the one in `program.c` can then be used to
153+
build a binary that runs the julia code.
154+
155+
Instead of a driver script, the generated system image can be embedded
156+
into a larger program following the embedding examples and relevant
157+
sections in the Julia manual. Note that the name of the generated system
158+
image (`"libhello"` for `hello.jl`) is accessible from C in the
159+
preprocessor macro `JULIAC_PROGRAM_LIBNAME`.
160+
161+
With Julia 0.7, a single large binary can be created, which does not
162+
require the driver program to load the shared library. An example of
163+
that is in `program2.c`, where the image file is the binary itself.
164+
165+
For more information on static Julia compilation see:\
166+
https://juliacomputing.com/blog/2016/02/09/static-julia.html
167+
168+
For more information on embedding Julia see:\
169+
https://github.com/JuliaLang/julia/blob/master/doc/src/manual/embedding.md

examples/hello.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module Hello
2+
3+
using UnicodePlots
4+
using Distributions
5+
f() = rand(Normal())
6+
7+
Base.@ccallable function julia_main(ARGS::Vector{String})::Cint
8+
println("hello, world")
9+
@show f()
10+
println(lineplot(1:10, (1:10).^2))
11+
return 0
12+
end
13+
14+
end

examples/program.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// This file is a part of Julia. License is MIT: http://julialang.org/license
2+
3+
// Standard headers
4+
#include <string.h>
5+
#include <stdint.h>
6+
7+
// Julia headers (for initialization and gc commands)
8+
#include "uv.h"
9+
#include "julia.h"
10+
11+
#ifdef JULIA_DEFINE_FAST_TLS // only available in Julia v0.7 and above
12+
JULIA_DEFINE_FAST_TLS()
13+
#endif
14+
15+
// Declare C prototype of a function defined in Julia
16+
extern void julia_main();
17+
18+
int main(int argc, char *argv[])
19+
{
20+
intptr_t v;
21+
22+
// Initialize Julia
23+
uv_setup_args(argc, argv); // no-op on Windows
24+
libsupport_init();
25+
// JULIAC_PROGRAM_LIBNAME defined on command-line for compilation
26+
jl_options.image_file = JULIAC_PROGRAM_LIBNAME;
27+
julia_init(JL_IMAGE_JULIA_HOME);
28+
29+
// Do some work
30+
julia_main();
31+
32+
// Cleanup and graceful exit
33+
jl_atexit_hook(0);
34+
return 0;
35+
}

examples/program2.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// This file is a part of Julia. License is MIT: http://julialang.org/license
2+
3+
// Standard headers
4+
#include <string.h>
5+
#include <stdint.h>
6+
7+
// Julia headers (for initialization and gc commands)
8+
#include "uv.h"
9+
#include "julia.h"
10+
11+
#ifdef JULIA_DEFINE_FAST_TLS // only available in Julia v0.7 and above
12+
JULIA_DEFINE_FAST_TLS()
13+
#endif
14+
15+
// Declare C prototype of a function defined in Julia
16+
extern int julia_main(jl_array_t*);
17+
18+
// main function (windows UTF16 -> UTF8 argument conversion code copied from julia's ui/repl.c)
19+
#ifndef _OS_WINDOWS_
20+
int main(int argc, char *argv[])
21+
{
22+
int retcode;
23+
int i;
24+
uv_setup_args(argc, argv); // no-op on Windows
25+
#else
26+
int wmain(int argc, wchar_t *wargv[], wchar_t *envp[])
27+
{
28+
int retcode;
29+
int i;
30+
char **argv;
31+
for (i = 0; i < argc; i++) { // convert the command line to UTF8
32+
wchar_t *warg = argv[i];
33+
size_t len = WideCharToMultiByte(CP_UTF8, 0, warg, -1, NULL, 0, NULL, NULL);
34+
if (!len) return 1;
35+
char *arg = (char*)alloca(len);
36+
if (!WideCharToMultiByte(CP_UTF8, 0, warg, -1, arg, len, NULL, NULL)) return 1;
37+
argv[i] = arg;
38+
}
39+
#endif
40+
41+
// initialization
42+
libsupport_init();
43+
// jl_options.compile_enabled = JL_OPTIONS_COMPILE_OFF;
44+
// JULIAC_PROGRAM_LIBNAME defined on command-line for compilation
45+
jl_options.image_file = JULIAC_PROGRAM_LIBNAME;
46+
julia_init(JL_IMAGE_JULIA_HOME);
47+
48+
// build arguments array: `String[ unsafe_string(argv[i]) for i in 1:argc ]`
49+
jl_array_t *ARGS = jl_alloc_array_1d(jl_apply_array_type(jl_string_type, 1), 0);
50+
JL_GC_PUSH1(&ARGS);
51+
jl_array_grow_end(ARGS, argc - 1);
52+
for (i = 1; i < argc; i++) {
53+
jl_value_t *s = (jl_value_t*)jl_cstr_to_string(argv[i]);
54+
jl_arrayset(ARGS, s, i - 1);
55+
}
56+
// call the work function, and get back a value
57+
retcode = julia_main(ARGS);
58+
JL_GC_POP();
59+
60+
// Cleanup and gracefully exit
61+
jl_atexit_hook(retcode);
62+
return retcode;
63+
}

0 commit comments

Comments
 (0)