Search code examples
nix

I don't understand why I have " cannot evaluate a function that has an argument without a value ('fetchurl') " when I try to build a package


I try to build a nix package

a.nix :

{ lib
, stdenv
, fetchurl
, testVersion
, hello
}:
stdenv.mkDerivation {
  name = "libfoo-1.2.3";
  src = fetchurl {
    url = "http://example.org/libfoo-1.2.3.tar.bz2";
    sha256 = "0x2g1jqygyr5wiwg4ma1nd7w4ydpy82z9gkcv8vh2v8dn3y58v5m";
  };
}

then I execute this bash command

nix-build a.nix

cannot evaluate a function that has an argument without a value ('fetchurl')

someone proposed me to write this command instead:

nix-build '<nixpkgs>' a.nix

It raised this error

    Please be informed that this pseudo-package is not the only part of
       Nixpkgs that fails to evaluate. You should not evaluate entire Nixpkgs
       without some special measures to handle failing packages, like those taken
       by Hydra.

I'm not that is the solution to the problem, lib was imported without problems.

Does somebody know where this problem comes from?


Solution

  • If you want to be invokable with nix-build and also with pkgs.callPackage, consider specifying default arguments:

    { pkgs ? import <nixpkgs> { system = builtins.currentSystem; }
    , lib ? pkgs.lib
    , stdenv ? pkgs.stdenv
    , fetchurl ? pkgs.fetchurl
    , testVersion ? pkgs.testVersion
    , hello ? pkgs.hello
    }:
    stdenv.mkDerivation {
      name = "libfoo-1.2.3";
      src = fetchurl {
        url = "http://example.org/libfoo-1.2.3.tar.bz2";
        sha256 = "0x2g1jqygyr5wiwg4ma1nd7w4ydpy82z9gkcv8vh2v8dn3y58v5m";
      };
    }
    

    ...but I don't generally advise that. Pick one calling convention or the other, don't do both. (In modern times, a flake is a great way to have a consistent structure for your code with inputs reliably pinned: if you had a flake.nix using pkgs.callPackage to invoke your derivation, that would let users invoke nix build pathToYourFlake#nameOfThePackage to build it -- nix build .# if it's the flake's default package and the current directory is a checkout of your flake).