forked from mirrors/nixpkgs
agda: rework builder
This commit is contained in:
parent
6cbaa256fa
commit
d30e2468e0
96
doc/languages-frameworks/agda.section.md
Normal file
96
doc/languages-frameworks/agda.section.md
Normal file
|
@ -0,0 +1,96 @@
|
|||
---
|
||||
title: Agda
|
||||
author: Alex Rice (alexarice)
|
||||
date: 2020-01-06
|
||||
---
|
||||
# Agda
|
||||
|
||||
## How to use Agda
|
||||
|
||||
Agda can be installed from `agda`:
|
||||
```
|
||||
$ nix-env -iA agda
|
||||
```
|
||||
|
||||
To use agda with libraries, the `agda.withPackages` function can be used. This function either takes:
|
||||
+ A list of packages,
|
||||
+ or a function which returns a list of packages when given the `agdaPackages` attribute set,
|
||||
+ or an attribute set containing a list of packages and a GHC derivation for compilation (see below).
|
||||
|
||||
For example, suppose we wanted a version of agda which has access to the standard library. This can be obtained with the expressions:
|
||||
|
||||
```
|
||||
agda.withPackages [ agdaPackages.standard-library ]
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
agda.withPackages (p: [ p.standard-library ])
|
||||
```
|
||||
|
||||
or can be called as in the [Compiling Agda](#compiling-agda) section.
|
||||
|
||||
If you want to use a library in your home directory (for instance if it is a development version) then typecheck it manually (using `agda.withPackages` if necessary) and then override the `src` attribute of the package to point to your local repository.
|
||||
|
||||
Agda will not by default use these libraries. To tell agda to use the library we have some options:
|
||||
- Call `agda` with the library flag:
|
||||
```
|
||||
$ agda -l standard-library -i . MyFile.agda
|
||||
```
|
||||
- Write a `my-library.agda-lib` file for the project you are working on which may look like:
|
||||
```
|
||||
name: my-library
|
||||
include: .
|
||||
depends: standard-library
|
||||
```
|
||||
- Create the file `~/.agda/defaults` and add any libraries you want to use by default.
|
||||
|
||||
More information can be found in the [official Agda documentation on library management](https://agda.readthedocs.io/en/v2.6.1/tools/package-system.html).
|
||||
|
||||
## Compiling Agda
|
||||
Agda modules can be compiled with the `--compile` flag. A version of `ghc` with `ieee` is made available to the Agda program via the `--with-compiler` flag.
|
||||
This can be overridden by a different version of `ghc` as follows:
|
||||
|
||||
```
|
||||
agda.withPackages {
|
||||
pkgs = [ ... ];
|
||||
ghc = haskell.compiler.ghcHEAD;
|
||||
}
|
||||
```
|
||||
|
||||
## Writing Agda packages
|
||||
To write a nix derivation for an agda library, first check that the library has a `*.agda-lib` file.
|
||||
|
||||
A derivation can then be written using `agdaPackages.mkDerivation`. This has similar arguments to `stdenv.mkDerivation` with the following additions:
|
||||
+ `everythingFile` can be used to specify the location of the `Everything.agda` file, defaulting to `./Everything.agda`. If this file does not exist then either it should be patched in or the `buildPhase` should be overridden (see below).
|
||||
+ `libraryName` should be the name that appears in the `*.agda-lib` file, defaulting to `pname`.
|
||||
+ `libraryFile` should be the file name of the `*.agda-lib` file, defaulting to `${libraryName}.agda-lib`.
|
||||
|
||||
The build phase for `agdaPackages.mkDerivation` simply runs `agda` on the `Everything.agda` file. If something else is needed to build the package (e.g. `make`) then the `buildPhase` should be overridden (or a `preBuild` or `configurePhase` can be used if there are steps that need to be done prior to checking the `Everything.agda` file). `agda` and the Agda libraries contained in `buildInputs` are made available during the build phase. The install phase simply copies all `.agda`, `.agdai` and `.agda-lib` files to the output directory. Again, this can be overridden.
|
||||
|
||||
To add an agda package to `nixpkgs`, the derivation should be written to `pkgs/development/libraries/agda/${library-name}/` and an entry should be added to `pkgs/top-level/agda-packages.nix`. Here it is called in a scope with access to all other agda libraries, so the top line of the `default.nix` can look like:
|
||||
```
|
||||
{ mkDerivation, standard-library, fetchFromGitHub }:
|
||||
```
|
||||
and `mkDerivation` should be called instead of `agdaPackages.mkDerivation`. Here is an example skeleton derivation for iowa-stdlib:
|
||||
|
||||
```
|
||||
mkDerivation {
|
||||
version = "1.5.0";
|
||||
pname = "iowa-stdlib";
|
||||
|
||||
src = ...
|
||||
|
||||
libraryFile = "";
|
||||
libraryName = "IAL-1.3";
|
||||
|
||||
buildPhase = ''
|
||||
patchShebangs find-deps.sh
|
||||
make
|
||||
'';
|
||||
}
|
||||
```
|
||||
This library has a file called `.agda-lib`, and so we give an empty string to `libraryFile` as nothing precedes `.agda-lib` in the filename. This file contains `name: IAL-1.3`, and so we let `libraryName = "IAL-1.3"`. This library does not use an `Everything.agda` file and instead has a Makefile, so there is no need to set `everythingFile` and we set a custom `buildPhase`.
|
||||
|
||||
When writing an agda package it is essential to make sure that no `.agda-lib` file gets added to the store as a single file (for example by using `writeText`). This causes agda to think that the nix store is a agda library and it will attempt to write to it whenever it typechecks something. See [https://github.com/agda/agda/issues/4613](https://github.com/agda/agda/issues/4613).
|
|
@ -5,6 +5,7 @@
|
|||
<para>
|
||||
The <link linkend="chap-stdenv">standard build environment</link> makes it easy to build typical Autotools-based packages with very little code. Any other kind of package can be accomodated by overriding the appropriate phases of <literal>stdenv</literal>. However, there are specialised functions in Nixpkgs to easily build packages for other programming languages, such as Perl or Haskell. These are described in this chapter.
|
||||
</para>
|
||||
<xi:include href="agda.section.xml" />
|
||||
<xi:include href="android.section.xml" />
|
||||
<xi:include href="beam.xml" />
|
||||
<xi:include href="bower.xml" />
|
||||
|
|
|
@ -1,90 +1,71 @@
|
|||
# Builder for Agda packages. Mostly inspired by the cabal builder.
|
||||
# Builder for Agda packages.
|
||||
|
||||
{ stdenv, Agda, glibcLocales
|
||||
, writeShellScriptBin
|
||||
, extension ? (self: super: {})
|
||||
}:
|
||||
{ stdenv, lib, self, Agda, runCommandNoCC, makeWrapper, writeText, mkShell, ghcWithPackages }:
|
||||
|
||||
with stdenv.lib.strings;
|
||||
with lib.strings;
|
||||
|
||||
let
|
||||
defaults = self : {
|
||||
# There is no Hackage for Agda so we require src.
|
||||
inherit (self) src name;
|
||||
|
||||
isAgdaPackage = true;
|
||||
|
||||
buildInputs = [ Agda ] ++ self.buildDepends;
|
||||
buildDepends = [];
|
||||
|
||||
buildDependsAgda = stdenv.lib.filter
|
||||
(dep: dep ? isAgdaPackage && dep.isAgdaPackage)
|
||||
self.buildDepends;
|
||||
buildDependsAgdaShareAgda = map (x: x + "/share/agda") self.buildDependsAgda;
|
||||
|
||||
# Not much choice here ;)
|
||||
LANG = "en_US.UTF-8";
|
||||
LOCALE_ARCHIVE = stdenv.lib.optionalString
|
||||
stdenv.isLinux
|
||||
"${glibcLocales}/lib/locale/locale-archive";
|
||||
|
||||
everythingFile = "Everything.agda";
|
||||
|
||||
propagatedBuildInputs = self.buildDependsAgda;
|
||||
propagatedUserEnvPkgs = self.buildDependsAgda;
|
||||
|
||||
# Immediate source directories under which modules can be found.
|
||||
sourceDirectories = [ ];
|
||||
|
||||
# This is used if we have a top-level element that only serves
|
||||
# as the container for the source and we only care about its
|
||||
# contents. The directories put here will have their
|
||||
# *contents* copied over as opposed to sourceDirectories which
|
||||
# would make a direct copy of the whole thing.
|
||||
topSourceDirectories = [ "src" ];
|
||||
|
||||
# FIXME: `dirOf self.everythingFile` is what we really want, not hardcoded "./"
|
||||
includeDirs = self.buildDependsAgdaShareAgda
|
||||
++ self.sourceDirectories ++ self.topSourceDirectories
|
||||
++ [ "." ];
|
||||
buildFlags = stdenv.lib.concatMap (x: ["-i" x]) self.includeDirs;
|
||||
|
||||
agdaWithArgs = "${Agda}/bin/agda ${toString self.buildFlags}";
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
${self.agdaWithArgs} ${self.everythingFile}
|
||||
runHook postBuild
|
||||
withPackages' = {
|
||||
pkgs,
|
||||
ghc ? ghcWithPackages (p: with p; [ ieee ])
|
||||
}: let
|
||||
pkgs' = if builtins.isList pkgs then pkgs else pkgs self;
|
||||
library-file = writeText "libraries" ''
|
||||
${(concatMapStringsSep "\n" (p: "${p}/${p.libraryFile}") pkgs')}
|
||||
'';
|
||||
pname = "agdaWithPackages";
|
||||
version = Agda.version;
|
||||
in runCommandNoCC "${pname}-${version}" {
|
||||
inherit pname version;
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
passthru.unwrapped = Agda;
|
||||
} ''
|
||||
mkdir -p $out/bin
|
||||
makeWrapper ${Agda}/bin/agda $out/bin/agda \
|
||||
--add-flags "--with-compiler=${ghc}/bin/ghc" \
|
||||
--add-flags "--library-file=${library-file}" \
|
||||
--add-flags "--local-interfaces"
|
||||
makeWrapper ${Agda}/bin/agda-mode $out/bin/agda-mode
|
||||
''; # Local interfaces has been added for now: See https://github.com/agda/agda/issues/4526
|
||||
|
||||
installPhase = let
|
||||
srcFiles = self.sourceDirectories
|
||||
++ map (x: x + "/*") self.topSourceDirectories;
|
||||
in ''
|
||||
runHook preInstall
|
||||
mkdir -p $out/share/agda
|
||||
cp -pR ${concatStringsSep " " srcFiles} $out/share/agda
|
||||
runHook postInstall
|
||||
'';
|
||||
withPackages = arg: if builtins.isAttrs arg then withPackages' arg else withPackages' { pkgs = arg; };
|
||||
|
||||
passthru = {
|
||||
env = stdenv.mkDerivation {
|
||||
name = "interactive-${self.name}";
|
||||
inherit (self) LANG LOCALE_ARCHIVE;
|
||||
AGDA_PACKAGE_PATH = concatMapStrings (x: x + ":") self.buildDependsAgdaShareAgda;
|
||||
buildInputs = let
|
||||
# Makes a wrapper available to the user. Very useful in
|
||||
# nix-shell where all dependencies are -i'd.
|
||||
agdaWrapper = writeShellScriptBin "agda" ''
|
||||
exec ${self.agdaWithArgs} "$@"
|
||||
'';
|
||||
in [agdaWrapper] ++ self.buildDepends;
|
||||
|
||||
defaults =
|
||||
{ pname
|
||||
, buildInputs ? []
|
||||
, everythingFile ? "./Everything.agda"
|
||||
, libraryName ? pname
|
||||
, libraryFile ? "${libraryName}.agda-lib"
|
||||
, buildPhase ? null
|
||||
, installPhase ? null
|
||||
, ...
|
||||
}: let
|
||||
agdaWithArgs = withPackages (builtins.filter (p: p ? isAgdaDerivation) buildInputs);
|
||||
in
|
||||
{
|
||||
inherit libraryName libraryFile;
|
||||
|
||||
isAgdaDerivation = true;
|
||||
|
||||
buildInputs = buildInputs ++ [ agdaWithArgs ];
|
||||
|
||||
buildPhase = if buildPhase != null then buildPhase else ''
|
||||
runHook preBuild
|
||||
agda -i ${dirOf everythingFile} ${everythingFile}
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase = if installPhase != null then installPhase else ''
|
||||
runHook preInstall
|
||||
mkdir -p $out
|
||||
find \( -name '*.agda' -or -name '*.agdai' -or -name '*.agda-lib' \) -exec cp -p --parents -t "$out" {} +
|
||||
runHook postInstall
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{ mkDerivation = args: let
|
||||
super = defaults self // args self;
|
||||
self = super // extension self super;
|
||||
in stdenv.mkDerivation self;
|
||||
{
|
||||
mkDerivation = args: stdenv.mkDerivation (args // defaults args);
|
||||
|
||||
inherit withPackages withPackages';
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
{ stdenv, agda, fetchgit }:
|
||||
{ stdenv, mkDerivation, fetchFromGitHub }:
|
||||
|
||||
agda.mkDerivation (self: rec {
|
||||
mkDerivation rec {
|
||||
version = "eacc961c2c312b7443109a7872f99d55557df317";
|
||||
name = "agda-prelude-${version}";
|
||||
pname = "agda-prelude";
|
||||
|
||||
src = fetchgit {
|
||||
url = "https://github.com/UlfNorell/agda-prelude.git";
|
||||
src = fetchFromGitHub {
|
||||
owner = "UlfNorell";
|
||||
repo = "agda-prelude";
|
||||
rev = version;
|
||||
sha256 = "0iql67hb1q0fn8dwkcx07brkdkxqfqrsbwjy71ndir0k7qzw7qv2";
|
||||
};
|
||||
|
||||
topSourceDirectories = [ "src" ];
|
||||
everythingFile = "src/Prelude.agda";
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
|
@ -18,6 +18,6 @@ agda.mkDerivation (self: rec {
|
|||
description = "Programming library for Agda";
|
||||
license = stdenv.lib.licenses.mit;
|
||||
platforms = stdenv.lib.platforms.unix;
|
||||
maintainers = with maintainers; [ mudri ];
|
||||
maintainers = with maintainers; [ mudri alexarice ];
|
||||
};
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{ stdenv, agda, fetchFromGitHub }:
|
||||
{ stdenv, mkDerivation, fetchFromGitHub }:
|
||||
|
||||
agda.mkDerivation (self: rec {
|
||||
mkDerivation (rec {
|
||||
version = "1.5.0";
|
||||
name = "agda-iowa-stdlib-${version}";
|
||||
pname = "iowa-stdlib";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "cedille";
|
||||
|
@ -11,7 +11,9 @@ agda.mkDerivation (self: rec {
|
|||
sha256 = "0dlis6v6nzbscf713cmwlx8h9n2gxghci8y21qak3hp18gkxdp0g";
|
||||
};
|
||||
|
||||
sourceDirectories = [ "./." ];
|
||||
libraryFile = "";
|
||||
libraryName = "IAL-1.3";
|
||||
|
||||
buildPhase = ''
|
||||
patchShebangs find-deps.sh
|
||||
make
|
||||
|
@ -22,6 +24,6 @@ agda.mkDerivation (self: rec {
|
|||
description = "Agda standard library developed at Iowa";
|
||||
license = stdenv.lib.licenses.free;
|
||||
platforms = stdenv.lib.platforms.unix;
|
||||
maintainers = with stdenv.lib.maintainers; [ ];
|
||||
maintainers = with stdenv.lib.maintainers; [ alexarice ];
|
||||
};
|
||||
})
|
|
@ -1,8 +1,8 @@
|
|||
{ stdenv, agda, fetchFromGitHub, ghcWithPackages }:
|
||||
{ stdenv, mkDerivation, fetchFromGitHub, ghcWithPackages }:
|
||||
|
||||
agda.mkDerivation (self: rec {
|
||||
mkDerivation rec {
|
||||
pname = "standard-library";
|
||||
version = "1.1";
|
||||
name = "agda-stdlib-${version}";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
repo = "agda-stdlib";
|
||||
|
@ -16,13 +16,11 @@ agda.mkDerivation (self: rec {
|
|||
runhaskell GenerateEverything.hs
|
||||
'';
|
||||
|
||||
topSourceDirectories = [ "src" ];
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
homepage = "https://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.StandardLibrary";
|
||||
description = "A standard library for use with the Agda compiler";
|
||||
license = stdenv.lib.licenses.mit;
|
||||
platforms = stdenv.lib.platforms.unix;
|
||||
maintainers = with maintainers; [ jwiegley mudri ];
|
||||
maintainers = with maintainers; [ jwiegley mudri alexarice ];
|
||||
};
|
||||
})
|
||||
}
|
24
pkgs/top-level/agda-packages.nix
Normal file
24
pkgs/top-level/agda-packages.nix
Normal file
|
@ -0,0 +1,24 @@
|
|||
{ pkgs, lib, callPackage, newScope, Agda }:
|
||||
|
||||
let
|
||||
mkAgdaPackages = Agda: lib.makeScope newScope (mkAgdaPackages' Agda);
|
||||
mkAgdaPackages' = Agda: self: let
|
||||
callPackage = self.callPackage;
|
||||
inherit (callPackage ../build-support/agda {
|
||||
inherit Agda self;
|
||||
inherit (pkgs.haskellPackages) ghcWithPackages;
|
||||
}) withPackages mkDerivation;
|
||||
in {
|
||||
inherit mkDerivation;
|
||||
|
||||
agda = withPackages [] // { inherit withPackages; };
|
||||
|
||||
standard-library = callPackage ../development/libraries/agda/standard-library {
|
||||
inherit (pkgs.haskellPackages) ghcWithPackages;
|
||||
};
|
||||
|
||||
iowa-stdlib = callPackage ../development/libraries/agda/iowa-stdlib { };
|
||||
|
||||
agda-prelude = callPackage ../development/libraries/agda/agda-prelude { };
|
||||
};
|
||||
in mkAgdaPackages Agda
|
|
@ -15128,19 +15128,10 @@ in
|
|||
|
||||
### DEVELOPMENT / LIBRARIES / AGDA
|
||||
|
||||
agda = callPackage ../build-support/agda {
|
||||
glibcLocales = if pkgs.stdenv.isLinux then pkgs.glibcLocales else null;
|
||||
extension = self : super : { };
|
||||
agdaPackages = callPackage ./agda-packages.nix {
|
||||
inherit (haskellPackages) Agda;
|
||||
};
|
||||
|
||||
agdaIowaStdlib = callPackage ../development/libraries/agda/agda-iowa-stdlib { };
|
||||
|
||||
agdaPrelude = callPackage ../development/libraries/agda/agda-prelude { };
|
||||
|
||||
AgdaStdlib = callPackage ../development/libraries/agda/agda-stdlib {
|
||||
inherit (haskellPackages) ghcWithPackages;
|
||||
};
|
||||
agda = agdaPackages.agda;
|
||||
|
||||
### DEVELOPMENT / LIBRARIES / JAVA
|
||||
|
||||
|
|
|
@ -181,6 +181,7 @@ let
|
|||
haskell.compiler = packagePlatforms pkgs.haskell.compiler;
|
||||
haskellPackages = packagePlatforms pkgs.haskellPackages;
|
||||
idrisPackages = packagePlatforms pkgs.idrisPackages;
|
||||
agdaPackages = packagePlatforms pkgs.agdaPackages;
|
||||
|
||||
tests = packagePlatforms pkgs.tests;
|
||||
|
||||
|
|
Loading…
Reference in a new issue