Nix Shell - Conditionally Include Package depending on Host Platform

I have a nix flake for my flutter environment, and just yesterday I installed nix onto a macbook, pulled in the flake and it worked!! I noticed though that I was missing cocoapods, deps manager on iOS, so I added that to my flake. Now, back on my linux machine, I am getting an error saying cocoapods isnt supported on linux, which makes sense, nor would I ever need it installed here as I can’t do iOS dev on this machine. So, my question is, how do you optionally include this package in the nix flake shell depending on the hostPlatform? Is it something with flake-utils (I poked around in the nix repl but couldn’t figure anything out…)? Sorry if this has been asked already, but I could not find this online anywhere. If you do, please just point me there and save the time writing anything up. Thanks in advance!!

My flake:

{
  description = "An example project using flutter";

  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.android-nixpkgs.url = "github:tadfisher/android-nixpkgs";

  outputs = {
    self,
    flake-utils,
    nixpkgs,
    ...
  } @ inputs:
    flake-utils.lib.eachDefaultSystem (system: let
      pkgs = import nixpkgs {
        inherit system;
      };
    in {
      devShell = let
        android-nixpkgs = pkgs.callPackage inputs.android-nixpkgs {};
        android-sdk = android-nixpkgs.sdk (sdkPkgs:
          with sdkPkgs; [
            cmdline-tools-latest
            build-tools-30-0-3
            # This version needs to match the GRADLE_OPTS env var down below, vice versa
            build-tools-34-0-0
            platform-tools
            platforms-android-28
            platforms-android-29
            platforms-android-31
            platforms-android-33
            platforms-android-34
            emulator
          ]);
        # See below link for configuring ruby env with bundix
        # https://github.com/the-nix-way/nix-flake-dev-environments/tree/main/ruby-on-rails
        rubyEnv = pkgs.bundlerEnv {
          name = "ruby-env";
          inherit (pkgs) ruby;
          gemdir = ./android;
        };

      in 
        pkgs.mkShell {
          GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${android-sdk}/share/android-sdk/build-tools/34.0.0/aapt2";
          FLUTTER_ROOT = "${pkgs.flutter}";
          buildInputs = with pkgs; [
            flutter
            # pkg-config
            jdk17
            android-sdk
            rubyEnv
            rubyEnv.wrappedRuby
            # fastlane
            bundix
            # gems
            firebase-tools
            # nodejs
            cocoapods
          ];
          shellHook = ''
            export PATH="$PATH":"$HOME/.pub-cache/bin" 
          '';
        };
    });
}

This doesn’t work, but I tried some variations of checking the hostPlatform in the buildInputs with a lib.list.flatten (I use this in my nixOS config in some spots):

...
          buildInputs = with pkgs; lib.list.flatten [[
            flutter
            # pkg-config
            jdk17
            android-sdk
            rubyEnv
            rubyEnv.wrappedRuby
            # fastlane
            bundix
            # gems
            firebase-tools
            # nodejs
          ]
          lib.mkIf (pkgs.stdenv.hostPlatform == "darwin") [
            cocoapods
          ]];
...

To poke around, copy the full flake above to a file, then open a repl with nix --extra-experimental-features repl-flake repl . and then :lf . loads up the flake locally. At least this is what I was doing to try and figure this out…

Use the lib.optionals function, along with the pkgs.stdenv.isLinux or pkgs.stdenv.isDarwin.

buildInputs = [ ... ]
  ++ (pkgs.lib.optionals pkgs.stdenv.isLinux [ ... ])
  ++ (pkgs.lib.optionals pkgs.stdenv.isDarwin [ ... ]);

optionals returns an empty list when the argument is false, or the given list when true.

(EDIT: use pkgs.stdenv.isLinux instead of the non-existent pkgs.isLinux).

1 Like

I tried adding the lib.optionals but I’m getting an error saying the pkgs.isLinux attribute is missing:

       error: attribute 'isLinux' missing

       at /nix/store/jh8kivhm3jpxbyl4kisy70d72rypslw6-source/flake.nix:78:34:

           77|           ]
           78|           ++ (pkgs.lib.optionals pkgs.isLinux []);
             |                                  ^
           79|           ++ (pkgs.lib.optionals pkgs.isDarwin [ cocoapods ]);

I’m not sure why I thought it was pkgs.isLinux.

Try pkgs.stdenv.isLinux instead.

$ nix eval --impure --expr '(import <nixpkgs> {}).stdenv.isLinux'
true
1 Like

That’s it! Thanks, haha I was so close pkgs.stdenv.isLinux not pkgs.stdenv.platform