Expression Syntax
Nix expression for GNU Hello
(default.nix)
{ stdenv, fetchurl, perl }: 
stdenv.mkDerivation { 
  name = "hello-2.1.1"; 
  builder = ./builder.sh; 
  src = fetchurl { 
    url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
    sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
  };
  inherit perl; 
}
 shows a Nix expression for GNU
Hello.  It's actually already in the Nix Packages collection in
pkgs/applications/misc/hello/ex-1/default.nix.
It is customary to place each package in a separate directory and call
the single Nix expression in that directory
default.nix.  The file has the following elements
(referenced from the figure by number):
  
    This states that the expression is a
    function that expects to be called with three
    arguments: stdenv, fetchurl,
    and perl.  They are needed to build Hello, but
    we don't know how to build them here; that's why they are function
    arguments.  stdenv is a package that is used
    by almost all Nix Packages packages; it provides a
    standard
 environment consisting of the things you
    would expect in a basic Unix environment: a C/C++ compiler (GCC,
    to be precise), the Bash shell, fundamental Unix tools such as
    cp, grep,
    tar, etc.  fetchurl is a
    function that downloads files.  perl is the
    Perl interpreter.
    Nix functions generally have the form { x, y, ...,
    z }: e where x, y,
    etc. are the names of the expected arguments, and where
    e is the body of the function.  So
    here, the entire remainder of the file is the body of the
    function; when given the required arguments, the body should
    describe how to build an instance of the Hello package.
  
  
    So we have to build a package.  Building something from
    other stuff is called a derivation in Nix (as
    opposed to sources, which are built by humans instead of
    computers).  We perform a derivation by calling
    stdenv.mkDerivation.
    mkDerivation is a function provided by
    stdenv that builds a package from a set of
    attributes.  A set is just a list of
    key/value pairs where each key is a string and each value is an
    arbitrary Nix expression.  They take the general form {
    name1 =
    expr1; ...
    nameN =
    exprN; }.
  
  
    The attribute name specifies the symbolic
    name and version of the package.  Nix doesn't really care about
    these things, but they are used by for instance nix-env
    -q to show a human-readable
 name for
    packages.  This attribute is required by
    mkDerivation.
  
  
    The attribute builder specifies the
    builder.  This attribute can sometimes be omitted, in which case
    mkDerivation will fill in a default builder
    (which does a configure; make; make install, in
    essence).  Hello is sufficiently simple that the default builder
    would suffice, but in this case, we will show an actual builder
    for educational purposes.  The value
    ./builder.sh refers to the shell script shown
    in , discussed below.
  
  
    The builder has to know what the sources of the package
    are.  Here, the attribute src is bound to the
    result of a call to the fetchurl function.
    Given a URL and a SHA-256 hash of the expected contents of the file
    at that URL, this function builds a derivation that downloads the
    file and checks its hash.  So the sources are a dependency that
    like all other dependencies is built before Hello itself is
    built.
    Instead of src any other name could have
    been used, and in fact there can be any number of sources (bound
    to different attributes).  However, src is
    customary, and it's also expected by the default builder (which we
    don't use in this example).
  
  
    Since the derivation requires Perl, we have to pass the
    value of the perl function argument to the
    builder.  All attributes in the set are actually passed as
    environment variables to the builder, so declaring an attribute
    
perl = perl;
    will do the trick: it binds an attribute perl
    to the function argument which also happens to be called
    perl.  However, it looks a bit silly, so there
    is a shorter syntax.  The inherit keyword
    causes the specified attributes to be bound to whatever variables
    with the same name happen to be in scope.