简述
公司有一个项目我用clojure写了一个数据处理的SDK,里面混合了Java和Clojure的代码,之前用习惯了Leiningen,不过慢慢的感觉Leiningen越来越慢了(不知道是不是错觉),这次打算使用deps.edn管理项目。
环境准备(包含开发工具相关的包)
# windows
PS> scoop install openjdk
PS> scoop install clojure
PS> scoop install clojure-lsp
PS> scoop install clj-deps
# mise
$ mise install java
$ mise install clojure
$ sudo bash < <(curl -s https://raw.githubusercontent.com/clojure-lsp/clojure-lsp/master/install)
# macos
$ brew install openjdk
$ brew install clojure
$ brew install clojure-lsp/brew/clojure-lsp-native
添加deps.edn文件
添加deps.edn文件,并添加tools.build依赖
{:deps {org.clojure/clojure {:mvn/version "1.11.3"}}
:paths ["src/main/clojure", "src/main/java", "src/main/resources", "src/test/clojure"]
:aliases {:build {:deps {io.github.clojure/tools.build {:mvn/version "0.10.5"}}
:ns-default build}}}
添加build.clj文件
在项目根目录添加build.clj用于项目构建
(ns build
(:require [clojure.tools.build.api :as b])
(:import java.io.File))
(def lib 'io.github.leejoker/your-package-name)
(def version "1.0.0")
(def class-dir "target/classes")
(def basis (delay (b/create-basis {:project "deps.edn"})))
(def jar-file (format "target/%s-%s.jar" (name lib) version))
(def uber-file (format "target/%s-%s-standalone.jar" (name lib) version))
(defn clean [_]
(b/delete {:path "target"}))
(defn copy-src [_]
(b/copy-dir {:src-dirs ["src/main/clojure" "src/main/resources"]
:target-dir class-dir}))
(defn compile-java [_]
(if (not-empty (.listFiles (File. "src/main/java")))
(b/javac {:src-dirs ["src/main/java"]
:class-dir class-dir
:basis @basis
:javac-opts ["--release" "11"]})
(println "java file not found")))
(defn compile-clojure [_]
(b/compile-clj {:basis @basis
:ns-compile '[io.github.leejoker.app] ;; 需要暴露的ns,用于生成提供static方法的类
:class-dir class-dir}))
(defn compile-all [_]
(clean nil)
(b/write-pom {:class-dir class-dir
:lib lib
:version version
:basis @basis
:src-dirs ["src/main/clojure"]})
(copy-src nil)
(compile-java nil)
(compile-clojure nil))
(defn jar [_]
(compile-all nil)
(b/jar {:class-dir class-dir
:jar-file jar-file}))
(defn uber [_]
(compile-all nil)
(b/uber {:class-dir class-dir
:uber-file uber-file
:basis @basis
:main 'io.github.leejoker.app})) ;; 向jar包中添加main-class信息,如果是SDK其实可以没有
这样就基本上完成了。
使用clj命令进行编译
# 清理 target 目录
$ clj -T:build clean
# 编译java文件
$ clj -T:build compile-java
# 编译clojure文件
$ clj -T:build compile-clojure
# 编译所有文件
$ clj -T:build compile-all
# 编译不含依赖的jar
$ clj -T:build jar
# 编译fat jar
$ clj -T:build uber