Skip to content

Instantly share code, notes, and snippets.

@p-himik
Last active March 12, 2020 19:59
Show Gist options
  • Save p-himik/fcf638b05d70d908c74d98e25fd9e935 to your computer and use it in GitHub Desktop.
Save p-himik/fcf638b05d70d908c74d98e25fd9e935 to your computer and use it in GitHub Desktop.
(ns prj.compile
(:require [clojure.tools.namespace.find :as ns.find]
[clojure.java.io :as io]
[clojure.string :as string]))
(defn current-classpath []
(vec (.split ^String
(System/getProperty "java.class.path")
(System/getProperty "path.separator"))))
(defn compiler-itself? [p]
(string/includes? p "prj.compile"))
(defn jar? [p]
;; We cannot control what happens in jars in general.
;; E.g. `manifold.deferred.IDeferred` defined in such
;; a way so that most of the time it doesn't even compile
;; leading to `ClassNotFoundException`. Probably depends
;; on the compilation order.
;; Another reason is that timestamps within jars are preserved.
;; Thus, we can end up having some library v2 on classpath
;; while v1 is compiled and is actually used.
(string/ends-with? p ".jar"))
(defn clojure-ns? [p]
;; Clojure is already compiled.
(string/includes? p "org/clojure/clojure"))
(defn output-dir? [p]
(= p *compile-path*))
(defn aot-namespaces [paths]
(ns.find/find-namespaces (map io/file paths)))
(defn -main [& _]
(let [paths (remove (some-fn jar? compiler-itself? output-dir? clojure-ns?) (current-classpath))
nss (aot-namespaces paths)]
(println "All paths:" paths)
(doseq [n nss]
(println "Compiling" n)
(try
(compile n)
(catch Throwable e
;; In this case, the usual reason for the error is a missing
;; optional runtime dependency that we don't actually use.
;; Another reason (I think) is that the class being compiled is actually
;; used during the compilation process. It causes incompatibility
;; between some classes due to the different class loaders.
(println "Unable to compile:" (.getMessage e)))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment