liveBook · Manning

Compile

As explained in Clojure: The Essential Reference

clojure.lang.Compile is the Clojure Java class whose main method performs ahead-of-time compilation from the command line.

`compile` performs ahead-of-time (AOT) compilation of a Clojure library. It accepts the library path as a symbol, parses and evaluates its forms much like `load`, and writes generated Java class files to disk. The main method of `clojure.lang.Compile` provides a command-line route to the same kind of compilation. section 17.4 section 23.7

Compile a namespace

With `source.clj` available on the classpath and containing `(ns source)` and `(defn plus [x y] (+ x y))`, evaluate `(compile 'source)`; the result is `source`. The output directory, `*compile-path*`, defaults to `classes`. Its generated files include classes that initialize the namespace and its vars and a class for `plus`. section 17.4 section 23.7

;; mkdir mypath
;; export CLOJURE_JAR=~/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar
;; java -cp $CLOJURE_JAR:mypath clojure.main ; #1

(spit "mypath/example.clj"
  "(ns example)
   (println \"example loaded\")")

(binding [*compile-path* "mypath"] ; #2
  (compile 'example))
;; example loaded
;; example

For a different output directory, put the source namespace on the classpath and bind `*compile-path*` around `compile`. Compiling also evaluates the namespace: its print statement runs in this example. section 23.7

Use AOT when disk-backed classes help startup time or make Clojure code available to other JVM languages. It also enables `gen-class` declarations to produce Java classes. A class with a generated `main` method still needs a corresponding `-main` implementation; otherwise calling it raises an exception. AOT is not a universal default: generated classes are tied to a particular Clojure-JVM version, and deciding when to rebuild them adds build complexity. section 15.3 section 17.4

Compilation can also control what enters the output. Binding `clojure.test/*load-tests*` to `false` while compiling prevents accompanying `deftest` functions from being generated. In short, `compile` evaluates a library as `load` does, but additionally leaves reusable class files on disk. section 23.14 section 17.4

How Clojure: The Essential Reference covers it

How deep it goes
Defines symbol input, evaluation, generated classes, output-path setup, and AOT trade-offs; does not detail command-line arguments.
Examples
Compiles namespaces, generates a Java entry point, and omits test functions by binding `clojure.test/*load-tests*`.
What it assumes
Assumes a namespace source file on the JVM classpath and an output directory; demonstrates classpath and directory setup.
What you can do after
Operate/configure it by setting `*compile-path*`, compiling a namespace, inspecting class files, or excluding compiled tests.
How it connects
Connects `compile` to `gen-class`, `*compile-files*`, `*compile-path*`, and `eval`.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.