diff options
11 files changed, 646 insertions, 99 deletions
diff --git a/pkgs/development/interpreters/octave/build-env.nix b/pkgs/development/interpreters/octave/build-env.nix new file mode 100644 index 0000000000000..8eb70c6289457 --- /dev/null +++ b/pkgs/development/interpreters/octave/build-env.nix @@ -0,0 +1,83 @@ +{ stdenv, octave, buildEnv +, makeWrapper, texinfo +, octavePackages +, wrapOctave +, computeRequiredOctavePackages +, extraLibs ? [] +, extraOutputsToInstall ? [] +, postBuild ? "" +, ignoreCollisions ? false +}: + +# Create an octave executable that knows about additional packages +let + packages = computeRequiredOctavePackages extraLibs; + +in buildEnv { + name = "${octave.name}-env"; + paths = extraLibs ++ [ octave ]; + + inherit ignoreCollisions; + extraOutputsToInstall = [ "out" ] ++ extraOutputsToInstall; + + buildInputs = [ makeWrapper texinfo wrapOctave ]; + + # During "build" we must first unlink the /share symlink to octave's /share + # Then, we can re-symlink the all of octave/share, except for /share/octave + # in env/share/octave, re-symlink everything from octave/share/octave and then + # perform the pkg install. + postBuild = '' + . "${makeWrapper}/nix-support/setup-hook" + # The `makeWrapper` used here is the one defined in + # ${makeWrapper}/nix-support/setup-hook + + if [ -L "$out/bin" ]; then + unlink $out/bin + mkdir -p "$out/bin" + cd "${octave}/bin" + for prg in *; do + if [ -x $prg ]; then + makeWrapper "${octave}/bin/$prg" "$out/bin/$prg" --set OCTAVE_SITE_INITFILE "$out/share/octave/site/m/startup/octaverc" + fi + done + cd $out + fi + + # Remove symlinks to the input tarballs, they aren't needed. + rm $out/*.tar.gz + + createOctavePackagesPath $out ${octave} + + for path in ${stdenv.lib.concatStringsSep " " packages}; do + if [ -e $path/*.tar.gz ]; then + $out/bin/octave-cli --eval "pkg local_list $out/.octave_packages; \ + pkg prefix $out/${octave.octPkgsPath} $out/${octave.octPkgsPath}; \ + pfx = pkg (\"prefix\"); \ + pkg install -nodeps -local $path/*.tar.gz" + fi + done + + # Re-write the octave-wide startup file (share/octave/site/m/startup/octaverc) + # To point to the new local_list in $out + addPkgLocalList $out ${octave} + + wrapOctavePrograms "${stdenv.lib.concatStringsSep " " packages}" + '' + postBuild; + + inherit (octave) meta; + + passthru = octave.passthru // { + interpreter = "$out/bin/octave"; + inherit octave; + env = stdenv.mkDerivation { + name = "interactive-${octave.name}-environment"; + + buildCommand = '' + echo >&2 "" + echo >&2 "*** octave 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" + echo >&2 "" + exit 1 + ''; + }; + }; +} diff --git a/pkgs/development/interpreters/octave/build-octave-package.nix b/pkgs/development/interpreters/octave/build-octave-package.nix new file mode 100644 index 0000000000000..73a67769d6a6e --- /dev/null +++ b/pkgs/development/interpreters/octave/build-octave-package.nix @@ -0,0 +1,113 @@ +# Generic builder for GNU Octave libraries. +# This is a file that contains nested functions. The first, outer, function +# is the library- and package-wide details, such as the nixpkgs library, any +# additional configuration provided, and the namePrefix to use (based on the +# pname and version of Octave), the octave package, etc. + +{ lib +, stdenv +, config +, octave +, texinfo +, computeRequiredOctavePackages +, writeRequiredOctavePackagesHook +}: + +# The inner function contains information required to build the individual +# libraries. +{ fullLibName ? "${attrs.pname}-${attrs.version}" + +, src + +, dontPatch ? false +, patches ? [] +, patchPhase ? "" + +, enableParallelBuilding ? true +# Build-time dependencies for the package, which were compiled for the system compiling this. +, nativeBuildInputs ? [] + +# Build-time dependencies for the package, which may not have been compiled for the system compiling this. +, buildInputs ? [] + +# Propagate build dependencies so in case we have A -> B -> C, +# C can import package A propagated by B +# Run-time dependencies for the package. +, propagatedBuildInputs ? [] + +# Octave packages that are required at runtime for this one. +# These behave similarly to propagatedBuildInputs, where if +# package A is needed by B, and C needs B, then C also requires A. +# The main difference between these and propagatedBuildInputs is +# during the package's installation into octave, where all +# requiredOctavePackages are ALSO installed into octave. +, requiredOctavePackages ? [] + +, preBuild ? "" + +, meta ? {} + +, passthru ? {} + +, ... } @ attrs: + +let + requiredOctavePackages' = computeRequiredOctavePackages requiredOctavePackages; + +in stdenv.mkDerivation { + packageName = "${fullLibName}"; + # The name of the octave package ends up being + # "octave-version-package-version" + name = "${octave.pname}-${octave.version}-${fullLibName}"; + + # This states that any package built with the function that this returns + # will be an octave package. This is used for ensuring other octave + # packages are installed into octave during the environment building phase. + isOctavePackage = true; + + OCTAVE_HISTFILE = "/dev/null"; + + inherit src; + + inherit dontPatch patches patchPhase; + + dontConfigure = true; + + enableParallelBuilding = enableParallelBuilding; + + requiredOctavePackages = requiredOctavePackages'; + + nativeBuildInputs = [ + octave + writeRequiredOctavePackagesHook + ] + ++ nativeBuildInputs; + + buildInputs = buildInputs ++ requiredOctavePackages'; + + propagatedBuildInputs = propagatedBuildInputs ++ [ texinfo ]; + + preBuild = if preBuild == "" then + '' + # This trickery is needed because Octave expects a single directory inside + # at the top-most level of the tarball. + tar --transform 's,^,${fullLibName}/,' -cz * -f ${fullLibName}.tar.gz + '' + else + preBuild; + + buildPhase = '' + runHook preBuild + + mkdir -p $out + octave-cli --eval "pkg build $out ${fullLibName}.tar.gz" + + runHook postBuild + ''; + + # We don't install here, because that's handled when we build the environment + # together with Octave. + dontInstall = true; + + inherit meta; +} diff --git a/pkgs/development/interpreters/octave/default.nix b/pkgs/development/interpreters/octave/default.nix index 72f3dd552de6d..0a87c1ddcf07f 100644 --- a/pkgs/development/interpreters/octave/default.nix +++ b/pkgs/development/interpreters/octave/default.nix @@ -1,4 +1,5 @@ { stdenv +, pkgs , lib # Note: either stdenv.mkDerivation or, for octaveFull, the qt-5 mkDerivation # with wrapQtAppsHook (comes from libsForQt5.callPackage) @@ -45,6 +46,11 @@ , python ? null , overridePlatforms ? null , sundials ? null +# - Packages required for building extra packages. +, newScope +, callPackage +, makeSetupHook +, makeWrapper # - Build Octave Qt GUI: , enableQt ? false , qtbase ? null @@ -60,6 +66,7 @@ }: let + # Not always evaluated blas' = if use64BitIdx then blas.override { @@ -94,118 +101,144 @@ let else null ; -in mkDerivation rec { - version = "6.2.0"; - pname = "octave"; - src = fetchurl { - url = "mirror://gnu/octave/${pname}-${version}.tar.gz"; - sha256 = "sha256-RX0f2oY0qDni/Xz8VbmL1W82tq5z0xu530Pd4wEsqnw="; + octavePackages = import ../../../top-level/octave-packages.nix { + inherit pkgs; + inherit lib stdenv fetchurl newScope; + octave = self; }; - buildInputs = [ - readline - ncurses - perl - flex - qhull - graphicsmagick - pcre - fltk - zlib - curl - blas' - lapack' - libsndfile - fftw - fftwSinglePrec - portaudio - qrupdate' - arpack' - libwebp - gl2ps - ] - ++ lib.optionals enableQt [ - qtbase - qtsvg - qscintilla - ] - ++ lib.optionals (ghostscript != null) [ ghostscript ] - ++ lib.optionals (hdf5 != null) [ hdf5 ] - ++ lib.optionals (glpk != null) [ glpk ] - ++ lib.optionals (suitesparse != null) [ suitesparse' ] - ++ lib.optionals (enableJava) [ jdk ] - ++ lib.optionals (sundials != null) [ sundials ] - ++ lib.optionals (gnuplot != null) [ gnuplot ] - ++ lib.optionals (python != null) [ python ] - ++ lib.optionals (!stdenv.isDarwin) [ libGL libGLU libX11 ] - ++ lib.optionals stdenv.isDarwin [ - libiconv - darwin.apple_sdk.frameworks.Accelerate - darwin.apple_sdk.frameworks.Cocoa - ] - ; - nativeBuildInputs = [ - pkg-config - gfortran - # Listed here as well because it's outputs are split - fftw - fftwSinglePrec - texinfo - ] - ++ lib.optionals (sundials != null) [ sundials ] - ++ lib.optionals enableJIT [ llvm ] - ++ lib.optionals enableQt [ - qtscript - qttools - ] - ; + wrapOctave = callPackage ./wrap-octave.nix { + octave = self; + inherit (pkgs) makeSetupHook makeWrapper; + }; + + self = mkDerivation rec { + version = "6.2.0"; + pname = "octave"; + + src = fetchurl { + url = "mirror://gnu/octave/${pname}-${version}.tar.gz"; + sha256 = "sha256-RX0f2oY0qDni/Xz8VbmL1W82tq5z0xu530Pd4wEsqnw="; + }; + + buildInputs = [ + readline + ncurses + perl + flex + qhull + graphicsmagick + pcre + fltk + zlib + curl + blas' + lapack' + libsndfile + fftw + fftwSinglePrec + portaudio + qrupdate' + arpack' + libwebp + gl2ps + ] + ++ lib.optionals enableQt [ + qtbase + qtsvg + qscintilla + ] + ++ lib.optionals (ghostscript != null) [ ghostscript ] + ++ lib.optionals (hdf5 != null) [ hdf5 ] + ++ lib.optionals (glpk != null) [ glpk ] + ++ lib.optionals (suitesparse != null) [ suitesparse' ] + ++ lib.optionals (enableJava) [ jdk ] + ++ lib.optionals (sundials != null) [ sundials ] + ++ lib.optionals (gnuplot != null) [ gnuplot ] + ++ lib.optionals (python != null) [ python ] + ++ lib.optionals (!stdenv.isDarwin) [ libGL libGLU libX11 ] + ++ lib.optionals stdenv.isDarwin [ + libiconv + darwin.apple_sdk.frameworks.Accelerate + darwin.apple_sdk.frameworks.Cocoa + ] + ; + nativeBuildInputs = [ + pkg-config + gfortran + # Listed here as well because it's outputs are split + fftw + fftwSinglePrec + texinfo + ] + ++ lib.optionals (sundials != null) [ sundials ] + ++ lib.optionals enableJIT [ llvm ] + ++ lib.optionals enableQt [ + qtscript + qttools + ] + ; - doCheck = !stdenv.isDarwin; + doCheck = !stdenv.isDarwin; - enableParallelBuilding = true; + enableParallelBuilding = true; - # See https://savannah.gnu.org/bugs/?50339 - F77_INTEGER_8_FLAG = if use64BitIdx then "-fdefault-integer-8" else ""; + # See https://savannah.gnu.org/bugs/?50339 + F77_INTEGER_8_FLAG = if use64BitIdx then "-fdefault-integer-8" else ""; - configureFlags = [ - "--with-blas=blas" - "--with-lapack=lapack" - (if use64BitIdx then "--enable-64" else "--disable-64") - ] + configureFlags = [ + "--with-blas=blas" + "--with-lapack=lapack" + (if use64BitIdx then "--enable-64" else "--disable-64") + ] ++ lib.optionals stdenv.isDarwin [ "--enable-link-all-dependencies" ] ++ lib.optionals enableReadline [ "--enable-readline" ] ++ lib.optionals stdenv.isDarwin [ "--with-x=no" ] ++ lib.optionals enableQt [ "--with-qt=5" ] ++ lib.optionals enableJIT [ "--enable-jit" ] - ; + ; - # Keep a copy of the octave tests detailed results in the output - # derivation, because someone may care - postInstall = '' - cp test/fntests.log $out/share/octave/${pname}-${version}-fntests.log || true - ''; + # Keep a copy of the octave tests detailed results in the output + # derivation, because someone may care + postInstall = '' + cp test/fntests.log $out/share/octave/${pname}-${version}-fntests.log || true + ''; - passthru = { - sitePath = "share/octave/${version}/site"; - blas = blas'; - lapack = lapack'; - qrupdate = qrupdate'; - arpack = arpack'; - suitesparse = suitesparse'; - inherit python; - inherit enableQt enableJIT enableReadline enableJava; - }; + passthru = rec { + sitePath = "share/octave/${version}/site"; + octPkgsPath = "share/octave/octave_packages"; + blas = blas'; + lapack = lapack'; + qrupdate = qrupdate'; + arpack = arpack'; + suitesparse = suitesparse'; + inherit fftw fftwSinglePrec; + inherit portaudio; + inherit jdk; + inherit python; + inherit enableQt enableJIT enableReadline enableJava; + buildEnv = callPackage ./build-env.nix { + octave = self; + inherit octavePackages wrapOctave; + inherit (octavePackages) computeRequiredOctavePackages; + }; + withPackages = import ./with-packages.nix { inherit buildEnv octavePackages; }; + pkgs = octavePackages; + interpreter = "${self}/bin/octave"; + }; - meta = { - homepage = "https://www.gnu.org/software/octave/"; - license = lib.licenses.gpl3Plus; - maintainers = with lib.maintainers; [ raskin doronbehar ]; - description = "Scientific Pragramming Language"; - # https://savannah.gnu.org/bugs/?func=detailitem&item_id=56425 is the best attempt to fix JIT - broken = enableJIT; - platforms = if overridePlatforms == null then - (lib.platforms.linux ++ lib.platforms.darwin) - else overridePlatforms; + meta = { + homepage = "https://www.gnu.org/software/octave/"; + license = lib.licenses.gpl3Plus; + maintainers = with lib.maintainers; [ raskin doronbehar ]; + description = "Scientific Pragramming Language"; + # https://savannah.gnu.org/bugs/?func=detailitem&item_id=56425 is the best attempt to fix JIT + broken = enableJIT; + platforms = if overridePlatforms == null then + (lib.platforms.linux ++ lib.platforms.darwin) + else overridePlatforms; + }; }; -} + +in self diff --git a/pkgs/development/interpreters/octave/hooks/default.nix b/pkgs/development/interpreters/octave/hooks/default.nix new file mode 100644 index 0000000000000..f47560921af3c --- /dev/null +++ b/pkgs/development/interpreters/octave/hooks/default.nix @@ -0,0 +1,13 @@ +# Hooks for building Octave packages. +{ octave +, lib +, callPackage +, makeSetupHook +}: + +rec { + writeRequiredOctavePackagesHook = callPackage ({ }: + makeSetupHook { + name = "write-required-octave-packages-hook"; + } ./write-required-octave-packages-hook.sh) {}; +} diff --git a/pkgs/development/interpreters/octave/hooks/octave-write-required-octave-packages-hook.sh b/pkgs/development/interpreters/octave/hooks/octave-write-required-octave-packages-hook.sh new file mode 100644 index 0000000000000..64e87d68246f1 --- /dev/null +++ b/pkgs/development/interpreters/octave/hooks/octave-write-required-octave-packages-hook.sh @@ -0,0 +1,17 @@ +# Setup hook for writing octave packages that are run-time dependencies for +# another package to a nix-support file. +# `echo`s the full path name to the package derivation that is required. +echo "Sourcing octave-write-required-octave-packages-hook.sh" + +octaveWriteRequiredOctavePackagesPhase() { + echo "Executing octaveWriteRequiredOctavePackagesPhase" + + mkdir -p $out/nix-support + echo ${requiredOctavePackages} > $out/nix-support/required-octave-packages +} + +# Yes its a bit long... +if [ -z "${dontWriteRequiredOctavePackagesPhase-}" ]; then + echo "Using octaveWriteRequiredOctavePackagesPhase" + preDistPhases+=" octaveWriteRequiredOctavePackagesPhase" +fi diff --git a/pkgs/development/interpreters/octave/hooks/write-required-octave-packages-hook.sh b/pkgs/development/interpreters/octave/hooks/write-required-octave-packages-hook.sh new file mode 100644 index 0000000000000..032ea398ac568 --- /dev/null +++ b/pkgs/development/interpreters/octave/hooks/write-required-octave-packages-hook.sh @@ -0,0 +1,17 @@ +# Setup hook for writing octave packages that are run-time dependencies for +# another package to a nix-support file. +# `echo`s the full path name to the package derivation that is required. +echo "Sourcing write-required-octave-packages-hook.sh" + +writeRequiredOctavePackagesPhase() { + echo "Executing writeRequiredOctavePackagesPhase" + + mkdir -p $out/nix-support + echo ${requiredOctavePackages} > $out/nix-support/required-octave-packages +} + +# Yes its a bit long... +if [ -z "${dontWriteRequiredOctavePackagesPhase-}" ]; then + echo "Using writeRequiredOctavePackagesPhase" + preDistPhases+=" writeRequiredOctavePackagesPhase" +fi diff --git a/pkgs/development/interpreters/octave/with-packages.nix b/pkgs/development/interpreters/octave/with-packages.nix new file mode 100644 index 0000000000000..f00befbb00d45 --- /dev/null +++ b/pkgs/development/interpreters/octave/with-packages.nix @@ -0,0 +1,6 @@ +{ buildEnv, octavePackages }: + +# Takes the buildEnv defined for Octave and the set of octavePackages, and returns +# a function, which when given a function whose return value is a list of extra +# packages to install, builds and returns that environment. +f: let packages = f octavePackages; in buildEnv.override { extraLibs = packages; } diff --git a/pkgs/development/interpreters/octave/wrap-octave.nix b/pkgs/development/interpreters/octave/wrap-octave.nix new file mode 100644 index 0000000000000..1e4616136a1b9 --- /dev/null +++ b/pkgs/development/interpreters/octave/wrap-octave.nix @@ -0,0 +1,16 @@ +{ lib +, octave +, makeSetupHook +, makeWrapper +}: + +# Defined in trivial-builders.nix +# Imported as wrapOctave in octave/default.nix and passed to octave's buildEnv +# as nativeBuildInput +# Each of the substitutions is available in the wrap.sh script as @thingSubstituted@ +makeSetupHook { + name = "${octave.name}-pkgs-setup-hook"; + deps = makeWrapper; + substitutions.executable = octave.interpreter; + substitutions.octave = octave; +} ./wrap.sh diff --git a/pkgs/development/interpreters/octave/wrap.sh b/pkgs/development/interpreters/octave/wrap.sh new file mode 100644 index 0000000000000..a5969fca2a96e --- /dev/null +++ b/pkgs/development/interpreters/octave/wrap.sh @@ -0,0 +1,132 @@ +# Unlinks a directory (given as the first argument), and re-creates that +# directory as an actual directory. Then descends into the directory of +# the same name in the origin (arg_2/arg_3) and symlinks the contents of +# that directory into the passed end-location. +unlinkDirReSymlinkContents() { + local dirToUnlink="$1" + local origin="$2" + local contentsLocation="$3" + + unlink $dirToUnlink/$contentsLocation + mkdir -p $dirToUnlink/$contentsLocation + for f in $origin/$contentsLocation/*; do + ln -s -t "$dirToUnlink/$contentsLocation" "$f" + done +} + +# Using unlinkDirReSymlinkContents, un-symlinks directories down to +# $out/share/octave, and then creates the octave_packages directory. +createOctavePackagesPath() { + local desiredOut=$1 + local origin=$2 + + if [ -L "$out/share" ]; then + unlinkDirReSymlinkContents "$desiredOut" "$origin" "share" + fi + + if [ -L "$out/share/octave" ]; then + unlinkDirReSymlinkContents "$desiredOut" "$origin" "share/octave" + fi + + # Now that octave_packages has a path rather than symlinks, create the + # octave_packages directory for installed packages. + mkdir -p "$desiredOut/share/octave/octave_packages" +} + +# First, descends down to $out/share/octave/site/m/startup/octaverc, and +# copies that start-up file. Once done, it performs a `chmod` to allow +# writing. Lastly, it `echo`s the location of the locally installed packages +# to the startup file, allowing octave to discover installed packages. +addPkgLocalList() { + local desiredOut=$1 + local origin=$2 + local octaveSite="share/octave/site" + local octaveSiteM="$octaveSite/m" + local octaveSiteStartup="$octaveSiteM/startup" + local siteOctavercStartup="$octaveSiteStartup/octaverc" + + unlinkDirReSymlinkContents "$desiredOut" "$origin" "$octaveSite" + unlinkDirReSymlinkContents "$desiredOut" "$origin" "$octaveSiteM" + unlinkDirReSymlinkContents "$desiredOut" "$origin" "$octaveSiteStartup" + + unlink "$out/$siteOctavercStartup" + cp "$origin/$siteOctavercStartup" "$desiredOut/$siteOctavercStartup" + chmod u+w "$desiredOut/$siteOctavercStartup" + echo "pkg local_list $out/.octave_packages" >> "$desiredOut/$siteOctavercStartup" +} + +# Wrapper function for wrapOctaveProgramsIn. Takes one argument, a +# space-delimited string of packages' paths that will be installed. +wrapOctavePrograms() { + wrapOctaveProgramsIn "$out/bin" "$out" "$@" +} + +# Wraps all octave programs in $out/bin with all the propagated inputs that +# a particular package requires. $1 is the directory to look for binaries in +# to wrap. $2 is the path to the octave ENVIRONMENT. $3 is the space-delimited +# string of packages. +wrapOctaveProgramsIn() { + local dir="$1" + local octavePath="$2" + local pkgs="$3" + local f + + buildOctavePath "$octavePath" "$pkgs" + + # Find all regular files in the output directory that are executable. + if [ -d "$dir" ]; then + find "$dir" -type f -perm -0100 -print0 | while read -d "" f; do + echo "wrapping \`$f'..." + local -a wrap_args=("$f" + --prefix PATH ':' "$program_PATH" + ) + local -a wrapProgramArgs=("${wrap_args[@]}") + wrapProgram "${wrapProgramArgs[@]}" + done + fi +} + +# Build the PATH environment variable by walking through the closure of +# dependencies. Starts by constructing the `program_PATH` variable with the +# environment's path, then adding the original octave's location, and marking +# them in `octavePathsSeen`. +buildOctavePath() { + local octavePath="$1" + local packages="$2" + + local pathsToSearch="$octavePath $packages" + + # Create an empty table of Octave paths. + declare -A octavePathsSeen=() + program_PATH= + octavePathsSeen["$out"]=1 + octavePathsSeen["@octave@"]=1 + addToSearchPath program_PATH "$out/bin" + addToSearchPath program_PATH "@octave@/bin" + echo "program_PATH to change to is: $program_PATH" + for path in $pathsToSearch; do + echo "Recurse to propagated-build-input: $path" + _addToOctavePath $path + done +} + +# Adds the bin directories to the program_PATH variable. +# Recurses on any paths declared in `propagated-build-inputs`, while avoiding +# duplicating paths by flagging the directires it has seen in `octavePathsSeen`. +_addToOctavePath() { + local dir="$1" + # Stop if we've already visited this path. + if [ -n "${octavePathsSeen[$dir]}" ]; then return; fi + octavePathsSeen[$dir]=1 + # addToSearchPath is defined in stdenv/generic/setup.sh. It has the effect + # of calling `export X=$dir/...:$X`. + addToSearchPath program_PATH $dir/bin + + # Inspect the propagated inputs (if they exist) and recur on them. + local prop="$dir/nix-support/propagated-build-inputs" + if [ -e $prop ]; then + for new_path in $(cat $prop); do + _addToOctavePath $new_path + done + fi +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 761a5faaecf27..c50b6cdf0636e 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -11346,6 +11346,8 @@ in overridePlatforms = ["x86_64-linux" "x86_64-darwin"]; }; + octavePackages = recurseIntoAttrs octave.pkgs; + ocropus = callPackage ../applications/misc/ocropus { }; pachyderm = callPackage ../applications/networking/cluster/pachyderm { }; diff --git a/pkgs/top-level/octave-packages.nix b/pkgs/top-level/octave-packages.nix new file mode 100644 index 0000000000000..ef5d83b67919f --- /dev/null +++ b/pkgs/top-level/octave-packages.nix @@ -0,0 +1,115 @@ +# This file contains the GNU Octave add-on packages set. +# Each attribute is an Octave library. +# Expressions for the Octave libraries are supposed to be in `pkgs/development/octave-modules/<name>/default.nix`. + +# When contributing a new package, if that package has a dependency on another +# octave package, then you DO NOT need to explicitly list it as such when +# performing the callPackage. It will be passed implicitly. +# In addition, try to use the same dependencies as the ones octave needs, which +# should ensure greater compatibility between Octave itself and its packages. + +# Like python-packages.nix, packages from top-level.nix are not in the scope +# of the `callPackage` used for packages here. So, when we do need packages +# from outside, we can `inherit` them from `pkgs`. +{ pkgs +, lib +, stdenv +, fetchurl +, newScope +, octave +}: + +with lib; + +makeScope newScope (self: + let + inherit (octave) blas lapack gfortran python texinfo gnuplot; + + callPackage = self.callPackage; + + buildOctavePackage = callPackage ../development/interpreters/octave/build-octave-package.nix { + inherit lib stdenv; + inherit octave; + inherit computeRequiredOctavePackages; + }; + + wrapOctave = callPackage ../development/interpreters/octave/wrap-octave.nix { + inherit octave; + inherit (pkgs) makeSetupHook makeWrapper; + }; + + # Given a list of required Octave package derivations, get a list of + # ALL required Octave packages needed for the ones specified to run. + computeRequiredOctavePackages = drvs: let + # Check whether a derivation is an octave package + hasOctavePackage = drv: drv?isOctavePackage; + packages = filter hasOctavePackage drvs; + in unique (packages ++ concatLists (catAttrs "requiredOctavePackages" packages)); + + in { + + inherit callPackage buildOctavePackage computeRequiredOctavePackages; + + inherit (callPackage ../development/interpreters/octave/hooks { }) + writeRequiredOctavePackagesHook; + + arduino = callPackage ../development/octave-modules/arduino { + inherit (pkgs) arduino; + # Full arduino right now. Might be able to use pkgs.arduino-core + # Needs arduinoIDE as a runtime dependency. + }; + + audio = callPackage ../development/octave-modules/audio { + rtmidi = pkgs.rtmidi; + }; + + bim = callPackage ../development/octave-modules/bim { }; + + bsltl = callPackage ../development/octave-modules/bsltl { }; + + cgi = callPackage ../development/octave-modules/cgi { }; + + communications = callPackage ../development/octave-modules/communications { + hdf5 = pkgs.hdf5; + }; + + control = callPackage ../development/octave-modules/control { }; + + io = callPackage ../development/octave-modules/io { + unzip = pkgs.unzip; + }; + + level-set = callPackage ../development/octave-modules/level-set { }; + + linear-algebra = callPackage ../development/octave-modules/linear-algebra { }; + + ltfat = callPackage ../development/octave-modules/ltfat { + fftw = pkgs.fftw; + fftwSinglePrec = pkgs.fftwSinglePrec; + fftwFloat = pkgs.fftwFloat; + fftwLongDouble = pkgs.fftwLongDouble; + portaudio = pkgs.portaudio; + jre = pkgs.jre; + }; + + signal = callPackage ../development/octave-modules/signal { }; + + symbolic = callPackage ../development/octave-modules/symbolic { + # Need to use sympy 1.5.1 for https://github.com/cbm755/octsympy/issues/1023 + # It has been addressed, but not merged yet. + pythonEnv = (let + overridenPython = let + packageOverrides = self: super: { + sympy = super.sympy.overridePythonAttrs (old: rec { + version = pkgs.python2Packages.sympy.version; + src = pkgs.python2Packages.sympy.src; + }); + }; + in python.override {inherit packageOverrides; self = overridenPython; }; + in overridenPython.withPackages (ps: [ + ps.sympy + ps.mpmath + ])); + }; + + }) |