factor: Restructure package for easier extension

+231
doc/languages-frameworks/factor.section.md
···
+
# Factor {#sec-language-factor}
+
+
## Development Environment {#ssec-factor-dev-env}
+
+
All Nix expressions for the Factor compiler and development environment can be found in `pkgs/top-level/factor-packages.nix`.
+
+
The 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.
+
It 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.
+
+
For 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.
+
The package is defined in `pkgs/development/compilers/factor-lang/wrapper.nix` and provides several attributes for adding those:
+
+
- `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.
+
- `binPackages` does the same as `extraLibs` and additionally adds the packages to Factor's PATH environment variable.
+
- `extraVocabs` adds Factor vocabularies to the tree that are not part of the standard library.
+
The packages must adhere to the default vocabulary root structure to be found.
+
- `guiSupport` draws in all necessary graphical libraries to enable the Factor GUI.
+
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).
+
This argument is `true` by default.
+
- `enableDefaults` can be deactivated to only wrap libraries that are named in `extraLibs` or `binPackages`.
+
This reduces the runtime dependencies especially when shipping Factor applications.
+
+
The package also passes through several attributes listing the wrapped libraries and binaries, namely, `extraLibs` and `binPackages` as well as `defaultLibs` and `defaultBins`.
+
Additionally, all `runtimeLibs` is the concatenation of all the above for the purpose of providing all necessary dynamic libraries as "`propagatedBuildInputs`".
+
+
`factorPackages` provides pre-configured Factor packages:
+
- `factorPackages.factor-lang` is the default package with GUI support and several default library bindings (e.g. openssl, openal etc.).
+
- `factorPackages.factor-no-gui` turns off GUI support while maintaining default library bindings.
+
- `factorPackages.factor-minimal` comes with practically no additional library bindings and binaries and no GUI support.
+
- `factorPackages.factor-minimal-gui` comes with no additional library bindings but includes GUI support.
+
+
### Scaffolding and the `work` vocabulary root {#ssec-factor-scaffolding}
+
+
Factor uses the concept of "scaffolding" to spin off a new vocabulary in a personal workspace rooted at the `work` vocabulary root.
+
This concept does not scale very well, because it makes many assumptions which all turn out to be wrong at some point.
+
In the current implementation, the `work` vocabulary root points to `/var/lib/factor` on the target machine.
+
This can be suitable for a single-user system.
+
Create the location and make it writable to your user.
+
Then, you can use the `scaffold-work` word as instructed by many tutorials.
+
+
If 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.
+
Use `scaffold-vocab` to create your vocabularies in one of these additional roots.
+
The online Factor documentation is extensive on how to use the scaffolding framework.
+
+
## Packaging Factor Vocabularies {#ssec-factor-packaging}
+
+
All Factor vocabularies that shall be added to a Factor environment via the `extraVocabs` attribute must adhere to the following directory scheme.
+
Its top-level directory must be one (or multiple) of `basis`, `core` or `extra`.
+
`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).
+
You should usually use `extra`, but you can use the other roots to overwrite built-in vocabularies.
+
Be aware that vocabularies in `core` are part of the Factor image which the development environment is run from.
+
This means the code in those vocabularies is not loaded from the sources, such that you need to call `refresh-all` to re-compile and load the changed definitions.
+
In these instances, it is advised to override the `factor-unwrapped` package directly, which compiles and packages the core Factor libraries into the default Factor
+
image.
+
+
As 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`.
+
+
All extra Factor vocabularies are registered in `pkgs/top-level/factor-packages.nix` and their package definitions usually live in `development/compilers/factor-lang/vocabs/`.
+
+
Package a vocabulary using the `buildFactorVocab` function.
+
Its default `installPhase` takes care of installing it under `out/lib/factor`.
+
It also understands the following special attributes:
+
- `vocabName` is the path to the vocabulary to be installed.
+
Defaults to `pname`.
+
- `vocabRoot` is the vocabulary root to install the vocabulary under.
+
Defaults to `extra`.
+
Unless you know what you are doing, do not change it.
+
Other readily understood vocabulary roots are `core` and `base`, which allow you to modify the default Factor runtime environment with an external package.
+
- `extraLibs`, `extraVocabs`, `extraPaths` have the same meaning as for [applications](#ssec-factor-applications).
+
They have no immediate effect and are just passed through.
+
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.
+
+
The function understands several forms of source directory trees:
+
1. Simple single-vocab projects with their Factor and supplementary files directly in the project root.
+
All `.factor` and `.txt` files are copied to `out/lib/factor/<vocabRoot>/<vocabName>`.
+
2. More complex projects with several vocabularies next to each other, e.g. `./<vocabName>` and `./<otherVocab>`.
+
All directories except `bin`, `doc` and `lib` are copied to `out/lib/factor/<vocabRoot>`.
+
3. Even more complex projects that touch multiple vocabulary roots.
+
Vocabularies must reside under `lib/factor/<root>/<vocab>` with the name-giving vocabulary being in `lib/factor/<vocabRoot>/<vocabName>`.
+
All directories in `lib/factor` are copied to `out/`.
+
+
For instance, packaging the Bresenham algorithm for line interpolation looks like this, see `pkgs/development/compilers/factor-lang/vocabs/bresenham` for the complete file:
+
```nix
+
{
+
factorPackages,
+
fetchFromGitHub,
+
}:
+
+
factorPackages.buildFactorVocab {
+
pname = "bresenham";
+
version = "dev";
+
+
src = fetchFromGitHub {
+
owner = "Capital-EX";
+
repo = "bresenham";
+
rev = "58d76b31a17f547e19597a09d02d46a742bf6808";
+
hash = "sha256-cfQOlB877sofxo29ahlRHVpN3wYTUc/rFr9CJ89dsME=";
+
};
+
}
+
```
+
+
The 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.
+
In 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.
+
They are then picked up by the `buildFactorApplication` function and added as runtime dependencies.
+
+
## Building Applications {#ssec-factor-applications}
+
+
Factor applications are built using Factor's `deploy` facility with the help of the `buildFactorApplication` function.
+
+
### `buildFactorApplication` function {#ssec-factor-buildFactorApplication-func}
+
+
`factorPackages.buildFactorApplication` *`buildDesc`*
+
+
When packaging a Factor application with [`buildFactorApplication`](#ssec-factor-buildFactorApplication-func), its [`override`](#sec-pkg-override) interface should contain the `factorPackages` argument.
+
For example:
+
```nix
+
{
+
lib,
+
fetchurl,
+
factorPackages,
+
}:
+
+
factorPackages.buildFactorApplication (finalAttrs: {
+
pname = "foo";
+
version = "1.0";
+
+
src = fetchurl {
+
url = "https://some-forge.org/foo-${finalAttrs.version}.tar.gz"
+
};
+
})
+
```
+
+
The `buildFactorApplication` function expects the following source structure for a package `foo-1.0` and produces a `/bin/foo` application:
+
```
+
foo-1.0/
+
foo/
+
foo.factor
+
deploy.factor
+
<more files and directories>...
+
```
+
+
It provides the additional attributes `vocabName` and `binName` to cope with naming deviations.
+
The `deploy.factor` file controls how the application is deployed and is documented in the Factor online documentation on the `deploy` facility.
+
+
Use the `preInstall` or `postInstall` hooks to copy additional files and directories to `out/`.
+
The function itself only builds the application in `/lib/factor/` and a wrapper in `/bin/`.
+
+
A more complex example shows how to specify runtime dependencies and additional Factor vocabularies at the example of the `painter` Factor application:
+
```nix
+
{
+
lib,
+
fetchFromGitHub,
+
factorPackages,
+
curl,
+
}:
+
+
factorPackages.buildFactorApplication (finalAttrs: {
+
pname = "painter";
+
version = "1";
+
+
factor-lang = factorPackages.factor-minimal-gui;
+
+
src = fetchFromGitHub {
+
name = finalAttrs.vocabName;
+
owner = "Capital-EX";
+
repo = "painter";
+
rev = "365797be8c4f82440bec0ad0a50f5a858a06c1b6";
+
hash = "sha256-VdvnvKNGcFAtjWVDoxyYgRSyyyy0BEZ2MZGQ71O8nUI=";
+
};
+
+
sourceRoot = ".";
+
+
enableUI = true;
+
extraVocabs = [ factorPackages.bresenham ];
+
+
extraPaths = with finalAttrs.factor-lang; binPackages ++ defaultBins ++ [ curl ];
+
+
})
+
```
+
+
The use of the `src.name` and`sourceRoot` attributes conveniently establish the necessary `painter` vocabulary directory that is needed for the deployment to work.
+
+
It requires the packager to specify the full set of binaries to be made available at runtime.
+
This enables the standard pattern for application packages to specify all runtime dependencies explicitly without the Factor runtime interfering.
+
+
`buildFactorApplication` is a wrapper around `stdenv.mkDerivation` and takes all of its attributes.
+
Additional attributes that are understood by `buildFactorApplication`:
+
+
*`buildDesc`* (Function or attribute set)
+
+
: A build description similar to `stdenv.mkDerivation` with the following attributes:
+
+
`vocabName` (String; _optional_)
+
+
: is the path to the vocabulary to be deployed relative to the source root.
+
So, directory `foo/` from the example above could be `extra/deep/down/foo`.
+
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.
+
+
`binName` (String; _optional_)
+
+
: is the name of the resulting binary in `/bin/`.
+
It defaults to the last directory component in `vocabName`.
+
It is also added as the `meta.mainProgram` attribute to facilitate `nix run`.
+
+
`enableUI` (Boolean; _optional_)
+
+
: is `false` by default.
+
Set this to `true` when you ship a graphical application.
+
+
`extraLibs` (List; _optional_)
+
+
: adds additional libraries as runtime dependencies.
+
Defaults to `[]` and is concatenated with `runtimeLibs` from the used factor-lang package.
+
Use `factor-minimal` to minimize the closure of runtime libraries.
+
+
`extraPaths` (List; _optional_)
+
+
: adds additional binaries to the runtime PATH environment variable (without adding their libraries, as well).
+
Defaults to `[]` and is concatenated with `defaultBins` and `binPackages` from the used factor-lang package.
+
Use `factor-minimal` to minimize the closure of runtime libraries.
+
+
`deployScriptText` (String; _optional_)
+
+
: is the actual deploy Factor file that is executed to deploy the application.
+
You can change it if you need to perform additional computation during deployment.
+
+
`factor-lang` (Package; _optional_)
+
+
: overrides the Factor package to use to deploy this application, which also affects the default library bindings and programs in the runtime PATH.
+
It defaults to `factor-lang` when `enableUI` is turned on and `factor-no-gui` when it is turned off.
+
Applications that use only Factor libraries without external bindings or programs may set this to `factor-minimal` or `factor-minimal-gui`.
+1
doc/languages-frameworks/index.md
···
dlang.section.md
dotnet.section.md
emscripten.section.md
+
factor.section.md
gnome.section.md
go.section.md
gradle.section.md
+18
doc/redirects.json
···
"declarative-debugging": [
"index.html#declarative-debugging"
],
+
"sec-language-factor": [
+
"index.html#sec-language-factor"
+
],
+
"ssec-factor-scaffolding": [
+
"index.html#ssec-factor-scaffolding"
+
],
+
"ssec-factor-packaging": [
+
"index.html#ssec-factor-packaging"
+
],
+
"ssec-factor-buildFactorApplication-func": [
+
"index.html#ssec-factor-buildFactorApplication-func"
+
],
+
"ssec-factor-dev-env": [
+
"index.html#ssec-factor-dev-env"
+
],
+
"ssec-factor-applications": [
+
"index.html#ssec-factor-applications"
+
],
"sec-language-gnome": [
"index.html#sec-language-gnome"
],
+2
doc/release-notes/rl-2505.section.md
···
- LLVM has been updated from LLVM 16 (on Darwin) and LLVM 18 (on other platforms) to LLVM 19.
This introduces some backwards‐incompatible changes; see the [upstream release notes](https://releases.llvm.org/) for details.
+
- The Factor programming language packages were reworked. `factor-lang-scope` is now named `factorPackages` and provides a `buildFactorApplication` function to deploy Factor programs as binaries. It has also received proper documentation in the Nixpkgs manual.
+
- Emacs has been updated to 30.1.
This introduces some backwards‐incompatible changes; see the NEWS for details.
NEWS can been viewed from Emacs by typing `C-h n`, or by clicking `Help->Emacs News` from the menu bar.
+17 -16
pkgs/development/compilers/factor-lang/adjust-paths-in-unit-tests.patch
···
-
From da8a4b9c1094a568f443c525ca1ce11f686be1bc Mon Sep 17 00:00:00 2001
-
From: timor <timor.dd@googlemail.com>
-
Date: Thu, 8 Aug 2019 14:13:09 +0200
-
Subject: [PATCH] adjust unit test for finding executables in path for NixOS
-
-
---
-
basis/io/standard-paths/unix/unix-tests.factor | 4 ++--
-
1 file changed, 2 insertions(+), 2 deletions(-)
-
-
diff --git a/basis/io/standard-paths/unix/unix-tests.factor b/basis/io/standard-paths/unix/unix-tests.factor
-
index acd5029..870537f 100644
-
--- a/basis/io/standard-paths/unix/unix-tests.factor
-
+++ b/basis/io/standard-paths/unix/unix-tests.factor
-
@@ -5,13 +5,13 @@ sequences tools.test ;
-
+
diff -ur factor.orig/basis/io/standard-paths/unix/unix-tests.factor factor/basis/io/standard-paths/unix/unix-tests.factor
+
--- factor.orig/basis/io/standard-paths/unix/unix-tests.factor 2024-02-09 14:38:33.932439180 +0100
+
+++ factor/basis/io/standard-paths/unix/unix-tests.factor 2024-02-09 15:41:18.529141569 +0100
+
@@ -1,21 +1,21 @@
+
! Copyright (C) 2011 Doug Coleman.
+
! See https://factorcode.org/license.txt for BSD license.
+
USING: environment io.standard-paths io.standard-paths.unix
+
-sequences tools.test ;
+
+kernel sequences tools.test ;
+
{ f } [ "" find-in-path ] unit-test
{ t } [
- "ls" find-in-path { "/bin/ls" "/usr/bin/ls" } member?
+ "ls" find-in-path not not
] unit-test
-
+
{ t } [
"/sbin:" "PATH" os-env append "PATH" [
"ps" find-in-path
···
+ not not
] with-os-env
] unit-test
+
+
{ t } [
+
"ls" find-in-standard-login-path
+
- { "/bin/ls" "/usr/bin/ls" } member?
+
+ not not
+
] unit-test
+27
pkgs/development/compilers/factor-lang/ld.so.cache-from-env.patch
···
+
diff -ur factor.orig/basis/alien/libraries/finder/linux/linux.factor factor/basis/alien/libraries/finder/linux/linux.factor
+
--- factor.orig/basis/alien/libraries/finder/linux/linux.factor 2024-02-09 14:38:33.966439078 +0100
+
+++ factor/basis/alien/libraries/finder/linux/linux.factor 2024-02-09 14:41:16.775938179 +0100
+
@@ -2,7 +2,7 @@
+
! See https://factorcode.org/license.txt for BSD license
+
USING: accessors alien.libraries.finder arrays assocs
+
combinators.short-circuit environment io io.encodings.utf8
+
-io.launcher kernel make sequences sets splitting system
+
+io.files io.launcher kernel make sequences sets splitting system
+
unicode ;
+
IN: alien.libraries.finder.linux
+
+
@@ -25,8 +25,12 @@
+
] map ;
+
+
: load-ldconfig-cache ( -- seq )
+
- "/sbin/ldconfig -p" utf8 [ read-lines ] with-process-reader*
+
- 2drop [ f ] [ rest parse-ldconfig-lines ] if-empty ;
+
+ "FACTOR_LD_SO_CACHE" os-env [
+
+ utf8 [ read-lines ] with-file-reader
+
+ ] [
+
+ { } clone
+
+ ] if*
+
+ [ f ] [ rest parse-ldconfig-lines ] if-empty ;
+
+
: ldconfig-arch ( -- str )
+
mach-map cpu of { "libc6" } or ;
+141
pkgs/development/compilers/factor-lang/mk-factor-application.nix
···
+
{
+
stdenv,
+
lib,
+
writeText,
+
makeWrapper,
+
factor-lang,
+
factor-no-gui,
+
librsvg,
+
gdk-pixbuf,
+
}@initAttrs:
+
+
drvArgs:
+
+
let
+
flang = factor-lang; # workaround to satisfy nixf-tidy
+
in
+
(stdenv.mkDerivation drvArgs).overrideAttrs (
+
finalAttrs:
+
{
+
name ? "${finalAttrs.pname}-${finalAttrs.version}",
+
factor-lang ? if enableUI then flang else factor-no-gui,
+
enableUI ? false,
+
# Allow overriding the path to the deployed vocabulary name. A
+
# $vocabName.factor file must exist!
+
vocabName ? finalAttrs.pname or name,
+
# Allow overriding the binary name
+
binName ? lib.last (lib.splitString "/" vocabName),
+
# Extra libraries needed
+
extraLibs ? [ ],
+
# Extra binaries in PATH
+
extraPaths ? [ ],
+
# Extra vocabularies needed by this application
+
extraVocabs ? [ ],
+
deployScriptText ? ''
+
USING: command-line io io.backend io.pathnames kernel namespaces sequences
+
tools.deploy tools.deploy.config tools.deploy.backend vocabs.loader ;
+
+
IN: deploy-me
+
+
: load-and-deploy ( path/vocab -- )
+
normalize-path [
+
parent-directory add-vocab-root
+
] [
+
file-name dup reload deploy
+
] bi ;
+
+
: deploy-vocab ( path/vocab path/target -- )
+
normalize-path deploy-directory set
+
f open-directory-after-deploy? set
+
load-and-deploy ;
+
+
: deploy-me ( -- )
+
command-line get dup length 2 = [
+
first2 deploy-vocab
+
] [
+
drop
+
"usage: deploy-me <PATH-TO-VOCAB> <TARGET-DIR>" print
+
nl
+
] if ;
+
+
MAIN: deploy-me
+
'',
+
...
+
}@attrs:
+
let
+
deployScript = writeText "deploy-me.factor" finalAttrs.deployScriptText;
+
wrapped-factor = finalAttrs.factor-lang.override {
+
inherit (finalAttrs) extraLibs extraVocabs;
+
doInstallCheck = false;
+
};
+
runtimePaths = with finalAttrs.wrapped-factor; defaultBins ++ binPackages ++ finalAttrs.extraPaths;
+
in
+
{
+
inherit
+
enableUI
+
vocabName
+
deployScriptText
+
extraLibs
+
extraPaths
+
extraVocabs
+
binName
+
factor-lang
+
wrapped-factor
+
;
+
nativeBuildInputs = [
+
makeWrapper
+
(lib.hiPrio finalAttrs.wrapped-factor)
+
] ++ attrs.nativeBuildInputs or [ ];
+
+
buildInputs = (lib.optional enableUI gdk-pixbuf) ++ attrs.buildInputs or [ ];
+
+
buildPhase =
+
attrs.buildPhase or ''
+
runHook preBuild
+
vocabBaseName=$(basename "$vocabName")
+
mkdir -p "$out/lib/factor" "$TMPDIR/.cache"
+
export XDG_CACHE_HOME="$TMPDIR/.cache"
+
+
factor "${deployScript}" "./$vocabName" "$out/lib/factor"
+
cp "$TMPDIR/factor-temp"/*.image "$out/lib/factor/$vocabBaseName"
+
runHook postBuild
+
'';
+
+
__structuredAttrs = true;
+
+
installPhase =
+
attrs.installPhase or (
+
''
+
runHook preInstall
+
''
+
+ (lib.optionalString finalAttrs.enableUI ''
+
# Set Gdk pixbuf loaders file to the one from the build dependencies here
+
unset GDK_PIXBUF_MODULE_FILE
+
# Defined in gdk-pixbuf setup hook
+
findGdkPixbufLoaders "${librsvg}"
+
appendToVar makeWrapperArgs --set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE"
+
appendToVar makeWrapperArgs --prefix LD_LIBRARY_PATH : /run/opengl-driver/lib
+
'')
+
+ (lib.optionalString (wrapped-factor.runtimeLibs != [ ])) ''
+
appendToVar makeWrapperArgs --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath wrapped-factor.runtimeLibs}"
+
''
+
+ ''
+
mkdir -p "$out/bin"
+
makeWrapper "$out/lib/factor/$vocabBaseName/$vocabBaseName" \
+
"$out/bin/$binName" \
+
--prefix PATH : "${lib.makeBinPath runtimePaths}" \
+
"''${makeWrapperArgs[@]}"
+
runHook postInstall
+
''
+
);
+
+
passthru = {
+
vocab = finalAttrs.src;
+
} // attrs.passthru or { };
+
+
meta = {
+
platforms = wrapped-factor.meta.platforms;
+
mainProgram = finalAttrs.binName;
+
} // attrs.meta or { };
+
}
+
)
+59
pkgs/development/compilers/factor-lang/mk-vocab.nix
···
+
{
+
stdenv,
+
}@initAttrs:
+
+
drvArgs:
+
+
(stdenv.mkDerivation drvArgs).overrideAttrs (
+
finalAttrs:
+
{
+
name ? "${finalAttrs.pname}-${finalAttrs.version}",
+
vocabName ? finalAttrs.pname or name,
+
vocabRoot ? "extra",
+
# Runtime libraries needed to run this vocab, handed to runtime wrapper
+
extraLibs ? [ ],
+
# Extra vocabularies, handed to runtime wrapper
+
extraVocabs ? [ ],
+
# Extra binaries in PATH, handed to runtime wrapper
+
extraPaths ? [ ],
+
...
+
}@attrs:
+
{
+
inherit vocabName vocabRoot;
+
installPhase =
+
# Default installer
+
# 1. If lib/factor/<vocabRoot>/<vocabName> exists, copy all vocab roots
+
# under lib/factor/* to out/.
+
# 2. If <vocabName> exists, copy all directories next to <vocabName> to
+
# out/.
+
# These two carry over package-defined vocabs that the name-giving vocab
+
# depends on.
+
# 3. Otherwise, copy all .factor and .txt files to out/. For simple
+
# single-vocab packages.
+
attrs.installPhase or ''
+
runHook preInstall
+
mkdir -p "$out/lib/factor/${finalAttrs.vocabRoot}/${finalAttrs.vocabName}"
+
if [ -d "lib/factor/${finalAttrs.vocabRoot}/${finalAttrs.vocabName}" ]; then
+
find lib/factor -mindepth 1 -maxdepth 1 -type d -exec \
+
cp -r -t "$out/lib/factor" {} \+
+
elif [ -d "${finalAttrs.vocabName}" ]; then
+
fname="${finalAttrs.vocabName}"
+
base=$(basename "${finalAttrs.vocabName}")
+
root=''${fname%$base}
+
root=''${root:-.}
+
find "$root" -mindepth 1 -maxdepth 1 -type -d \
+
-not \( -name bin -or -name doc -or -name lib \) -exec \
+
cp -r -t "$out/lib/factor/${finalAttrs.vocabRoot}" {} \+
+
else
+
cp *.factor *.txt "$out/lib/factor/${finalAttrs.vocabRoot}/${finalAttrs.vocabName}"
+
fi
+
runHook postInstall
+
'';
+
+
passthru = {
+
inherit extraLibs extraVocabs extraPaths;
+
};
+
+
meta = attrs.meta or { };
+
}
+
)
-24
pkgs/development/compilers/factor-lang/scope.nix
···
-
{
-
lib,
-
pkgs,
-
overrides ? (self: super: { }),
-
}:
-
-
let
-
inside = (
-
self:
-
let
-
callPackage = pkgs.newScope self;
-
in
-
{
-
interpreter = callPackage ./factor99.nix { inherit (pkgs) stdenv; };
-
-
# Convenience access for using the returned attribute the same way as the
-
# interpreter derivation. Takes a list of runtime libraries as its only
-
# argument.
-
inherit (self.interpreter) withLibs;
-
}
-
);
-
extensible-self = lib.makeExtensible (lib.extends overrides inside);
-
in
-
extensible-self
+110
pkgs/development/compilers/factor-lang/unwrapped.nix
···
+
{
+
lib,
+
stdenv,
+
fetchurl,
+
makeWrapper,
+
curl,
+
git,
+
ncurses,
+
tzdata,
+
unzip,
+
}:
+
+
stdenv.mkDerivation (finalAttrs: {
+
pname = "factor-lang";
+
version = "0.99";
+
+
src = fetchurl {
+
url = "https://downloads.factorcode.org/releases/${finalAttrs.version}/factor-src-${finalAttrs.version}.zip";
+
sha256 = "f5626bb3119bd77de9ac3392fdbe188bffc26557fab3ea34f7ca21e372a8443e";
+
};
+
+
patches = [
+
# Use full path to image while bootstrapping
+
./staging-command-line-0.99-pre.patch
+
# Point work vocabulary root to a writable location
+
./workdir-0.99-pre.patch
+
# Patch hard-coded FHS paths
+
./adjust-paths-in-unit-tests.patch
+
# Avoid using /sbin/ldconfig
+
./ld.so.cache-from-env.patch
+
];
+
+
nativeBuildInputs = [
+
git
+
makeWrapper
+
curl
+
unzip
+
];
+
+
postPatch = ''
+
sed -ie '4i GIT_LABEL = heads/master-'$(< git-id) GNUmakefile
+
# Some other hard-coded paths to fix:
+
substituteInPlace extra/tzinfo/tzinfo.factor \
+
--replace-fail '/usr/share/zoneinfo' '${tzdata}/share/zoneinfo'
+
+
substituteInPlace extra/terminfo/terminfo.factor \
+
--replace-fail '/usr/share/terminfo' '${ncurses.out}/share/terminfo'
+
+
# update default paths in fuel-listener.el for fuel mode
+
substituteInPlace misc/fuel/fuel-listener.el \
+
--replace-fail '(defcustom fuel-factor-root-dir nil' "(defcustom fuel-factor-root-dir \"$out/lib/factor\""
+
'';
+
+
dontConfigure = true;
+
+
preBuild = ''
+
patchShebangs ./build.sh
+
# Factor uses XDG_CACHE_HOME for cache during compilation.
+
# We can't have that. So, set it to $TMPDIR/.cache
+
export XDG_CACHE_HOME=$TMPDIR/.cache
+
mkdir -p $XDG_CACHE_HOME
+
'';
+
+
makeTarget = "linux-x86-64";
+
+
postBuild = ''
+
printf "First build from upstream boot image\n" >&2
+
./build.sh bootstrap
+
printf "Rebuild boot image\n" >&2
+
./factor -script -e='"unix-x86.64" USING: system bootstrap.image memory ; make-image save 0 exit'
+
printf "Second build from local boot image\n" >&2
+
./build.sh bootstrap
+
'';
+
+
installPhase = ''
+
runHook preInstall
+
mkdir -p $out/lib/factor $out/share/emacs/site-lisp
+
cp -r factor factor.image libfactor.a libfactor-ffi-test.so \
+
boot.*.image LICENSE.txt README.md basis core extra misc \
+
$out/lib/factor
+
+
# install fuel mode for emacs
+
ln -r -s $out/lib/factor/misc/fuel/*.el $out/share/emacs/site-lisp
+
runHook postInstall
+
'';
+
+
meta = with lib; {
+
homepage = "https://factorcode.org/";
+
description = "A concatenative, stack-based programming language";
+
longDescription = ''
+
The Factor programming language is a concatenative, stack-based
+
programming language with high-level features including dynamic types,
+
extensible syntax, macros, and garbage collection. On a practical side,
+
Factor has a full-featured library, supports many different platforms, and
+
has been extensively documented.
+
+
The implementation is fully compiled for performance, while still
+
supporting interactive development. Factor applications are portable
+
between all common platforms. Factor can deploy stand-alone applications
+
on all platforms. Full source code for the Factor project is available
+
under a BSD license.
+
'';
+
license = licenses.bsd2;
+
maintainers = with maintainers; [
+
vrthra
+
spacefrogg
+
];
+
platforms = [ "x86_64-linux" ];
+
};
+
})
+183
pkgs/development/compilers/factor-lang/wrapper.nix
···
+
{
+
lib,
+
stdenv,
+
makeWrapper,
+
buildEnv,
+
factor-unwrapped,
+
cairo,
+
freealut,
+
gdk-pixbuf,
+
glib,
+
gnome2,
+
gtk2-x11,
+
libGL,
+
libGLU,
+
librsvg,
+
graphviz,
+
libogg,
+
libvorbis,
+
openal,
+
openssl,
+
pango,
+
pcre,
+
udis86,
+
zlib,
+
# Enable factor GUI support
+
guiSupport ? true,
+
# Libraries added to ld.so.cache
+
extraLibs ? [ ],
+
# Packages added to path (and ld.so.cache)
+
binPackages ? [ ],
+
# Extra vocabularies added to out/lib/factor
+
extraVocabs ? [ ],
+
# Enable default libs and bins to run most of the standard library code.
+
enableDefaults ? true,
+
doInstallCheck ? true,
+
}:
+
let
+
inherit (lib) optional optionals optionalString;
+
# missing from lib/strings
+
escapeNixString = s: lib.escape [ "$" ] (builtins.toJSON s);
+
toFactorArgs = x: lib.concatStringsSep " " (map escapeNixString x);
+
defaultLibs = optionals enableDefaults [
+
libogg
+
libvorbis
+
openal
+
openssl
+
pcre
+
udis86
+
zlib
+
];
+
defaultBins = optionals enableDefaults [ graphviz ];
+
runtimeLibs =
+
defaultLibs
+
++ extraLibs
+
++ binPackages
+
++ (lib.flatten (map (v: v.extraLibs or [ ]) extraVocabs))
+
++ optionals guiSupport [
+
cairo
+
freealut
+
gdk-pixbuf
+
glib
+
gnome2.gtkglext
+
gtk2-x11
+
libGL
+
libGLU
+
pango
+
];
+
bins = binPackages ++ defaultBins ++ (lib.flatten (map (v: v.extraPaths or [ ]) extraVocabs));
+
vocabTree = buildEnv {
+
name = "${factor-unwrapped.pname}-vocabs";
+
ignoreCollisions = true;
+
pathsToLink = map (r: "/lib/factor/${r}") [
+
"basis"
+
"core"
+
"extra"
+
];
+
paths = [ factor-unwrapped ] ++ extraVocabs;
+
};
+
+
in
+
stdenv.mkDerivation (finalAttrs: {
+
pname = "${factor-unwrapped.pname}-env";
+
inherit (factor-unwrapped) version;
+
+
nativeBuildInputs = [ makeWrapper ];
+
buildInputs = optional guiSupport gdk-pixbuf;
+
+
dontUnpack = true;
+
+
installPhase =
+
''
+
runHook preInstall
+
''
+
+ optionalString guiSupport ''
+
# Set Gdk pixbuf loaders file to the one from the build dependencies here
+
unset GDK_PIXBUF_MODULE_FILE
+
# Defined in gdk-pixbuf setup hook
+
findGdkPixbufLoaders "${librsvg}"
+
makeWrapperArgs+=(--set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE")
+
''
+
+ ''
+
makeWrapperArgs+=(
+
--prefix LD_LIBRARY_PATH : /run/opengl-driver/lib:${lib.makeLibraryPath runtimeLibs}
+
--prefix PATH : ${lib.makeBinPath bins})
+
mkdir -p "$out/bin" "$out/share"
+
cp -r "${factor-unwrapped}/lib" "$out/"
+
cp -r "${factor-unwrapped}/share/emacs" "$out/share/"
+
chmod -R u+w "$out/lib" "$out/share"
+
(
+
cd ${vocabTree}
+
for f in "lib/factor/"* ; do
+
rm -r "$out/$f"
+
ln -s "${vocabTree}/$f" "$out/$f"
+
done
+
)
+
+
# There is no ld.so.cache in NixOS so we construct one
+
# out of known libraries. The side effect is that find-lib
+
# will work only on the known libraries. There does not seem
+
# to be a generic solution here.
+
find $(echo ${
+
lib.makeLibraryPath ([ stdenv.cc.libc ] ++ runtimeLibs)
+
} | sed -e 's#:# #g') -name \*.so.\* > $TMPDIR/so.lst
+
(echo $(cat $TMPDIR/so.lst | wc -l) "libs found in cache \`/etc/ld.so.cache'";
+
for l in $(<$TMPDIR/so.lst); do
+
echo " $(basename $l) (libc6,x86-64) => $l";
+
done)> $out/lib/factor/ld.so.cache
+
+
# Create a wrapper in bin/ and lib/factor/
+
wrapProgram "$out/lib/factor/factor" \
+
--argv0 factor \
+
--set FACTOR_LD_SO_CACHE "$out/lib/factor/ld.so.cache" \
+
"''${makeWrapperArgs[@]}"
+
mv $out/lib/factor/factor.image $out/lib/factor/.factor-wrapped.image
+
cp $out/lib/factor/factor $out/bin/
+
+
# Emacs fuel expects the image being named `factor.image` in the factor base dir
+
ln -rs $out/lib/factor/.factor-wrapped.image $out/lib/factor/factor.image
+
+
# Update default paths in fuel-listener.el to new output
+
sed -E -i -e 's#(\(defcustom fuel-factor-root-dir ").*(")#'"\1$out/lib/factor\2#" \
+
"$out/share/emacs/site-lisp/fuel-listener.el"
+
runHook postInstall
+
'';
+
+
inherit doInstallCheck;
+
disabledTests = toFactorArgs [
+
"io.files.info.unix"
+
"io.launcher.unix"
+
"io.ports"
+
"io.sockets"
+
"io.sockets.unix"
+
"io.sockets.secure.openssl"
+
"io.sockets.secure.unix"
+
];
+
installCheckPhase = ''
+
runHook preCheck
+
export HOME=$TMPDIR
+
$out/bin/factor -e='USING: tools.test tools.test.private
+
zealot.factor sequences namespaces formatting ;
+
zealot-core-vocabs
+
{ ${finalAttrs.disabledTests} } without
+
"compiler" suffix
+
[ test-vocab ] each :test-failures
+
test-failures get length "Number of failed tests: %d\n" printf'
+
runHook postCheck
+
'';
+
+
passthru = {
+
inherit
+
defaultLibs
+
defaultBins
+
extraLibs
+
runtimeLibs
+
binPackages
+
extraVocabs
+
;
+
};
+
+
meta = factor-unwrapped.meta // {
+
mainProgram = "factor";
+
};
+
})
+26
pkgs/development/factor-vocabs/bresenham/default.nix
···
+
{
+
lib,
+
factorPackages,
+
fetchFromGitHub,
+
curl,
+
gnutls,
+
}:
+
+
factorPackages.buildFactorVocab {
+
pname = "bresenham";
+
version = "dev";
+
+
src = fetchFromGitHub {
+
owner = "Capital-EX";
+
repo = "bresenham";
+
rev = "58d76b31a17f547e19597a09d02d46a742bf6808";
+
hash = "sha256-cfQOlB877sofxo29ahlRHVpN3wYTUc/rFr9CJ89dsME=";
+
};
+
+
meta = {
+
description = "Bresenham's line interpolation algorithm";
+
homepage = "https://github.com/Capital-EX/bresenham";
+
license = lib.licenses.bsd2;
+
maintainers = with lib.maintainers; [ spacefrogg ];
+
};
+
}
+1
pkgs/top-level/aliases.nix
···
### F ###
+
factor-lang-scope = throw "'factor-lang-scope' has been renamed to 'factorPackages'"; # added 2024-11-28
fahcontrol = throw "fahcontrol has been removed because the download is no longer available"; # added 2024-09-24
fahviewer = throw "fahviewer has been removed because the download is no longer available"; # added 2024-09-24
fam = throw "'fam' (aliased to 'gamin') has been removed as it is unmaintained upstream"; # Added 2024-04-19
+2 -2
pkgs/top-level/all-packages.nix
···
inherit (darwin.apple_sdk.frameworks) Carbon OpenGL;
};
-
factor-lang-scope = callPackage ../development/compilers/factor-lang/scope.nix { };
-
factor-lang = factor-lang-scope.interpreter;
+
factorPackages = callPackage ./factor-packages.nix { };
+
factor-lang = factorPackages.factor-lang;
far2l = callPackage ../applications/misc/far2l {
inherit (darwin.apple_sdk.frameworks)
+43
pkgs/top-level/factor-packages.nix
···
+
{
+
lib,
+
pkgs,
+
overrides ? (self: super: { }),
+
}:
+
+
let
+
inside =
+
self:
+
let
+
callPackage = pkgs.newScope self;
+
in
+
lib.recurseIntoAttrs {
+
+
buildFactorApplication =
+
callPackage ../development/compilers/factor-lang/mk-factor-application.nix
+
{ };
+
buildFactorVocab = callPackage ../development/compilers/factor-lang/mk-vocab.nix { };
+
+
factor-unwrapped = callPackage ../development/compilers/factor-lang/unwrapped.nix { };
+
+
factor-lang = callPackage ../development/compilers/factor-lang/wrapper.nix { };
+
factor-no-gui = callPackage ../development/compilers/factor-lang/wrapper.nix {
+
guiSupport = false;
+
};
+
factor-minimal = callPackage ../development/compilers/factor-lang/wrapper.nix {
+
enableDefaults = false;
+
guiSupport = false;
+
};
+
factor-minimal-gui = callPackage ../development/compilers/factor-lang/wrapper.nix {
+
enableDefaults = false;
+
};
+
+
# Vocabularies
+
bresenham = callPackage ../development/factor-vocabs/bresenham { };
+
+
}
+
// lib.optionalAttrs pkgs.config.allowAliases {
+
interpreter = builtins.throw "factorPackages now offers various wrapped factor runtimes (see documentation) and the buildFactorApplication helper.";
+
};
+
extensible-self = lib.makeExtensible (lib.extends overrides inside);
+
in
+
extensible-self