/nix-matlab

A fork for my own use. Originally from doronbehar/nix-matlab on GitLab

Primary LanguageNix

Matlab for Nix users

Important
Originally from doronbehar/nix-matlab on GitLab.

This repo is a collection of files that should help Nix and NixOS users install Matlab imperatively. The matlab* derivations provided by this repo use Nixpkgs' buildFHSEnv to run any executable provided by matlab in an environment that imitates a system with FHS. Please read the description of buildFHSEnv to understand how it works.

Install

Like any other Matlab user, you should first go to your Matlab account on Mathworks' website, at: https://www.mathworks.com/mwaccount/ and download the installation zip file. Extract the zip file and note the install executable you just extracted. To run that file, you’ll need to get into a FHS environment that a nix-shell will provide.

Run matlab-shell with an unstable Nix

nix run gitlab:doronbehar/nix-matlab#matlab-shell

Run matlab-shell with stable legacy Nix

git clone https://gitlab.com/doronbehar/nix-matlab
cd nix-matlab
nix-shell

Installation of Matlab itself

From inside the FHS shell, follow the following steps:

Important
Due to a not fully understood issue in Matlab, you might experience difficulty openning text files in Matlab’s editor. The symptoms are described here, along with the solution.

Adding matlab executables to your system

With what was done now, you run Matlab from the command line with:

# Legacy nix users (inside a clone of this repo)
$(nix-build)/bin/matlab
# Flake nix users (without cloning)
nix run gitlab:doronbehar/nix-matlab

But it’s likely you’d like to make Matlab’s FHS environment survive garbage collections and add a desktop launcher to your system. To do that you can follow one of the following paths according to your setup.

For NixOS users with a flakes setup

inputs = {
  # ...
  nix-matlab = {
    # nix-matlab's Nixpkgs input follows Nixpkgs' nixos-unstable branch. However
    # your Nixpkgs revision might not follow the same branch. You'd want to
    # match your Nixpkgs and nix-matlab to ensure fontconfig related
    # compatibility.
    inputs.nixpkgs.follows = "nixpkgs";
    url = "gitlab:doronbehar/nix-matlab";
  };
  # ...
  outputs = { self, nixpkgs, nix-matlab }:
  let
    flake-overlays = [
      nix-matlab.overlay
    ];
  in {
    nixosConfigurations = (
      HOSTNAME = nixpkgs.lib.nixosSystem {
        modules = [ (import ./configuration.nix flake-overlays) ]
      };
    };
  };
};

And in ./configuration.nix:

# All overlays given by flakes
flake-overlays:

{ config, pkgs, options, lib, ... }:
{
  nixpkgs.overlays = [
    (
      final: prev: {
        # Your own overlays...
      }
    )
  ] ++ flake-overlays;
  environment.systemPackages = with pkgs; [
    # Other packages
    matlab
    # More packages
  ];
}

Example evaluated here and here.

For NixOS users without a flakes setup

The following setup should also fit flake NixOS users.

Add to your configration.nix (untested, but should work):

  nixpkgs.overlays = let
    nix-matlab = import (builtins.fetchTarball "https://gitlab.com/doronbehar/nix-matlab/-/archive/master/nix-matlab-master.tar.gz");
  in [
    nix-matlab.overlay
    (
      final: prev: {
        # Your own overlays...
      }
    )
  ];
  environment.systemPackages = with pkgs; [
    # Other packages
    matlab
    # More packages
  ];

Home Manager setup

TODO

Usage in Other Flakes / shell.nix

Some people may wish to not install matlab globally, and only making it part of the buildInputs of their project. Usually this paradigm follows along with direnv + shell.nix / flake.nix setup. For example you can create in your project a shell.nix, or define devShell in your flake.nix similarly to this:

{ pkgs, nix-matlab }:

pkgs.mkShell {
  buildInputs = (with nix-matlab.packages.x86_64-linux; [
    matlab
    matlab-mlint
    matlab-mex
  ]);
  # Define C include path env vars for c development
  shellHook = nix-matlab.shellHooksCommon;
}

Note that Matlab still needs to be installed in a user-writeable location for this shellHook to work, as explained here.

Adding packages to matlab’s environment

Another non-trivial example usage of this flake, somewhat similar to the above, is to create a matlab development environment that includes external tools that you want to run from within matlab. The following flake.nix uses nix-matlab as an input flake and adds lammps package to the FHS environment. With this flake, you can run nix develop and run system('lmp') from within matlab’s CLI:

{
  description = "Matlab fhs environment with lammps included, uses gitlab:doronbehar/nix-matlab";

  inputs = {
    # https://gitlab.com/doronbehar/nix-matlab
    nix-matlab = {
      url = "gitlab:doronbehar/nix-matlab";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nixpkgs = {
      url = "github:nixos/nixpkgs/nixos-unstable";
    };
  };

  outputs = { self
  , nixpkgs
  , nix-matlab
  }: let
    pkgs = import nixpkgs {
      system = "x86_64-linux";
    };
  in {
    packages.x86_64-linux = {
      matlab-lammps = pkgs.buildFHSUserEnv {
        name = "matlab-lammps";
        targetPkgs = ps: (nix-matlab.targetPkgs ps ++ [
          pkgs.lammps
        ]);
        runScript = pkgs.writeScript "matlab-lammps" (nix-matlab.shellHooksCommon + ''
          exec $MATLAB_INSTALL_DIR/bin/matlab "$@"
        '');
        meta = {
          description = "MATLAB with lammps included in FHS environment";
        };
      };
      matlab-lammps-shell = pkgs.buildFHSUserEnv {
        name = "matlab-lammps-shell";
        targetPkgs = ps: (nix-matlab.targetPkgs ps ++ [
          pkgs.lammps
        ]);
        runScript = pkgs.writeScript "matlab-lammps" (nix-matlab.shellHooksCommon + ''
          echo matlab is installed in $MATLAB_INSTALL_DIR/bin/matlab
          exec bash
        '');
        meta = {
          description = "MATLAB shell with lammps included in FHS environment";
        };
      };
    };
    devShell.x86_64-linux = pkgs.mkShell {
      buildInputs = [
        self.packages.x86_64-linux.matlab-lammps-shell
      ];
      # From some reason using the attribute matlab-shell directly as the
      # devShell doesn't make it run like that by default.
      shellHook = ''
        exec matlab-lammps-shell
      '';
    };
  };
}

FAQ

Matlab says that my license was installed for a different Host ID, why does it happen?

I haven’t had reports of this issue by users of this repo, but I experience it myself sometimes, and I think it’s a good thing to include in this README. I use Gnome with NetworkManager on my laptop, and rarely I use USB tethering with my Android. From some reason while I’m tethered, I get the following error when I launch matlab from the command line:

The hostid of your computer ("000000000000 111111111111") does not match the hostid of the license
file (XXXXXXXXXXXX).

I get this error although I set in my /etc/nixos/configuration.nix:

networking.hostId = "6b216943" # fake id

As explained in the link in the full error message, I can reactivate the license and not go again through the whole installation procedure. But I will be required to reactivate the license again afterwards when I switch again to WiFi internet connection. It’s somewhat annoying, and I haven’t found a solution / explanation why does my host id changes when I switch to a wired connection.

Previous work / Credits

Core parts of this repo are based on @tviti’s work. My part was making it a bit more accessible for modern Nix flake setup, and making the shell and steps a bit more approachable.

The idea for a shellHooksCommon was by @DavidRConnell, first discussed in !1.