Using tarballs in flakes

Hello all, I am trying to package blender using the flakes paradigm as a learning exercise and cant figure out what I am doing wrong.

Could someone tell me how can we point to a tarball archive and use it as a source when using flakes? So far I have not been successful in making this work. It keeps complaining about cmake not finding CMakeLists.txt in the source.

I suspect the when using the fetchtarball with the flake, after the unpack, there is no directory named source but blender-3.3.1 and so cmake is not happy with it?

Following are the 2 latest attempts I have made.


{
  description = "Nix flake to providing blender application and its components.";

  inputs = {
    nixpkgs.url = github:NixOS/nixpkgs?ref=release-22.05;

    blender_tarball.url = "https://github.com/blender/blender/archive/refs/tags/v3.3.1.tar.gz";
    blender_tarball.flake = false;
  };

  outputs = {self, nixpkgs, blender_tarball}: {

    defaultPackage.x86_64-linux =
    with import nixpkgs { system = "x86_64-linux"; };
    stdenv.mkDerivation rec {
      name = "blender";
      version = "3.3.1";
      unpackPhase = ":";

      ## Can I do this and add the unpacked content to the source?
      # blender_src_tarball = fetchTarball {
      #   url = "https://github.com/blender/blender/archive/refs/tags/v3.3.1.tar.gz";
      #   sha256 = "0qrx41hmw7f85mkvjyvcv8badbrsmmfif632iinjdxc19kg46nib";
      # };
      # src = [self blender_src_tarball];

      src = blender_tarball;

      postPatch = ''
        tar -xvzf v3.3.1.tar.gz --strip-components=1
      '';

      python_with_packages = python310.withPackages(ps: with ps; [numpy requests zstandard]);
      nativeBuildInputs = [cmake python_with_packages pkg-config];
    };
  };
}

{
  description = "Nix flake to providing blender application and its components.";

  inputs = {
    nixpkgs.url = github:NixOS/nixpkgs?ref=release-22.05;

    blender_tarball.url = "https://github.com/blender/blender/archive/refs/tags/v3.3.1.tar.gz";
    blender_tarball.flake = false;
  };

  outputs = {self, nixpkgs, blender_tarball}: {
  # outputs = {self, nixpkgs}: {

    defaultPackage.x86_64-linux =
    with import nixpkgs { system = "x86_64-linux"; };
    stdenv.mkDerivation rec {
      name = "blender";
      version = "3.3.1";

      src = self;

      python_with_packages = python310.withPackages(ps: with ps; [numpy requests zstandard]);
      nativeBuildInputs = [cmake python_with_packages pkg-config];
    };

Following is the error I get:

CMake Error: The source directory “/tmp/nix-build-blender.drv-0/source” does not appear to contain CMakeLists.txt.

Any help would be hugely appreciated! :smiley:

1 Like

That’s how you do it. Or slightly better:

src = fetchFromGithub {
  owner = "blender";
  repo = "blender";
  rev = "v3.3.1";
  sha256 = "0qrx41hmw7f85mkvjyvcv8badbrsmmfif632iinjdxc19kg46nib";
};

No need for the array if there’s only one source, and usually the src is just defined inline like that.

Flake inputs are supposed to give you access to already built packages, nixos modules, library functions and things like that. Packages should still use fetch.* for their sources.

I don’t know if this will fix that error though.


Also, I can’t help myself but critique:

There are two problems with this expression:

  1. import nixpkgs {...}; in a flake is unoptimal. Flakes have an “evaluation cache” that caches the evaluation of the outputs of your inputs. If you use import nixpkgs instead of using that mechanism you just evaluate nixpkgs from scratch. Unless you have a really good reason to (usually involving overlays), just use the actual output - nixpkgs.legacyPackages.x86_64-linux - instead.
  2. with is an anti-pattern, and doing it on something this broad with this large of a scope is a sin I can’t overlook. nix.dev has a nice explanation: In the Nix language — nix.dev documentation
  • with pkgs; [ <a bunch of package names> ]; is less bad because it’s pretty clear IMO, and currently there’s no good alternative, but we’ll have better syntax for that soon too.

Also that rec is an anti-pattern: In the Nix language — nix.dev documentation

defaultPackage is deprecrated, use packages.default instead.

Finally, and this is a nit, you probably want to define python_with_packages in a let block outside the scope instead of using rec. No reason to have that as a variable in the build env.


In one code block:

packages.x86_64-linux.default = let
  pkgs = nixpkgs.legacyPackages.x86_64-linux;
  python_with_packages = pkgs.python310.withPackages (ps: with ps; [
    numpy
    requests
    zstandard
  ]);
in pkgs.stdenv.mkDerivation {
  name = "blender";
  version = "3.3.1";

  src = pkgs.fetchFromGithub {
    owner = "blender";
    repo = "blender";
    rev = "v3.3.1";
    sha256 = "0qrx41hmw7f85mkvjyvcv8badbrsmmfif632iinjdxc19kg46nib";
  };

  nativeBuildInputs = with pkgs; [
    cmake
    pkg-config
  ] ++ [python_with_packages];
};

Ok, much nicer. Sorry, I’ve grown quite opinionated about nix over the years. Normally I’d also tell you to factor this out into a separate file and use pkgs.callPackage, but I’ll leave it at this for today :slight_smile:

1 Like

You just needed src = _tarball;

The first attempt in the OP actually nearly works. If you just remove the unpackPhase and the postPatch parts, it proceeds to the build (and fails on something else entirely).

1 Like

Thank you @TLATER , @Growpotkin @ElvishJerricco !

Yes, I got it working by simply binding the blender_src_tarball to src but was quite late at night :sweat_smile: so didnt update.

I am very new to NixOS and am evaluating Nix to see if I can use it for packaging various applications I need internally for a project I am preparing for. After having to package few debian packages, I decided to not go that route.

Nix feels really good as it has support for various languages but also gives me ability to generate Debian packages (if needed) using same nix expressions / flakes.

I am really thankful for you pointers @TLATER . I am still learning the ropes :smiley: