Skip to content

Commit 164e116

Browse files
authored
Merge pull request #63 from frenchy64/update-2024
Update tutorial for graalvm21 and Clojure 1.12
2 parents a306479 + 7a3ef3b commit 164e116

File tree

1 file changed

+83
-42
lines changed

1 file changed

+83
-42
lines changed

doc/clojure-graalvm-native-binary.md

+83-42
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ OpenJDK Runtime Environment GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02)
1919
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02, mixed mode, sharing)
2020
```
2121

22-
Now install the `native-image` component:
22+
For GraalVM versions before v21, you must now install the `native-image` component:
2323

2424
``` bash
2525
$ gu install native-image
@@ -35,6 +35,14 @@ graalvm 20.1.0 GraalVM Core
3535
native-image 20.1.0 Native Image github.com
3636
```
3737

38+
At this point you should have access to the `native-image` command:
39+
40+
```
41+
$ native-image
42+
Please specify options for native-image building or use --help for more info.
43+
```
44+
45+
3846
**NOTE**: *if you are on Mac OSX you might need to de-quarantine the binaries.*
3947
Here a script to do so:
4048

@@ -64,15 +72,12 @@ Update the `project.clj` and add the `:main`
6472
:url "http://example.com/FIXME"
6573
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
6674
:url "https://www.eclipse.org/legal/epl-2.0/"}
67-
;; clojure version "1.10.2-alpha1" includes fixes for some graalvm specific issues
68-
;; see https://clojure.org/community/devchangelog#_release_1_10_2
69-
:dependencies [[org.clojure/clojure "1.10.3"]]
75+
:dependencies [[org.clojure/clojure "1.12.0"]]
7076
;; add the main namespace
7177
:main hello-world.core
7278

7379
;; add AOT compilation
74-
:profiles {:uberjar {:aot :all}}
75-
)
80+
:profiles {:uberjar {:aot :all}})
7681
```
7782

7883
Add a `-main` function in your `hello-world.core` namespace
@@ -118,22 +123,71 @@ native-image --report-unsupported-elements-at-runtime \
118123
-jar ./target/hello-world-0.1.0-SNAPSHOT-standalone.jar \
119124
-H:Name=./target/hello-world
120125

121-
[./target/hello-world:33840] classlist: 3,119.60 ms, 0.96 GB
122-
[./target/hello-world:33840] (cap): 2,250.97 ms, 0.96 GB
123-
[./target/hello-world:33840] setup: 3,980.23 ms, 0.96 GB
124-
[./target/hello-world:33840] (clinit): 163.43 ms, 1.72 GB
125-
[./target/hello-world:33840] (typeflow): 6,249.38 ms, 1.72 GB
126-
[./target/hello-world:33840] (objects): 4,975.02 ms, 1.72 GB
127-
[./target/hello-world:33840] (features): 202.49 ms, 1.72 GB
128-
[./target/hello-world:33840] analysis: 11,819.61 ms, 1.72 GB
129-
[./target/hello-world:33840] universe: 341.69 ms, 1.72 GB
130-
[./target/hello-world:33840] (parse): 1,850.44 ms, 1.72 GB
131-
[./target/hello-world:33840] (inline): 2,497.03 ms, 1.72 GB
132-
[./target/hello-world:33840] (compile): 12,415.94 ms, 2.35 GB
133-
[./target/hello-world:33840] compile: 17,341.60 ms, 2.35 GB
134-
[./target/hello-world:33840] image: 1,197.96 ms, 2.35 GB
135-
[./target/hello-world:33840] write: 643.75 ms, 2.35 GB
136-
[./target/hello-world:33840] [total]: 38,716.97 ms, 2.35 GB
126+
Warning: Ignoring server-mode native-image argument --no-server.
127+
Warning: The option '-H:Name=./target/hello-world' is experimental and must be enabled via '-H:+UnlockExperimentalVMOptions' in the future.
128+
Warning: Please re-evaluate whether any experimental option is required, and either remove or unlock it. The build output lists all active experimental options, including where they come from and possible alternatives. If you think an experimental option should be considered as stable, please file an issue.
129+
========================================================================================================================
130+
GraalVM Native Image: Generating 'hello-world' (executable)...
131+
========================================================================================================================
132+
For detailed information and explanations on the build output, visit:
133+
https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md
134+
------------------------------------------------------------------------------------------------------------------------
135+
[1/8] Initializing... (8.1s @ 0.14GB)
136+
Java version: 21.0.2+13, vendor version: GraalVM CE 21.0.2+13.1
137+
Graal compiler: optimization level: 2, target machine: x86-64-v3
138+
C compiler: cc (apple, x86_64, 15.0.0)
139+
Garbage collector: Serial GC (max heap size: 80% of RAM)
140+
1 user-specific feature(s):
141+
- com.oracle.svm.thirdparty.gson.GsonFeature
142+
------------------------------------------------------------------------------------------------------------------------
143+
1 experimental option(s) unlocked:
144+
- '-H:Name' (alternative API option(s): -o hello-world; origin(s): command line)
145+
------------------------------------------------------------------------------------------------------------------------
146+
Build resources:
147+
- 10.44GB of memory (32.6% of 32.00GB system memory, determined at start)
148+
- 8 thread(s) (100.0% of 8 available processor(s), determined at start)
149+
[2/8] Performing analysis... [*****] (15.4s @ 0.31GB)
150+
3,582 reachable types (73.9% of 4,850 total)
151+
4,056 reachable fields (49.9% of 8,130 total)
152+
17,154 reachable methods (45.5% of 37,736 total)
153+
1,097 types, 87 fields, and 695 methods registered for reflection
154+
57 types, 57 fields, and 52 methods registered for JNI access
155+
4 native libraries: -framework Foundation, dl, pthread, z
156+
[3/8] Building universe... (3.4s @ 0.33GB)
157+
[4/8] Parsing methods... [*] (1.9s @ 0.38GB)
158+
[5/8] Inlining methods... [***] (1.7s @ 0.38GB)
159+
[6/8] Compiling methods... [****] (16.0s @ 0.32GB)
160+
[7/8] Layouting methods... [*] (2.0s @ 0.38GB)
161+
[8/8] Creating image... [**] (2.9s @ 0.30GB)
162+
6.01MB (41.80%) for code area: 10,000 compilation units
163+
8.16MB (56.77%) for image heap: 102,439 objects and 47 resources
164+
210.63kB ( 1.43%) for other data
165+
14.38MB in total
166+
------------------------------------------------------------------------------------------------------------------------
167+
Top 10 origins of code area: Top 10 object types in image heap:
168+
4.11MB java.base 1.80MB byte[] for code metadata
169+
976.71kB svm.jar (Native Image) 1.33MB byte[] for java.lang.String
170+
550.00kB hello-world-0.1.0-SNAPSHOT-standalone.jar 1012.91kB java.lang.String
171+
113.72kB java.logging 880.58kB java.lang.Class
172+
65.03kB org.graalvm.nativeimage.base 307.83kB com.oracle.svm.core.hub.DynamicHubCompanion
173+
47.59kB jdk.proxy1 279.30kB byte[] for general heap data
174+
45.84kB jdk.proxy3 244.73kB java.util.HashMap$Node
175+
27.06kB jdk.internal.vm.ci 225.45kB java.lang.Object[]
176+
22.06kB org.graalvm.collections 210.27kB heap alignment
177+
11.42kB jdk.proxy2 193.56kB java.lang.String[]
178+
11.17kB for 3 more packages 1.75MB for 1035 more object types
179+
------------------------------------------------------------------------------------------------------------------------
180+
Recommendations:
181+
INIT: Adopt '--strict-image-heap' to prepare for the next GraalVM release.
182+
HEAP: Set max heap for improved and more predictable memory usage.
183+
CPU: Enable more CPU features with '-march=native' for improved performance.
184+
------------------------------------------------------------------------------------------------------------------------
185+
2.9s (5.5% of total time) in 287 GCs | Peak RSS: 0.95GB | CPU load: 5.01
186+
------------------------------------------------------------------------------------------------------------------------
187+
Produced artifacts:
188+
/Users/clojure/hello-world/target/hello-world (executable)
189+
========================================================================================================================
190+
Finished generating 'hello-world' in 52.0s.
137191
```
138192

139193
That's it! now you can test your native binary!
@@ -194,7 +248,7 @@ Overall your `project.clj` should look like as follow:
194248
:url "http://example.com/FIXME"
195249
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
196250
:url "https://www.eclipse.org/legal/epl-2.0/"}
197-
:dependencies [[org.clojure/clojure "1.9.0"]]
251+
:dependencies [[org.clojure/clojure "1.12.0"]]
198252
:main hello-world.core
199253
:profiles {:uberjar {:aot :all}
200254
:dev {:plugins [[lein-shell "0.5.0"]]}}
@@ -205,31 +259,18 @@ Overall your `project.clj` should look like as follow:
205259
"native-image" "--report-unsupported-elements-at-runtime"
206260
"--initialize-at-build-time" "--no-server"
207261
"-jar" "./target/${:uberjar-name:-${:name}-${:version}-standalone.jar}"
208-
"-H:Name=./target/${:name}"]}
209-
)
262+
"-H:Name=./target/${:name}"]})
210263
```
211264

212265
With this in place you can just run `lein native` to build the native binary:
213266

214267
``` bash
215268
$ lein native
216-
OpenJDK 64-Bit Server VM warning: forcing TieredStopAtLevel to full optimization because JVMCI is enabled
217-
[./target/hello-world:33980] classlist: 2,970.75 ms, 0.96 GB
218-
[./target/hello-world:33980] (cap): 2,824.32 ms, 0.96 GB
219-
[./target/hello-world:33980] setup: 4,532.29 ms, 0.96 GB
220-
[./target/hello-world:33980] (clinit): 180.49 ms, 1.72 GB
221-
[./target/hello-world:33980] (typeflow): 6,960.70 ms, 1.72 GB
222-
[./target/hello-world:33980] (objects): 4,050.59 ms, 1.72 GB
223-
[./target/hello-world:33980] (features): 267.73 ms, 1.72 GB
224-
[./target/hello-world:33980] analysis: 11,822.33 ms, 1.72 GB
225-
[./target/hello-world:33980] universe: 322.57 ms, 1.72 GB
226-
[./target/hello-world:33980] (parse): 1,758.44 ms, 1.72 GB
227-
[./target/hello-world:33980] (inline): 2,497.64 ms, 1.72 GB
228-
[./target/hello-world:33980] (compile): 12,186.63 ms, 2.35 GB
229-
[./target/hello-world:33980] compile: 17,039.18 ms, 2.35 GB
230-
[./target/hello-world:33980] image: 1,252.06 ms, 2.35 GB
231-
[./target/hello-world:33980] write: 430.08 ms, 2.35 GB
232-
[./target/hello-world:33980] [total]: 38,668.99 ms, 2.35 GB
269+
...
270+
Produced artifacts:
271+
/Users/clojure/hello-world/target/hello-world (executable)
272+
========================================================================================================================
273+
Finished generating 'hello-world' in 52.4s.
233274

234275
$ ./target/hello-world
235276
Hello, World!

0 commit comments

Comments
 (0)