esp-rs / espup

Tool for installing and maintaining Espressif Rust ecosystem.
Apache License 2.0
224 stars 23 forks source link

`cargo install espup` fails on NixOS #433

Closed Raikiri closed 3 months ago

Raikiri commented 3 months ago

Bug description

Running `cargo install espup' under nixos fails with the following error:

  running cd "/tmp/cargo-installHTf4sX/release/build/openssl-sys-b7ba76288060b32f/out/openssl-build/build/src" && "make" "depend"

  --- stderr
  thread 'main' panicked at /home/alexander/.cargo/registry/src/index.crates.io-6f17d22bba15001f/openssl-src-300.3.1+3.3.1/src/lib.rs:621:9:

  Error building OpenSSL dependencies:
      Command: cd "/tmp/cargo-installHTf4sX/release/build/openssl-sys-b7ba76288060b32f/out/openssl-build/build/src" && "make" "depend"
      Failed to execute: No such file or directory (os error 2)

  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: failed to compile `espup v0.12.0`, intermediate artifacts can be found at `/tmp/cargo-installHTf4sX`.

To Reproduce

Steps to reproduce the behavior:

  1. Install added rustup to configuration.nix
  2. Ran cargo install espup
  3. Got the error

Expected behavior

My understanding is that it's not supposed to break

Screenshots

Environment

Additional context

Raikiri commented 3 months ago

Apparently there's a nix package for espup: https://search.nixos.org/packages?channel=24.05&show=espup That seems to bypass the cargo install step?

UPD: no, this breaks down the line due to seemingly different components being installed in different ways. Looks like either everything needs to be installed by cargo or everything needs to be installed by nixos, othewise problems happen. I don't think I know what I'm doing at this point.

Raikiri commented 3 months ago

Pretty much every crate that depends on openssl fails to build. I created a new clean shell.nix and no matter where I add openssl, it fails with the same error:


  Error configuring OpenSSL build:
      Command: cd "/run/user/1000/cargo-installlEZxO3/release/build/openssl-sys-3474271da71eb491/out/openssl-build/build/src" && env -u CROSS_COMPILE AR="ar" CC="gcc" RANLIB="ranlib" "perl" "./Configure" "--prefix=/run/user/1000/cargo-installlEZxO3/release/build/openssl-sys-3474271da71eb491/out/openssl-build/install" "--openssldir=/usr/local/ssl" "no-dso" "no-shared" "no-ssl3" "no-tests" "no-comp" "no-zlib" "no-zlib-dynamic" "--libdir=lib" "no-md2" "no-rc5" "no-weak-ssl-ciphers" "no-camellia" "no-idea" "no-seed" "linux-x86_64" "-O2" "-ffunction-sections" "-fdata-sections" "-fPIC" "-m64"
      Failed to execute: No such file or directory (os error 2)

Currently I'm trying this in my shell.nix:

    nativeBuildInputs = with pkgs; [
      pkg-config
      openssl
      openssl.dev
      stdenv.cc.cc
    ];
    PKG_CONFIG_PATH = "${pkgs.openssl.dev}/lib/pkgconfig";

openssl seems to be really determined to read from /run/user/1000/ that does not exist on nixos and i've no idea what to do about it.

Raikiri commented 3 months ago

Omg I figured it out. Apparently the No such file or directory doesn't actually refer to a missing directory, it refers to missing perl of all thing! Anyway. Adding perl to my build inputs fixed the issue. I hope it could be communicated better in the error message, because nothing even mentions perl there.

Anyway, that's not the end of my woes. There's also lots of out-of-space errors because nix-shell uses the wrong directory for temporary files or something. Anyway, that's seemingly fixed by adding to configuration.nix a temp directory (?):

  environment.sessionVariables.TMPDIR = "/tmp";

To be honesty I don't understand why setting an environment variable affects a nix-shell --pure environment but apparently it does somehow.

So if somebody else finds this, here's my shell.nix configuration for rust:

{ pkgs ? import <nixpkgs> {} }:
  let
    overrides = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml));
    libPath = with pkgs; lib.makeLibraryPath [
      # load external libraries that you need in your rust project here
    ];
in
  pkgs.mkShell rec {
    nativeBuildInputs = with pkgs; [
    ];
    buildInputs = with pkgs; [
      pkg-config
      llvmPackages.bintools
      rustup
      perl
      #udev
      #udev.dev
    ];
    RUSTC_VERSION = overrides.toolchain.channel;
    # https://github.com/rust-lang/rust-bindgen#environment-variables
    LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages_latest.libclang.lib ];
    shellHook = ''
      export PATH=$PATH:''${CARGO_HOME:-~/.cargo}/bin
      export PATH=$PATH:''${RUSTUP_HOME:-~/.rustup}/toolchains/$RUSTC_VERSION-x86_64-unknown-linux-gnu/bin/
      '';
    # Add precompiled library to rustc search path
    RUSTFLAGS = (builtins.map (a: ''-L ${a}/lib'') [
      # add libraries here (e.g. pkgs.libvmi)
    ]);
    NIX_LD = builtins.readFile "${pkgs.stdenv.cc}/nix-support/dynamic-linker";
    #NIX_LD_LIBRARY_PATH = libPath;
    #LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [ pkgs.openssl ];
    # Add glibc, clang, glib, and other headers to bindgen search path
    BINDGEN_EXTRA_CLANG_ARGS =
    # Includes normal include path
    (builtins.map (a: ''-I"${a}/include"'') [
      # add dev libraries here (e.g. pkgs.libvmi.dev)
      pkgs.glibc.dev
    ])
    # Includes with special directory paths
    ++ [
      ''-I"${pkgs.llvmPackages_latest.libclang.lib}/lib/clang/${pkgs.llvmPackages_latest.libclang.version}/include"''
      ''-I"${pkgs.glib.dev}/include/glib-2.0"''
      ''-I${pkgs.glib.out}/lib/glib-2.0/include/''
    ];
  }
SergioGasquez commented 3 months ago

The environment variable should be due to tempfile. perl is listed in the requirements for some distributions, but maybe we could improve the wording there.

Thanks for sharing your process and the working setup! I'll be closing the issue, if any other issue arises, feel free to reopen.