2024 Clojure 状态调查! 中分享您的想法。

欢迎!请查看关于 页面了解该工作方式的一些更多信息。

+5
tools.deps
重标记

我在 Slack 上关于 PowerShell Clojure CLI 命令行在 Windows 中引入的问题表现得相当直言不讳。Alex Miller 要求描述这些问题,并附带社区反馈,以及通过某种决策表格展示可能的解决方案。

虽然我不太确定这种格式是否符合 Alex Miller 的要求,但我会尽可能做。
Clojure CLI 问题

在本文档中,我展示了两种可能的解决方案。
- 环绕 PowerShell 脚本的二进制包装器
- 可移植的二进制修改版的 bash/Powershell 脚本

这两种解决方案都需要较低程度的编码工作量,我创建了探索性项目。
- Clojure PowerShell CLI 包装器。在 Windows 上进行了测试。
- 可移植的 Clojure CLI 修改版。在 Windows 和 Linux 上进行了测试,它证明了可移植的解决方案并非不可轻易获得。

希望收到对提出的问题以及那两个项目的反馈。

相关 jira:https://clojure.atlassian.net/browse/TDEPS-136

4 个答案

+3

仅供参考,我之前开始了一个跨平台的实现,使用CLJS编写并通过npm分发。虽然不确定这是不是一个好主意,但鉴于如今Node.js的广泛分布,它可能对很多人来说是一个选择。

由于在Windows上存在这个问题——每次按下CTRL+C都会弹出Terminate batch job (Y/N)?的提示,我没有找到解决这个问题的方法,这相当令人烦恼。但Linux/macOS运行正常。

请参见https://github.com/thheller/clojure-cli


编辑
感谢您的意见
是的,这是一个批处理文件的问题,很多人都在抱怨这个问题。据我所知,除了替换命令解释器之外,没有解决这个问题的方法。
+1

我认为便携式Clojure CLI包装器的想法听起来不错,但对于大多数平台(Linux、BSD、OSX),bash可能实际上是一个更好的选择,因为它既简单又足够快。无需编译到不同的目标,也不需要32位和64位版本,或者下载适合您的版本的版本。

如果GraalVM的本地镜像已经退出预览,尤其是在Windows上,我会个人倾向于使用它。根据这个基准测试:https://github.com/chocolateboy/startup-time,它实际上和bash一样快,甚至更快。

根据上述基准和这个基准:https://github.com/bdrung/startup-time,Pascal实际上可能有最小的启动时间,其次是C。它显示Nim几乎和C一样快,比Go和Bash快。

依赖于另一种语言似乎有点奇怪,但话又说回来,bash也是一种语言,尽管可能因为某种原因,它看起来不太怪异。Windows不支持真正的Bash确实很遗憾。

如果GraalVM的本地镜像对于Windows来说足够健壮,我仍会投票支持它。鉴于Oracle对该项目的积极投入,它应该会随着时间的推移而不断改进。而且我认为Clojure CLI启动脚本所做的任何事情都不会与Graal冲突。而且它是真正意义上的Clojure。

否则,选择 Nim、C、Pascal 还是 Go 而不是 bash,这是只有维护者应该做出的决定。bash 的管道操作最为简单。只需要打包脚本,无需编译成不同的目标版本并提供不同的安装程序。这比 GraalVM 要简单得多。我理解为什么做出了这样的选择。但在 Windows 的情况下,确实提出了倾向于其他方案的理由。

顺便一提,我想在这里添加一些基准测试信息,特别是 Graal 原生映像在启动时间方面应该与 bash 具有竞争力。

为了使回答更具说服力,我认为我回答了:bash 提供了所有选项中最简单的包装方式,这最初是一个明智的选择,但随着 Windows 的加入,我们看到 bash 的可移植性不足,因此我们需要两个实现,在这种情况下,一个是 bash,另一个是 powershell,或者使用 Java、Nim、C 等更具可移植性的语言,并通过 GraalVM 编译,这样可以使单一代码库跨平台运行,但代价是编译和包装流程更为复杂。

感谢您的反馈。
选择 Nim 的部分原因是能够从单个操作系统上进行交叉编译到所有目标。无论如何,任何语言都行,完整代码在 3 到 400 行之间,这不算什么,并且可以随时重写。
我同意您的看法,bash 在 Posix 系统上的确非常好。
GraalVM 听起来是个不错的想法,但有两大问题。
   它目前在 Windows 上还未准备好进入生产环境。
   据我所知,无法获取用于调用 Java 程序的完整命令行,这在 Windows 上是必要的,以便以 POSIX 兼容的方式执行。我需要在这方面做更多研究。
我同意 GraalVM 二进制的启动时间看起来足够好,但二进制大小可能是另一个问题,但我们真的介意这个吗?
最后,我同意您的看法,最终的决定取决于 Clojure 团队。虽然有一丝紧迫感。人们每天都在评估工具,也许会因为 PowerShell CLI 的不足而放弃了它们。这可能会影响 deps.edn 项目的采用,至少在 Windows 用户中是这样。
啊哈! [https://github.com/profesorfalken/jProcesses] 可以获取命令行...
我不知道 Nim 有这样的特性。不过这确实是一个很好的观点,因为使用本地编译工具链的一个缺点是构建和打包需求更加复杂。如果 Nim 可以在没有需要在对应的平台下运行构建步骤的情况下为所有平台构建和打包,那么这可以让事情变得容易得多。实际上,我没有搞清楚 GraalVM 是否也是如此。
作为一个测试,我在便携式重写中增加了交叉编译(Linux 方面),看起来一切正常。
+1

我在现有的 Nim 实现基础上添加了rust 实现。那个实现比我想的要难得多,可能是因为我是新手。但一旦实现,就成功了!

以下是我对这个项目的更多思考。

对构建过程复杂性的担忧

交叉编译是解决这个问题的关键。我深入研究了这个话题。虽然我没有对 Darwin 进行研究,这是社区中非常重要的一部分,但我没有 Mac!这两个项目都是从 Linux 构建Windows 安装程序和 Linux 字节码。还提供了一个 Docker 文件和构建脚本来以平台无关、可重复的方式执行此操作。

  • 如果选择重写,我会建议在 Mac 上构建,执行提供的 Docker 构建,这样可以从同一个机器上覆盖所有三个平台。
  • 对于 Mac 构建,两个项目的代码都不需要修改(尽管我无法完全确定)
  • 如果我们只想做 Windows,我们仍然可以从 Windows、Linux、使用 Docker 的 Linux 或使用 Docker 的 Mac 上进行。

因此,针对这个问题:一个可用的 Docker 就是一切所需的设置,接着调用提供的 docker_build 脚本就完成所有构建、打包,甚至构建 Windows 安装程序。

Nim 与 Rust 的比较

两个项目都有相同的功能

Nim
- 使用愉快 -> 优点
- 容易学习、阅读和编写 -> 优点
- 发现 ZIP 文件实现中的 bug(我用它来规避 TDEP-120) -> 已经解决,但不是很好
- 社区规模小 -> 缺点
- 轻松交叉编译 -> 好的
- 不是负责任的选择 -> 错的
- 简洁 -> 好的
- 对 VS 代码的支持很好 -> 好的
Rust
- 约束与纪律 -> 两者都有利也有弊
- 非常稳定 -> 好的
- 更难编写 -> 不好
- 易于阅读 -> 我想是吧
- 很难与之共事 -> 差
- 轻松交叉编译 -> 好的
- 负责任的选择 -> 好
- 对 VS 代码的支持很好 -> 好的
- Emacs 支持极佳 -> 除了我之外,谁会在意呢?

尽管 Rust 更负责任,但我不得不回转到 Nim 实现,做一些修正,而在 Rust 之后的 Nim 实现就像呼吸新鲜空气一样。

Rust 版本显然没有 Nim 版本测试得那么彻底。

当然,我会继续维护这个包装器以及这两次重写,但这就是我在这个项目上停止积极工作的地方。

0

现在有一个使用 GraalVM 构建的 Clojure 实现,可以作为 Linux、Mac 和 Windows 的本地可执行文件: https://github.com/borkdude/deps.clj

在我看来,这将是最好的前进道路。

...