PureScript 编译器安装全指南:预编译二进制、包管理器与 Stack 源码构建

原创2026-10-07 10:39:571,846 阅读
文章标签:编程语言编译器开发工具前端

PureScript 编译器安装全指南:预编译二进制、包管理器与 Stack 源码构建

导读:本文基于仓库根目录的 INSTALL.md 编写,系统梳理 PureScript 编译器(purs)在当前仓库(0.15.16,由 GHC 9.8.4 构建)下的全部安装途径——官方预编译二进制、NPM / Homebrew / FreeBSD / GNU Guix 等社区分发,以及使用 Stack 从源码自行编译的完整流程;同时针对 Linux 上 libtinfo 依赖缺失、npm 全局安装 EACCES 权限报错这两类高频安装故障给出定位与解决方案。读完本文,你可以根据自己的操作系统、架构与偏好,选择最合适的方式在几分钟内获得可用的 purs 可执行文件,并理解其版本输出与发布机制的底层细节。

一、安装前的系统要求:GHC 9.8.4 的支持范围

PureScript 编译器是用 Haskell 编写的(仓库 cabal 描述为 "A small strongly, statically typed programming language with expressive types, inspired by Haskell and compiling to JavaScript"),因此其运行平台的边界取决于构建所用 GHC 版本的支持范围。

按 INSTALL.md 的说明,当前编译器由 GHC 9.8.4 构建,可在 GHC 9.8.4 支持的任何操作系统上运行。具体而言:

  • Windows:早于 Vista 的版本不受官方支持;
  • macOS / OS X:早于 Mac OS X 10.7(Lion)的版本不受官方支持。

仓库中的构建配置与该要求一致:stack.yaml 使用 resolver: lts-23.18(该 snapshot 对应 GHC 9.8.x 系列),而 purescript.cabal 中 version: 0.15.16、base >=4.19.2.0 && <4.20 的依赖上界同样与 GHC 9.8.4 的 base 版本(4.19.x)吻合,可以作为“当前仓库实际由 GHC 9.8.4 构建”的实现层证据。

注意:这里描述的是“安装/运行”的支持范围,不涉及各平台下的语言特性差异;如果你所在平台不在 GHC 9.8.4 支持列表中,建议参考下文“从源码构建”一节,在其他环境(或交叉工具链)中自行产出可执行文件。

二、官方预编译二进制:解压即用的最快路径

每个 PureScript 官方 release 都会附带 Linux、macOS、Windows 三种平台的 x86-64 预编译二进制包。对绝大多数用户而言,这是最快、最不容易出错的安装方式:

  1. 在官方 release 页面下载对应平台与架构的压缩包;
  2. 解压后得到一个 purs 可执行文件;
  3. 将 purs 放入 PATH 环境变量中的任意目录(例如 ~/.local/bin、/usr/local/bin)。

仓库中 bundle/README 对二进制包的说明与此一致:

This bundle contains the purs executable; copy this file anywhere on your PATH. For information about how to use the purs executable, run purs --help.

也就是说,二进制包的内容就是一个自包含的 purs 可执行文件,无需任何额外运行库(详见下文“curses 库”一节,v0.14.2 之后预编译二进制已不再依赖 ncurses)。

适用范围与限制:官方预编译包仅提供 x86-64 架构。如果你使用的是其他操作系统或架构(如 ARM、RISC-V、PowerPC 等),通常需要自行从源码构建编译器——这正是下文“从源码构建”一节的适用场景。

三、包管理器分发:NPM、Homebrew、FreeBSD 与 Guix

INSTALL.md 列出了若干由社区维护的安装渠道,方便在不同生态中接入。需要注意:这些分发“并非官方发布流程的直接产物”,可能滞后于最新 release。

渠道 命令 适用场景
NPM npm install -g purescript Node.js 生态,可被前端构建工具链调用
Homebrew brew install purescript macOS
FreeBSD 二进制包 pkg install hs-purescript FreeBSD
GNU Guix guix install purescript GNU/Linux(Guix 发行版)

NPM 分发的实现机制

当前仓库的 npm-package/package.json 揭示了 npm 分发的工作方式,这对理解 npm install -g purescript 很有帮助:

  • 包名 purescript,版本 0.15.16(与 purescript.cabal 中的编译器版本保持一致);
  • bin 字段将命令 purs 映射到 purs.bin(发布时由 prepublishOnly 脚本从 purs.bin.placeholder 复制生成);
  • postinstall 脚本执行 install-purescript --purs-ver=0.15.16,即借助 purescript-installer 依赖,在安装时拉取并放置对应版本的 purs 二进制。

从源码结构看,npm 包本质上是一个“下载器 + 包装器”:它并不包含编译器源码,而是在安装时获取与 --purs-ver 指定版本匹配的预编译二进制。这也解释了为什么 npm 安装失败时通常表现为网络或权限问题(见下文“EACCES 错误”一节),而非编译器自身的问题。发布流程细节可参见 RELEASE_GUIDE.md(其中维护者发布后需验证 npm i purescript 与 npm i purescript@next 两种安装方式均可工作)。

四、从源码构建:Stack 方式与工程化细节

当没有对应平台的预编译二进制时,从源码构建是唯一途径。官方推荐的方式是使用 Stack,完整步骤如下:

$ stack update
$ stack unpack purescript
$ cd purescript-x.y.z  # (将 x.y.z 替换为你下载到的版本号)
$ stack install --flag purescript:RELEASE

执行完毕后,编译得到的 purs 可执行文件会被复制到 ~/.local/bin。如果尚未安装 Stack 本身,请参考 Stack 官方文档的安装与升级说明(INSTALL.md 中给出了对应链接)。

构建配置的源码级解读

仓库中的构建配置文件可以帮你理解上述命令背后的行为:

  • --flag purescript:RELEASE 的含义:该 flag 对应 purescript.cabal 中定义的 flag release(描述为 "Mark this build as a release build: prevents inclusion of extra info e.g. commit SHA in --version output")。从 app/Version.hs 的实现可以看到:定义了 RELEASE 时,purs --version 只输出版本号;未定义时,版本字符串会附加上 [development build; commit: <git hash> DIRTY?] 之类的开发构建信息。因此发布版二进制请务必带 RELEASE flag 构建,这样 --version 输出才会干净、可被工具解析。
  • 构建优化:stack.yaml 中对本地包统一启用了 -O2 -Werror -fspecialize-aggressively -fexpose-all-unfoldings,并固定了 language-javascript-0.7.0.0 等 extra-deps(原因是新版对 async 关键字作为对象键的解析存在回归)。
  • 静态链接选项:purescript.cabal 还提供了 flag static(manual: True),开启后通过 ld-options: -static -pthread 产出静态链接的可执行文件,适合需要部署到无 Haskell 运行时环境的场景。
  • Makefile 快捷目标:仓库根目录 Makefile 提供了等价的开发目标:make build(stack build purescript)、make install(stack install)、make run(stack build --fast && stack exec -- purs)、make test(stack test --fast purescript)、make ghci(打开 GHCi 交互环境)等。日常调试迭代可优先使用这些目标,它们封装了与 stack.yaml 一致的参数。

构建产物验证

构建成功后,可以用以下命令确认安装是否正常:

$ purs --version
$ purs --help

purs --help 会列出全部子命令(compile、repl、docs、graph、ide、publish 等,对应 app 目录下的各 Command 模块);purs --version 的输出行为则如前所述取决于是否定义了 RELEASE 宏。

五、历史遗留问题:curses 库与 libtinfo 报错

这是 PureScript 安装史上一个著名的坑,INSTALL.md 专门用一节解释:

  • 问题背景:在 v0.14.2 之前,PureScript REPL 默认依赖 curses 库(通过 Haskell 的 terminfo 包)。如果系统缺少该动态库,运行 purs 时会报:
    error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
    
  • Linux 上的修复:手动安装 ncurses。以 Ubuntu 为例:
    $ sudo apt install libtinfo5 libncurses5-dev
    
  • 现状(v0.14.2 起):使用官方预编译二进制或以默认配置从源码构建时,不再需要 ncurses。如果仍然希望启用 curses(例如获得更好的长行输入编辑体验),可以在构建时把 Haskeline 的 terminfo flag 设为 true 来“opt in”。

这条信息与仓库现状是吻合的:purescript.cabal 中 Haskeline 的版本约束为 haskeline >=0.8.2.1 && <0.9,但并未强制开启 terminfo 特性,因此默认构建产物不再绑定系统级 curses 动态库。

排查建议:如果你的 purs 恰好报出 libtinfo 相关错误,请先确认二进制来源(是否 v0.14.2 之前的旧版),再按上述 apt 方式补齐系统库,或直接改用新版预编译二进制。

六、npm 安装报 EACCES: permission denied

使用 npm install -g purescript 时,如果出现:

Error: EACCES: permission denied

其根因是 npm 全局安装目录的写入权限不足(例如默认全局目录位于系统级路径、当前用户无写权限)。INSTALL.md 给出的最佳解决方案是:

  • 通过 Node 版本管理器(node version manager) 安装 Node.js 和 npm;
  • 这样全局包会被安装到用户目录下的受控位置,天然规避权限问题;
  • npm 官方文档中关于 "resolving EACCES permissions errors when installing packages globally" 一节对此错误有更系统的说明。

这一建议与 npm 包的工作机制一致(见上文第三节):purescript 的 npm 包在 postinstall 阶段要通过 purescript-installer 将二进制写入安装位置,全局安装路径无写权限时,该阶段就会直接失败。

七、安装后快速自检清单

完成任一种安装后,建议按以下顺序确认环境就绪:

  1. purs --version:能打印版本号(官方预编译二进制或带 RELEASE flag 构建的输出不含 commit 后缀);
  2. purs --help:能看到完整的子命令列表;
  3. purs repl:能进入 REPL 交互环境(验证 REPL 相关依赖正常);
  4. which purs:确认 purs 位于 PATH 中你预期的目录。

如果以上任何一步失败,回到对应章节排查:版本与平台要求(第一节)、二进制来源(第二、三节)、源码构建参数(第四节)、系统库缺失(第五节)、权限问题(第六节)。

八、维护视角:INSTALL.md 与发布流程的联动

最后补充一个对镜像维护者有用的视角:RELEASE_GUIDE.md 在每次发布前明确要求“检查 INSTALL.md 是否保持最新”,包括:GHC 版本是否与当前构建一致、基于 GHC 版本的支持操作系统列表是否正确、是否有已停止维护的非官方安装渠道需要移除、源码构建步骤是否仍然可用。同时,INSTALL.md 本身也被列入 purescript.cabal 的 extra-source-files,随源码发行包一起分发。

这说明本文所有安装途径(预编译二进制、npm、Homebrew、FreeBSD、Guix、Stack 源码构建)都是发布流程中被主动维护和验证的“第一等公民”,你在镜像中看到的本文件与仓库代码、构建配置保持同一版本节奏。若发现安装文档与某个新 release 的实际情况不符,多半是发布前的同步遗漏,可对照 CHANGELOG.md 与 RELEASE_GUIDE.md 进一步核实。

登录后查看全文
purescript