nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at r-updates 230 lines 13 kB view raw view rendered
1# Factor {#sec-language-factor} 2 3## Development Environment {#ssec-factor-dev-env} 4 5All Nix expressions for the Factor compiler and development environment can be found in `pkgs/top-level/factor-packages.nix`. 6 7The default package `factor-lang` provides support for the built-in graphical user interface and a selected set of C library bindings, e.g., for sound and TLS connections. 8It also comes with the Fuel library for Emacs that provides an integrated development environment for developing Factor programs including access to the Factor runtime and online documentation. 9 10For using less frequently used libraries that need additional bindings, you can override the `factor-lang` package and add more library bindings and/or binaries to its PATH. 11The package is defined in `pkgs/development/compilers/factor-lang/wrapper.nix` and provides several attributes for adding those: 12 13- `extraLibs` adds the packages' `/lib` paths to the wrapper and adds all shared libraries to an ld.so cache such that they can be found dynamically by the Factor runtime. 14- `binPackages` does the same as `extraLibs` and additionally adds the packages to Factor's PATH environment variable. 15- `extraVocabs` adds Factor vocabularies to the tree that are not part of the standard library. 16 The packages must adhere to the default vocabulary root structure to be found. 17- `guiSupport` draws in all necessary graphical libraries to enable the Factor GUI. 18 This should be set to `true` when considering building and running graphical applications with this Factor runtime (even if the Factor GUI is not used for programming). 19 This argument is `true` by default. 20- `enableDefaults` can be deactivated to only wrap libraries that are named in `extraLibs` or `binPackages`. 21 This reduces the runtime dependencies especially when shipping Factor applications. 22 23The package also passes through several attributes listing the wrapped libraries and binaries, namely, `extraLibs` and `binPackages` as well as `defaultLibs` and `defaultBins`. 24Additionally, all `runtimeLibs` is the concatenation of all the above for the purpose of providing all necessary dynamic libraries as "`propagatedBuildInputs`". 25Lastly, `extraVocabs` is passed through as is for stacked composition, and the fully composed `vocabTree` is passed through as a store path. 26This makes it easier for external plugins (e.g. for editors and IDEs) to refer to the Factor vocabulary roots. 27 28`factorPackages` provides pre-configured Factor packages: 29- `factorPackages.factor-lang` is the default package with GUI support and several default library bindings (e.g. openssl, openal etc.). 30- `factorPackages.factor-no-gui` turns off GUI support while maintaining default library bindings. 31- `factorPackages.factor-minimal` comes with practically no additional library bindings and binaries and no GUI support. 32- `factorPackages.factor-minimal-gui` comes with no additional library bindings but includes GUI support. 33 34### Scaffolding and the `work` vocabulary root {#ssec-factor-scaffolding} 35 36Factor uses the concept of "scaffolding" to spin off a new vocabulary in a personal workspace rooted at the `work` vocabulary root. 37This concept does not scale very well, because it makes many assumptions which all turn out to be wrong at some point. 38In the current implementation, the `work` vocabulary root points to `/var/lib/factor` on the target machine. 39This can be suitable for a single-user system. 40Create the location and make it writable to your user. 41Then, you can use the `scaffold-work` word as instructed by many tutorials. 42 43If you don't like this approach, you can work around it by creating a `~/.factor-roots` file in your home directory which contains the locations you desire to represent additional Factor vocabulary roots, one directory per line. 44Use `scaffold-vocab` to create your vocabularies in one of these additional roots. 45The online Factor documentation is extensive on how to use the scaffolding framework. 46 47## Packaging Factor Vocabularies {#ssec-factor-packaging} 48 49All Factor vocabularies that shall be added to a Factor environment via the `extraVocabs` attribute must adhere to the following directory scheme. 50Its top-level directory must be one (or multiple) of `basis`, `core` or `extra`. 51`work` is routed to `/var/lib/factor` and is not shipped nor referenced in the nix store, see the section on [scaffolding](#ssec-factor-scaffolding). 52You should usually use `extra`, but you can use the other roots to overwrite built-in vocabularies. 53Be aware that vocabularies in `core` are part of the Factor image which the development environment is run from. 54This means the code in those vocabularies is not loaded from the sources, such that you need to call `refresh-all` to recompile and load the changed definitions. 55In these instances, it is advised to override the `factor-unwrapped` package directly, which compiles and packages the core Factor libraries into the default Factor 56image. 57 58As per Factor convention, your vocabulary `foo.factor` must be in a directory of the same name in addition to one of the previously mentioned vocabulary roots, e.g. `extra/foo/foo.factor`. 59 60All extra Factor vocabularies are registered in `pkgs/top-level/factor-packages.nix` and their package definitions usually live in `development/compilers/factor-lang/vocabs/`. 61 62Package a vocabulary using the `buildFactorVocab` function. 63Its default `installPhase` takes care of installing it under `out/lib/factor`. 64It also understands the following special attributes: 65- `vocabName` is the path to the vocabulary to be installed. 66 Defaults to `pname`. 67- `vocabRoot` is the vocabulary root to install the vocabulary under. 68 Defaults to `extra`. 69 Unless you know what you are doing, do not change it. 70 Other readily understood vocabulary roots are `core` and `basis`, which allow you to modify the default Factor runtime environment with an external package. 71- `extraLibs`, `extraVocabs`, `extraPaths` have the same meaning as for [applications](#ssec-factor-applications). 72 They have no immediate effect and are just passed through. 73 When building factor-lang packages and Factor applications that use this respective vocabulary, these variables are evaluated and their paths added to the runtime environment. 74 75The function understands several forms of source directory trees: 761. Simple single-vocab projects with their Factor and supplementary files directly in the project root. 77 All `.factor` and `.txt` files are copied to `out/lib/factor/<vocabRoot>/<vocabName>`. 782. More complex projects with several vocabularies next to each other, e.g. `./<vocabName>` and `./<otherVocab>`. 79 All directories except `bin`, `doc` and `lib` are copied to `out/lib/factor/<vocabRoot>`. 803. Even more complex projects that touch multiple vocabulary roots. 81 Vocabularies must reside under `lib/factor/<root>/<vocab>` with the name-giving vocabulary being in `lib/factor/<vocabRoot>/<vocabName>`. 82 All directories in `lib/factor` are copied to `out/`. 83 84For instance, packaging the Bresenham algorithm for line interpolation looks like this, see `pkgs/development/compilers/factor-lang/vocabs/bresenham` for the complete file: 85```nix 86{ factorPackages, fetchFromGitHub }: 87 88factorPackages.buildFactorVocab { 89 pname = "bresenham"; 90 version = "dev"; 91 92 src = fetchFromGitHub { 93 owner = "Capital-EX"; 94 repo = "bresenham"; 95 rev = "58d76b31a17f547e19597a09d02d46a742bf6808"; 96 hash = "sha256-cfQOlB877sofxo29ahlRHVpN3wYTUc/rFr9CJ89dsME="; 97 }; 98} 99``` 100 101The vocabulary goes to `lib/factor/extra`, extra files, like licenses etc. would go to `share/` as usual and could be added to the output via a `postInstall` phase. 102In case the vocabulary binds to a shared library or calls a binary that needs to be present in the runtime environment of its users, add `extraPaths` and `extraLibs` attributes, respectively. 103They are then picked up by the `buildFactorApplication` function and added as runtime dependencies. 104 105## Building Applications {#ssec-factor-applications} 106 107Factor applications are built using Factor's `deploy` facility with the help of the `buildFactorApplication` function. 108 109### `buildFactorApplication` function {#ssec-factor-buildFactorApplication-func} 110 111`factorPackages.buildFactorApplication` *`buildDesc`* 112 113When packaging a Factor application with [`buildFactorApplication`](#ssec-factor-buildFactorApplication-func), its [`override`](#sec-pkg-override) interface should contain the `factorPackages` argument. 114For example: 115```nix 116{ 117 lib, 118 fetchurl, 119 factorPackages, 120}: 121 122factorPackages.buildFactorApplication (finalAttrs: { 123 pname = "foo"; 124 version = "1.0"; 125 126 src = fetchurl { 127 url = "https://some-forge.org/foo-${finalAttrs.version}.tar.gz"; 128 }; 129}) 130``` 131 132The `buildFactorApplication` function expects the following source structure for a package `foo-1.0` and produces a `/bin/foo` application: 133``` 134foo-1.0/ 135 foo/ 136 foo.factor 137 deploy.factor 138 <more files and directories>... 139``` 140 141It provides the additional attributes `vocabName` and `binName` to cope with naming deviations. 142The `deploy.factor` file controls how the application is deployed and is documented in the Factor online documentation on the `deploy` facility. 143 144Use the `preInstall` or `postInstall` hooks to copy additional files and directories to `out/`. 145The function itself only builds the application in `/lib/factor/` and a wrapper in `/bin/`. 146 147A more complex example shows how to specify runtime dependencies and additional Factor vocabularies at the example of the `painter` Factor application: 148```nix 149{ 150 lib, 151 fetchFromGitHub, 152 factorPackages, 153 curl, 154}: 155 156factorPackages.buildFactorApplication (finalAttrs: { 157 pname = "painter"; 158 version = "1"; 159 160 factor-lang = factorPackages.factor-minimal-gui; 161 162 src = fetchFromGitHub { 163 name = finalAttrs.vocabName; 164 owner = "Capital-EX"; 165 repo = "painter"; 166 rev = "365797be8c4f82440bec0ad0a50f5a858a06c1b6"; 167 hash = "sha256-VdvnvKNGcFAtjWVDoxyYgRSyyyy0BEZ2MZGQ71O8nUI="; 168 }; 169 170 sourceRoot = "."; 171 172 enableUI = true; 173 extraVocabs = [ factorPackages.bresenham ]; 174 175 extraPaths = with finalAttrs.factor-lang; binPackages ++ defaultBins ++ [ curl ]; 176 177}) 178``` 179 180The use of the `src.name` and `sourceRoot` attributes conveniently establish the necessary `painter` vocabulary directory that is needed for the deployment to work. 181 182It requires the packager to specify the full set of binaries to be made available at runtime. 183This enables the standard pattern for application packages to specify all runtime dependencies explicitly without the Factor runtime interfering. 184 185`buildFactorApplication` is a wrapper around `stdenv.mkDerivation` and takes all of its attributes. 186Additional attributes that are understood by `buildFactorApplication`: 187 188*`buildDesc`* (Function or attribute set) 189 190: A build description similar to `stdenv.mkDerivation` with the following attributes: 191 192 `vocabName` (String; _optional_) 193 194 : is the path to the vocabulary to be deployed relative to the source root. 195 So, directory `foo/` from the example above could be `extra/deep/down/foo`. 196 This allows you to maintain Factor's vocabulary hierarchy and distribute the same source tree as a stand-alone application and as a library in the Factor development environment via the `extraVocabs` attribute. 197 198 `binName` (String; _optional_) 199 200 : is the name of the resulting binary in `/bin/`. 201 It defaults to the last directory component in `vocabName`. 202 It is also added as the `meta.mainProgram` attribute to facilitate `nix run`. 203 204 `enableUI` (Boolean; _optional_) 205 206 : is `false` by default. 207 Set this to `true` when you ship a graphical application. 208 209 `extraLibs` (List; _optional_) 210 211 : adds additional libraries as runtime dependencies. 212 Defaults to `[]` and is concatenated with `runtimeLibs` from the used factor-lang package. 213 Use `factor-minimal` to minimize the closure of runtime libraries. 214 215 `extraPaths` (List; _optional_) 216 217 : adds additional binaries to the runtime PATH environment variable (without adding their libraries, as well). 218 Defaults to `[]` and is concatenated with `defaultBins` and `binPackages` from the used factor-lang package. 219 Use `factor-minimal` to minimize the closure of runtime libraries. 220 221 `deployScriptText` (String; _optional_) 222 223 : is the actual deploy Factor file that is executed to deploy the application. 224 You can change it if you need to perform additional computation during deployment. 225 226 `factor-lang` (Package; _optional_) 227 228 : overrides the Factor package to use to deploy this application, which also affects the default library bindings and programs in the runtime PATH. 229 It defaults to `factor-lang` when `enableUI` is turned on and `factor-no-gui` when it is turned off. 230 Applications that use only Factor libraries without external bindings or programs may set this to `factor-minimal` or `factor-minimal-gui`.