diff --git a/pkgs/applications/science/math/matlab/default.nix b/pkgs/applications/science/math/matlab/default.nix new file mode 100644 index 0000000000000..0953b317f398b --- /dev/null +++ b/pkgs/applications/science/math/matlab/default.nix @@ -0,0 +1,7 @@ +{ callPackage }: + +rec { + fetchFromMPM = callPackage ./fetcher.nix { inherit matlab-package-manager; }; + matlab = callPackage ./matlab.nix { inherit fetchFromMPM matlab-package-manager; }; + matlab-package-manager = callPackage ./mpm.nix { }; +} diff --git a/pkgs/applications/science/math/matlab/fetcher.nix b/pkgs/applications/science/math/matlab/fetcher.nix new file mode 100644 index 0000000000000..bb035246decf8 --- /dev/null +++ b/pkgs/applications/science/math/matlab/fetcher.nix @@ -0,0 +1,47 @@ +{ + lib, + stdenvNoCC, + matlab-package-manager, +}: + +{ + release, + update ? 0, + # The full list of correctly formatted product names can be found within the template input files + # https://github.com/mathworks-ref-arch/matlab-dockerfile/tree/main/mpm-input-files + extra-products ? [ ], + hash, +}: + +let + version = "${release}U${toString update}"; + products = [ "MATLAB" ] ++ extra-products; +in +stdenvNoCC.mkDerivation { + pname = "matlab-download"; + inherit products version; + + __structuredAttrs = true; + + dontUnpack = true; + + installPhase = '' + # As mpm is bubblewrapped, it cannot write to $out directly + # https://github.com/NixOS/nixpkgs/issues/239017 + ${lib.getExe matlab-package-manager} download --release "$version" --platforms glnxa64 --destination matlab --products "''${products[@]}" + mv matlab $out + ''; + + dontFixup = true; + + # The MATLAB installation isn't 100% deterministic due to how the classpath.txt file is generated. + # But mpm download does appear to be deterministic. So create a fixed output derivation from the + # downloaded files, and then run the installer. + outputHashAlgo = if hash == "" then "sha256" else null; + outputHashMode = "recursive"; + outputHash = hash; + + passthru.matlab-download = { + inherit products release update; + }; +} diff --git a/pkgs/applications/science/math/matlab/matlab.nix b/pkgs/applications/science/math/matlab/matlab.nix new file mode 100644 index 0000000000000..380ef7b1168ef --- /dev/null +++ b/pkgs/applications/science/math/matlab/matlab.nix @@ -0,0 +1,222 @@ +{ + lib, + stdenvNoCC, + buildFHSEnv, + copyDesktopItems, + libarchive, + makeDesktopItem, + writeShellScriptBin, + + fetchFromMPM, + matlab-package-manager, +}: + +stdenvNoCC.mkDerivation (self: { + pname = "matlab"; + inherit (self.src) version; + products = self.src.matlab-download.products or [ "MATLAB" ]; + + matlabBins = [ + "matlab" + "mex" + ]; + + dontUnpack = true; + dontConfigure = true; + dontBuild = true; + + src = fetchFromMPM { + release = "R2024b"; + update = 1; + extra-products = [ ]; + hash = "sha256-t7+vIk7254mo7dUaRFjZp/qHRpVWnIhy3OEoZfhwqUI="; + }; + + nativeBuildInputs = [ copyDesktopItems ]; + + unwrapped = + let + unpack = + if self.src ? "matlab-download" then + # Downloaded using fetchFromMPM: already unpacked + { dontUnpack = true; } + else + # Assume this is an ISO image from requireFile: need to unpack + { + nativeBuildInputs = [ libarchive ]; + unpackCmd = "bsdtar -vxf $curSrc"; + sourceRoot = "."; + }; + in + stdenvNoCC.mkDerivation ( + { + pname = "matlab-unwrapped"; + inherit (self) src products version; + + __structuredAttrs = true; + + dontConfigure = true; + dontBuild = true; + dontFixup = true; + + installPhase = '' + # As mpm is bubblewrapped, it cannot write to $out directly + # https://github.com/NixOS/nixpkgs/issues/239017 + ${lib.getExe matlab-package-manager} install --source "$src" --destination matlab --products "''${products[@]}" + mv matlab $out + ln -s /etc/matlab $out/licenses + ''; + } + // unpack + ); + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin $out/share/applications $out/share/pixmaps + + ln -s ${self.env}/bin/matlab-env $out/bin/matlab-env + + ${ + let + launcherFor = + name: + writeShellScriptBin name '' + exec ${self.env}/bin/matlab-env ${self.unwrapped}/bin/${name} "''${@}" + ''; + in + lib.concatMapStringsSep "\n" (name: '' + if [ ! -f ${self.unwrapped}/bin/${name} ]; then + echo "MATLAB binary ${name} does not exist!" + exit 1 + fi + ln -sv ${lib.getExe (launcherFor name)} $out/bin/${name} + '') self.matlabBins + } + + ln -s ${self.unwrapped}/bin/glnxa64/cef_resources/matlab_icon.png $out/share/pixmaps/matlab.png + + runHook postInstall + ''; + + desktopItems = [ + (makeDesktopItem { + name = "matlab"; + exec = "matlab -desktop -useStartupFolderPref %F"; + comment = "MATLAB is a programming and numeric computing platform for engineering and scientific applications."; + desktopName = "MATLAB ${self.matlab-download.release or self.version}"; + icon = "matlab"; + categories = [ + "Development" + "Math" + "Science" + ]; + mimeTypes = [ + "text/x-matlab" + "text/x-octave" + ]; + }) + ]; + + env = buildFHSEnv { + name = "matlab-env"; + + extraPreBwrapCmds = '' + mkdir -p $HOME/.matlab/licenses + + # For some reason, MATLAB often fails to start unless this directory is cleared. + rm -rf ~/.MathWorks/ServiceHost/ + ''; + + extraBwrapArgs = [ + "--bind $HOME/.matlab/licenses /etc/matlab" + ]; + + targetPkgs = + pkgs: + builtins.attrValues { + # From https://gitlab.com/doronbehar/nix-matlab/-/blob/master/common.nix + inherit (pkgs) + alsa-lib + atk + at-spi2-atk + at-spi2-core + cacert + cairo + cups + dbus + fontconfig + gcc + gdk-pixbuf + gfortran + git + glib + glibc + glibcLocales + gtk2 + gtk3 + jre + libdrm + libglvnd + libselinux + libsndfile + libuuid + libxcrypt + libxcrypt-legacy + libxkbcommon + mesa + ncurses + nspr + nss + pam + pango + procps + python3 + udev + unzip + xkeyboard_config + zlib + ; + + inherit (pkgs.gst_all_1) + gst-plugins-base + gstreamer + ; + + inherit (pkgs.mesa) + drivers + ; + + inherit (pkgs.xorg) + libSM + libX11 + libXcomposite + libXcursor + libXdamage + libXext + libXfixes + libXft + libXi + libXinerama + libXrandr + libXrender + libXt + libXtst + libXxf86vm + libxcb + ; + }; + }; + + passthru.unwrapped = self.unwrapped; + + meta = { + mainProgram = "matlab"; + description = "MATLAB is a programming and numeric computing platform for engineering and scientific applications."; + homepage = "https://www.mathworks.com/products/matlab.html"; + platforms = [ "x86_64-linux" ]; + sourceProvenance = [ lib.sourceTypes.binaryNativeCode ]; + license = lib.licenses.unfree; + maintainers = with lib.maintainers; [ james-atkins ]; + }; +}) diff --git a/pkgs/applications/science/math/matlab/mpm.nix b/pkgs/applications/science/math/matlab/mpm.nix new file mode 100644 index 0000000000000..a43e12ab1a5b1 --- /dev/null +++ b/pkgs/applications/science/math/matlab/mpm.nix @@ -0,0 +1,51 @@ +{ + lib, + stdenvNoCC, + fetchurl, + buildFHSEnv, +}: + +let + pname = "mpm"; + version = "2024.3"; + + mpm-bin = stdenvNoCC.mkDerivation { + inherit pname version; + + src = fetchurl { + # https://www.mathworks.com/mpm/glnxa64/mpm redirects to here + url = "https://ssd.mathworks.com/supportfiles/downloads/mpm/${version}/glnxa64/mpm"; + hash = "sha256-xDL6Xx/fQeqQMEMDv0+s6TSIjEdZO6yMYMhnAXU9JQ8="; + executable = true; + }; + dontUnpack = true; + + installPhase = '' + runHook preInstall + mkdir -p $out/bin + cp $src $out/bin/mpm + runHook postInstall + ''; + }; +in +buildFHSEnv { + inherit pname version; + runScript = "mpm"; + + targetPkgs = + pkgs: with pkgs; [ + mpm-bin + pam + zlib + ]; + + meta = { + mainProgram = "mpm"; + description = "MATLAB Package Manager"; + homepage = "https://www.mathworks.com/help/install/ug/get-mpm-os-command-line.html"; + platforms = [ "x86_64-linux" ]; + sourceProvenance = [ lib.sourceTypes.binaryNativeCode ]; + license = lib.licenses.unfree; + maintainers = with lib.maintainers; [ james-atkins ]; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 1c0742d4aed50..27b81e1998285 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -17794,6 +17794,11 @@ with pkgs; geogebra = callPackage ../applications/science/math/geogebra { }; geogebra6 = callPackage ../applications/science/math/geogebra/geogebra6.nix { }; + inherit (callPackage ../applications/science/math/matlab { }) + fetchFromMPM + matlab + matlab-package-manager; + maxima = callPackage ../applications/science/math/maxima { lisp-compiler = sbcl; };