-
-
Couldn't load subscription status.
- Fork 178
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
