-
-
Notifications
You must be signed in to change notification settings - Fork 180
Circumnavigating Watch and AOT Compilation Limitations
The problem: When one wants to have an executable recompiled each time a source file is changed, the waiting required is practically immeasurable. AOT is the culprit and can be reduced to interfering with one's life by the folliwing means. The jist is to create a shim that acts as an entry point to your application.
The structure (upon completion):
├── build.boot
├── src
│ ├── clj
│ │ └── foo
│ │ ├── core.clj <-- where -main is located
│ │ ├── bar.clj <-- a source file referenced in core.cljs
│ │ └── main.clj <-- the shim (entry point) of the app
│ └── cljc
│ └── foo
│ ├── schema.cljc
│ └── utils.cljc
└── target
└── project.jar
First, include the src
directories in resource-paths
within build.boot:
(set-env!
:resource-paths #{"src/cljc" "src/clj"}
...)
core.clj
looks something like the following (and notice :gen-class
is not present, as it goes in main.clj
):
(ns foo.core
(:require [clojure.tools.cli :as cli]
[foo.bar :refer [quux]]))
(defn -main [& argv]
...)
And main.clj
:
(ns foo.main
(:gen-class))
(defn -main [& args]
(require 'foo.core)
(apply (resolve 'foo.core/-main) args))
The time consuming problem with building is aot if it is applied to the whole source tree. With the method just described, the aot task can only be applied to main.clj
. More from build.boot:
(task-options!
aot {:namespace '#{foo.main}} ;; the only namespace touched
jar {:main 'foo.main} ;; the entry point
)
Now, from the command line boot aot uber jar target
builds the project. To leave only project.jar in the target
directory, add sift: boot aot uber jar sift --include '\.jar$' target
.
Or fashion a boot task:
(deftask bundle []
(task-options!
sift {:include #{#"\.jar$"}})
(comp (aot) (uber) (jar) (sift) (target)))
(deftask dev []
(comp (watch) (repl) (bundle)))
The latter task enables recompilation if a file is changed in the source directories.
You can find other developers and users in the #hoplon
channel on freenode IRC or the boot slack channel.
If you have questions or need help, please visit the Discourse site.
- Environments
- Boot environment
- Java environment
- Tasks
- Built-ins
- Third-party
- Tasks Options
- Filesets
- Target Directory
- Pods
- Boot Exceptions
- Configuring Boot
- Updating Boot
- Setting Clojure version
- JVM Options
- S3 Repositories
- Scripts
- Task Writer's Guide
- Require inside Tasks
- Boot for Leiningen Users
- Boot in Leiningen Projects
- Repl reloading
- Repository Credentials and Deploying
- Snippets
- Troubleshooting
- FAQ
- API docs
- Core
- Pod
- Util