【问题标题】:How can I use a specific build of Rust in a nixpkgs derivation?如何在 nixpkgs 派生中使用特定的 Rust 构建?
【发布时间】:2019-04-21 21:50:38
【问题描述】:

我正在尝试为我的一个可执行项目构建一个派生,它需要一个尚未在 nixpkgs 频道中的 Rust 版本,所以我构建了一个 nix 派生来安装我需要的那个版本:

{ mkDerivation, stdenv, fetchurl }:
rec {
    version = "1.33.0";
    platform = mkDerivation rec {
        ver = version;
        name = "rust-${ver}";
        platform = if stdenv.system == "x86_64-linux" then "x86_64-unknown-linux-gnu"
            else if stdenv.system == "x86_64-darwin" then "x86_64-apple-darwin"
            else abort "unsupported platform";
        pkgSha = if stdenv.system == "x86_64-linux" then "6623168b9ee9de79deb0d9274c577d741ea92003768660aca184e04fe774393f"
            else if stdenv.system == "x86_64-darwin" then "864e7c074a0b88e38883c87c169513d072300bb52e1d320a067bd34cf14f66bd"
            else abort "unsupported platform";

        src = fetchurl {
            url = "https://static.rust-lang.org/dist/rust-${ver}-${platform}.tar.gz";
            sha256 = pkgSha;
        };

        phases = ["unpackPhase" "installPhase"];
        installPhase = ''
            mkdir -p $out
            ./install.sh --prefix=$out
        '';
    };

    rustc = platform;
    cargo = platform;
}

这对我来说很容易整合到我的 shell 环境中,因为我只需要包含 buildInputs = [ rust.rustc rust.cargo ],然后我就立即拥有了 Rust 1.33。

我使用 carnix-0.9.8 设置了 Cargo.nixcrates-io.nixcrates-io.list 文件。因此,我所依赖的库会像任何其他派生一样安装到 nix 商店中,理论上我的构建过程最终根本不使用 Cargo。

我已经需要一个 macOS 原生安全库,所以我已经创建了一个 default.nix 文件:

{ pkgs ? import <nixpkgs-18.09> {}
, unstable ? import <nixpkgs> {}
, stdenv ? pkgs.stdenv
, licenses ? pkgs.lib.licenses
, maintainers ? pkgs.stdenv.maintainers }:
let
    rust = import ./nixpkgs/rust-1.33.nix {
      mkDerivation = pkgs.stdenv.mkDerivation;
      fetchurl = pkgs.fetchurl;
      stdenv = pkgs.stdenv;
    };

    cratesIO = import ./crates-io.nix {
        lib = stdenv.lib;
        buildRustCrate = unstable.buildRustCrate;
        buildRustCrateHelpers = unstable.buildRustCrateHelpers;
    };
    cargo = ...

    frameworks = ...
    security = ...
    orizentic = (cargo.orizentic {}).override { ... };

in pkgs.symlinkJoin rec {
    ...
}

然后我设置了一个 build.rs 文件,如果用于构建的 Rust 版本不是至少版本 1.33.0,则会出错。

如何将 我的 Rust 派生注入 buildRustCratebuildRustCrateHelpers

供参考,这里是the entire Rust version of my project

【问题讨论】:

    标签: rust nix


    【解决方案1】:

    我最近遇到了类似的问题,所以我可以在这里提供我的方法。我的 rustc 版本来自Mozilla overlay,但我想差异应该很小。

    { moz_overlay ? builtins.fetchTarball https://github.com/mozilla/nixpkgs-ozilla/archive/master.tar.gz
    , nixpkgs ? <nixpkgs>
    }:
    let
      moz_nixpkgs = import "${nixpkgs}" { overlays = [ (import "${moz_overlay}") ]; };
      rustc = (moz_nixpkgs.rustChannelOf { date = "2019-03-15"; channel = "nightly"; }).rust;
      crates = (import ./Cargo.nix {
        inherit (moz_nixpkgs) lib buildPlatform buildRustCrateHelpers fetchgit;
        buildRustCrate = moz_nixpkgs.buildRustCrate.override {
          inherit rustc; # I guess that injection happens here?
        };
        cratesIO = import ./nix/crates-io.nix {
          inherit (moz_nixpkgs) lib buildRustCrate buildRustCrateHelpers;
        };
      });
    in {
      myapp = crates.myapp {};
    }
    
    

    【讨论】:

    • 我终于回到了这个问题上,我有一个完整的项目正在尝试打包。不幸的是,虽然事情看起来是正确的,而且我肯定看到某个版本的 Rust 开始构建东西,但它总是无法尝试构建 libc Failed to get rustc version。这是非常令人沮丧的,因为 shell 环境完美地构建了 libc。所以,很明显,有些东西是完全不同的。
    • 终于解决了。 Nix 18.09 在 Rust 构建基础设施中有一个错误,该错误已在 Nix 19.03 中修复。 rustChannelOf 函数需要 Mozilla 覆盖,它提供了在 NixOS 上运行 Rust 所需的二进制补丁。 nixpkgs-19.03 中的 buildRustCrate 允许现在覆盖 rustc。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 2019-05-15
    • 1970-01-01
    • 2020-05-23
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多