octavePackages: add documentation

+101
+1
doc/languages-frameworks/index.xml
··· 24 24 <xi:include href="lua.section.xml" /> 25 25 <xi:include href="maven.section.xml" /> 26 26 <xi:include href="ocaml.section.xml" /> 27 + <xi:include href="octave.section.xml" /> 27 28 <xi:include href="perl.section.xml" /> 28 29 <xi:include href="php.section.xml" /> 29 30 <xi:include href="python.section.xml" />
+100
doc/languages-frameworks/octave.section.md
··· 1 + # Octave {#sec-octave} 2 + 3 + ## Introduction {#ssec-octave-introduction} 4 + 5 + Octave is a modular scientific programming language and environment. 6 + A majority of the packages supported by Octave from their [website](https://octave.sourceforge.io/packages.php) are packaged in nixpkgs. 7 + 8 + ## Structure {#ssec-octave-structure} 9 + 10 + All Octave add-on packages are available in two ways: 11 + 1. Under the top-level `Octave` attribute, `octave.pkgs`. 12 + 2. As a top-level attribute, `octavePackages`. 13 + 14 + ## Packaging Octave Packages {#ssec-octave-packaging} 15 + 16 + Nixpkgs provides a function `buildOctavePackage`, a generic package builder function for any Octave package that complies with the Octave's current packaging format. 17 + 18 + All Octave packages are defined in [pkgs/top-level/octave-packages.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/octave-packages.nix) rather than `pkgs/all-packages.nix`. 19 + Each package is defined in their own file in the [pkgs/development/octave-modules](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/octave-modules) directory. 20 + Octave packages are made available through `all-packages.nix` through both the attribute `octavePackages` and `octave.pkgs`. 21 + You can test building an Octave package as follows: 22 + 23 + ```ShellSession 24 + $ nix-build -A octavePackages.symbolic 25 + ``` 26 + 27 + When building Octave packages with `nix-build`, the `buildOctavePackage` function adds `octave-octaveVersion` to; the start of the package's name attribute. 28 + 29 + This can be required when installing the package using `nix-env`: 30 + 31 + ```ShellSession 32 + $ nix-env -i octave-6.2.0-symbolic 33 + ``` 34 + 35 + Although, you can also install it using the attribute name: 36 + 37 + ```ShellSession 38 + $ nix-env -i -A octavePackages.symbolic 39 + ``` 40 + 41 + You can build Octave with packages by using the `withPackages` passed-through function. 42 + 43 + ```ShellSession 44 + $ nix-shell -p 'octave.withPackages (ps: with ps; [ symbolic ])' 45 + ``` 46 + 47 + This will also work in a `shell.nix` file. 48 + 49 + ```nix 50 + { pkgs ? import <nixpkgs> { }}: 51 + 52 + pkgs.mkShell { 53 + nativeBuildInputs = with pkgs; [ 54 + (octave.withPackages (opkgs: with opkgs; [ symbolic ])) 55 + ]; 56 + } 57 + ``` 58 + 59 + ### `buildOctavePackage` Steps {#sssec-buildOctavePackage-steps} 60 + 61 + The `buildOctavePackage` does several things to make sure things work properly. 62 + 63 + 1. Sets the environment variable `OCTAVE_HISTFILE` to `/dev/null` during package compilation so that the commands run through the Octave interpreter directly are not logged. 64 + 2. Skips the configuration step, because the packages are stored as gzipped tarballs, which Octave itself handles directly. 65 + 3. Change the hierarchy of the tarball so that only a single directory is at the top-most level of the tarball. 66 + 4. Use Octave itself to run the `pkg build` command, which unzips the tarball, extracts the necessary files written in Octave, and compiles any code written in C++ or Fortran, and places the fully compiled artifact in `$out`. 67 + 68 + `buildOctavePackage` is built on top of `stdenv` in a standard way, allowing most things to be customized. 69 + 70 + ### Handling Dependencies {#sssec-octave-handling-dependencies} 71 + 72 + In Octave packages, there are four sets of dependencies that can be specified: 73 + 74 + `nativeBuildInputs` 75 + : Just like other packages, `nativeBuildInputs` is intended for architecture-dependent build-time-only dependencies. 76 + 77 + `buildInputs` 78 + : Like other packages, `buildInputs` is intended for architecture-independent build-time-only dependencies. 79 + 80 + `propagatedBuildInputs` 81 + : Similar to other packages, `propagatedBuildInputs` is intended for packages that are required for both building and running of the package. 82 + See [Symbolic](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/octave-modules/symbolic/default.nix) for how this works and why it is needed. 83 + 84 + `requiredOctavePackages` 85 + : This is a special dependency that ensures the specified Octave packages are dependent on others, and are made available simultaneously when loading them in Octave. 86 + 87 + ### Installing Octave Packages {#sssec-installing-octave-packages} 88 + 89 + By default, the `buildOctavePackage` function does _not_ install the requested package into Octave for use. 90 + The function will only build the requested package. 91 + This is due to Octave maintaining an text-based database about which packages are installed where. 92 + To this end, when all the requested packages have been built, the Octave package and all its add-on packages are put together into an environment, similar to Python. 93 + 94 + 1. First, all the Octave binaries are wrapped with the environment variable `OCTAVE_SITE_INITFILE` set to a file in `$out`, which is required for Octave to be able to find the non-standard package database location. 95 + 2. Because of the way `buildEnv` works, all tarballs that are present (which should be all Octave packages to install) should be removed. 96 + 3. The path down to the default install location of Octave packages is recreated so that Nix-operated Octave can install the packages. 97 + 4. Install the packages into the `$out` environment while writing package entries to the database file. 98 + This database file is unique for each different (according to Nix) environment invocation. 99 + 5. Rewrite the Octave-wide startup file to read from the list of packages installed in that particular environment. 100 + 6. Wrap any programs that are required by the Octave packages so that they work with all the paths defined within the environment.