Julia2nix 的相关讨论

Nix 是以函数式编程语言去组建可声明,可重复构建的,且信赖的包管理和操作系统。julia2nix 皆为 Julia 编程语言提供 友好的 Nix 的接口和探索可能性,方便以 Nix/NixOS 为生态基础的开发者和用户轻松且方便的使用 Julia 生态.

JuliaCN/Julia2Nix.jl: WIP The Nix interface to Julia Pkg 是我最近学习 Julia Lang 和基于一些社区已有的项目来进行二次开发和维护的,在 julia 语言使用方面非常生涩。所以 juliaCN 发帖的缘由是阐述一下项目思路和缘由,降低对 Nix 语言本身的需求,让一些 Julia 开发者加入进来,帮助 Julia2nix 有良好的发展。

Questions?

  1. 想要参与或者贡献 Julia2nix 需要对 Nix 的掌握的程度如何

如果有兴趣学习 Nix Lang 的一些语法会是非常好的,大部分 Nix 相关的工作和实现将由我来完成,所以 NixLang 的掌握不是必要条件。

  1. 在开始之前我需要下载什么依赖

Julia2nix 带有一个可声明式的 develop shell 将包含所有开发所需要的环境和配置,用户只需要下载 nix 就好,无需其他操作。

就会得到相应的开发环境,类似于 Python 的 poetry shell.

  1. 需要具备什么知识才能开发 Julia2nix

对 julia Pkg.jl 和包构建机制理解透彻,能够用 julia lang 实现相关的流程就可以,其次对 julia 在 common development tools 有想法和编写过相关工具的都会给 julia2nix 带来帮助如,Roger-luo/IonCLI.jl: The Ion CLI for Julia.

  1. Julia2nix 的基本内核是什么

由于 Nix 可重复构建的特性,和构建途中尽可能不引入不稳定的因素。如.git 文件和无网路的沙盒化构建(building step),所以一切依赖的引入都要声明和具有唯一 hash 值。

因此,解析 julia 的 manifest.toml and project.toml 将下载源转换为 Nix 可以下载的文件类型和生成 唯一 hash. 通过 msteen/nix-prefetch: Prefetch any fetcher function call, e.g. a package source 和 julia lang 的编写实现这一过程,是 julia2nix 的基本底层。且相关步骤已经在 julia2nix 实现, Julia2Nix.jl/Depot.nix at main · JuliaCN/Julia2Nix.jl.

对于 Julia2nix 基本功能的一些期望

  1. 更加方便且快速的解析 julia 的 manifest/project.toml 详细 (核心)
  2. 提升代码的整洁性,注释。
  3. 将解析数据和输出数据接口明确分离,提升 debugging 和 developinng 体验
  4. 为 Julia Project/package 提供基本工能 toolchain 和常用的功能如
    1. 打包为 DockerImage
    2. 提供 SnoopCompile 等的静态构建发布
    3. 提供可声明式的 develop shell 环境用于快速开发
    4. 提供 common developing commands 像 Roger-luo/IonCLI.jl: The Ion CLI for Julia. 一样。

Why Julia2nix ?

  1. 首先 NixOS/nixpkgs: Nix Packages collection 拥有非常庞大且完整的依赖和包管理库,基于 nix/nixos 的生态,可以为 julia packages/projects 封装成 拥有唯一 hash 的环境和打包格式,每次的构建和所属的依赖都将会生产唯一的 hash ,天然的给 sandboxing, reproducible,mutil-Arch and cross-compiling 提供了优势和可能性。

  2. versioing control:

无论是 julia 在的各种版本号,和各个依赖的版本定制和改动在 Nix 里面都可以轻松实现,可以提供用户不同的开发体验和 不同于官方本身的 CI 测试需求。

如对于 CUDA 开发的同学可能需要不同版本和依赖的测试,那么 Julia2nix 也能提供非常方便的特性。如 hasktorch/flake.nix at master · hasktorch/hasktorch
做的那样。

  • Julia2nix 具有模板性

随着未来维护和开发的可能性,julia2nix 可以提供不同环境下用户开发的依赖和需求,通过 nix develop 进入一下进入相应的 shell 环境.用可以在一个 common template 上进行自己的需求扩展

  1. julia2default

    将会包含常用的 commands, julia flow, env,开发工具的包含,像 Roger-luo/Ion.jl: REPL/CLI based Developer Toolchain for Julia 我们将直接封装在 develop shell 里面,用户无需多余下载。

  2. julia2CUDA

    将会包含 cuda10/ cud11, cup,gpu 的环境的 shell 为当前的 project

  3. julia2data-science

    将会包含 jupyterLab 和 julia pluto 等相关环境和一些常用包,并且提供 open blas/MLK 的 override 接口,方便用户对其各种定制化修改

Julia2nix 目前完成了那些工作?

Julia develop => shell Mode 的实现

基于 Nix 和 direnv – unclutter your .profile | direnv,julia2nix develop 对 Roger-luo/Ion.jl: REPL/CLI based Developer Toolchain for Julia, Roger-luo/IonCLI.jl: The Ion CLI for Julia. 进行了一些衔接和想法改进。

用户在当前的可以下或者运行 julia2nix 的相应模板和 shell 的名字就可以进入对于的开发环境.

nix develop github:JuliaCN/Julia2Nix.jl#devShell.x86_64-linux.default
# or
nix develop github:JuliaCN/Julia2Nix.jl#devShell.x86_64-linux.cuda


Julia2nix 一些激进的想法和 roadmap

2 个赞

正向也可以让 Pkg.jl (julia 内置的包管理器)吸收一些 nix 的想法,甚至于和 nix 有部分的融合。

我不太了解 nix,经过简单搜索后

Nix 是一个操作系统包管理器。同 RPMAPT 和许多其它的软件包管理系统一样,它可以用来控制软件包的安装

此系统的纯函数式性质能够保证非常精准的依赖跟踪。
—— zh-wp

让我产生了一些其他的想法:
julia 目前选择通过 GitHub - JuliaPackaging/Yggdrasil: Collection of builder repositories for BinaryBuilder.jl 注册并自行分发(由 github release 进行分发)二进制的工件。

julia 目前自行分发二进制工件实际上做了很多重复的工作。
除了绑定二进制文件的胶水代码、部分Julia定义的带有自定义 patch 的工件以外。
大多数的工件其实完全可以从其他的包管理器发行渠道中获得。
或者至少,选择部分 ABI 兼容的发行渠道,有条件时利用一下他们的镜像。这样能大大加速国内的下载速度。(目前的镜像并不包括由 github 分发的工件)

能否反过来,把 nix 当作二进制工件的分发源,然后能把 nix 的产物打包为 jll(只需要 nix 能提供稳定的工件版本 => 物理路径关系),让 julia 能导入。
或者说让 nix 成为 Yggdrasil 注册时的二进制工件来源之一。(目前的主要分发源其实是 github)

我看了一下yggdrasil的代码,我可以非常确信,使用julia2nix可以自动化完成所有包的二进制编译发布,带有自定义的patch也无需担心,nix的拥有灵活的的overlay/ override的机制,可以精准的patch任何一个包。函数式的特性也无需写多余的代码。
Nix和julia2nix的不同于其他的包管理器是,沙盒构建的严格和静态数据引入的确定性,所有的源码依赖都得编译后生成hash。

只需要 nix 能提供稳定的工件版本 => 物理路径关系),让 julia 能导入。

这个百分百是可行的,julia2nix的buildPackage function就对当前的project生成一个依赖物理关系生成links,并将其的依赖,环境变量,julia-depot_path, 将其wrapping进julia-bin,变成独属于当前project的julia-bin。其次可以为当前的每个julia包二进制,并且生成binary cache,用户还可以自行分发binary cache通过ssh, 或者cloud storage. 无需再次从github下载和编译。

julia2nix目前主要做的是对Pkg.jl的数据解析解析,能够让nix可读,为开发环境和二进制分发提供可靠的流程。目前已经以及基本做到了,但是代码比较ditry,需要更加结构化和精准的信息,以此帮助后续的强大功能。

如果你对julia2nix有兴趣,可以下载个nix,然后看看julia2nix的write depot是如何实现的,我相信这是一个非常有前景的项目和想法。

1 个赞

鉴于 julia 目前的文档完善程度,我建议不懂就问吧,中文、英文社区都行。
英文社区一般能直接找到维护者,问背后的设计想法,以及对于你想做的事该怎么做
好在大部分 julia 包都是使用 julia 编写的,这样便于阅读也方便调试。没有文档的是时候不至于失去方向。
Pkg.jl 估计不会比 julia 本身的文档好到那里去。


我去英文社区找了一些和 nix 相关的 帖子,仅供参考

Julia2nix并不是build Julia on Nix/NixOS. 而是像 GitHub - input-output-hk/haskell.nix: Alternative Haskell Infrastructure for Nixpkgs 而是基于nixpkgs的julia开发环境和基础设施维护,将会和haskell.nix提供一样的API文档 Haskell.nix Library - Alternative Haskell Infrastructure for Nixpkgs 同理,haskell.nix你需要了解stack, hackage的原理,那么julia你需要解析manifest和julia的包构建过程,depot-path结构,并将它们解释给其他工具,如将用nix的方式还原出来。