在包含多个模块的单一代码库的上下文中,我发现了一个与clojure.tools.build.api/compile-clj
相关的问题,这个问题使得在基本项目根不是当前目录时难以编译文件。
以下是一个演示问题的最小场景。
我有一个使用tools.build来准备/包装其模块的顶级单一代码库deps.edn
{:deps {monorepo/module-a {:local/root "modules/a"}}
:aliases {:build {:deps {io.github.clojure/tools.build {:git/tag "v0.8.2"
:git/sha "ba1a2bf"}}
:ns-default build}}}
模块A包含一些Clojure源文件。这是modules/a/deps.edn
{:paths ["src"]}
这些文件需要一个编译步骤。这是用于处理这些文件的顶级build.clj
文件。
(ns build
(:require [clojure.tools.build.api :as b]))
(def module-a (binding [b/*project-root* "modules/a"]
(b/create-basis {:project "deps.edn"})))
(defn compile-a [_]
(b/compile-clj
{:basis module-a
:src-dirs ["modules/a/src"]
:class-dir "target/module-a/classes"}))
然而,当我从顶级目录调用clojure -T:build compile-a
时,遇到了以下错误
Execution error (FileNotFoundException) at user/eval136$fn (compile.clj:5).
Could not locate monorepo/module/a__init.class, monorepo/module/a.clj or monorepo/module/a.cljc on classpath.
问题在于“src”相对目录在:classpath-roots
中未展开,导致compile-clj
在错误的位置搜索源文件。可以通过再次绑定*project-root*
并像这样根据模块A的根目录调整:src-dirs
和class-dir
来解决此问题
(defn compile-a [_]
(binding [b/*project-root* "modules/a"]
(b/compile-clj
{:basis module-a
:src-dirs ["src"]
:class-dir "../../target/module-a/classes"})))
然而,我认为如果在基数中全面展开计算出的类路径(即将相对路径转换为绝对路径)来避免这种额外仪式会更好。
您怎么看?
相对源路径目录目前保持相对的路径有什么原因吗?