2017-04-17 3 views
5

Je me suis intéressé à Nix pendant un moment, et j'ai pensé que j'essaierais finalement de l'utiliser pour démarrer un nouveau projet haskell.Construire une bibliothèque haskell simple en utilisant nix

j'ai commencé avec la structure de répertoire

project.cabal 
src/Lib.hs 

Lorsque le fichier cabale a le contenu suivant:

name: project 
version: 0.1.0.0 
build-type: Simple 
license: MIT 
cabal-version: >= 1.18 

library 
    exposed-modules: Lib 
    build-depends: base < 5 
    hs-source-dirs: src 
    default-language: Haskell2010 

et Lib.hs a

module Lib where 

hello :: Int -> IO() 
hello x = putStrLn (show x) 

Comme vous pouvez le voir, c'est assez simple. Quand j'exécute cabal build, il semble être heureux. Notez que je ne suis pas un expert en haskell, donc je fais peut-être une erreur de débutant ici.

Pour construire cela avec Nix, j'ai lu https://github.com/Gabriel439/haskell-nix pour obtenir mes informations. J'ai exécuté cabal2nix . > default.nix pour obtenir une version Nix de mon fichier cabal. J'ai ensuite créé un fichier release.nix pour le construire. Le contenu des deux fichiers sont les suivants:

default.nix

{ mkDerivation, base, stdenv }: 
mkDerivation { 
    pname = "project"; 
    version = "0.1.0.0"; 
    src = ./.; 
    libraryHaskellDepends = [ base ]; 
    license = stdenv.lib.licenses.mit; 
} 

release.nix

let 
    pkgs = import <nixpkgs> { }; 
in 
    pkgs.haskellPackages.callPackage ./default.nix { } 

Après avoir fait cela, j'exécutais nix-build release.nix et je revins

these derivations will be built: 
    /nix/store/p481alkpm89712n3hnwai0nxhmjrm8b2-project-0.1.0.0.drv 
building path(s) ‘/nix/store/yszy2a6wd88pf6zlw0nw99l5wzvc0s9x-project-0.1.0.0’ 
setupCompilerEnvironmentPhase 
Build with /nix/store/d5w12a8bprd2518xnqp1cwh3rbjiagyx-ghc-8.0.1. 
unpacking sources 
unpacking source archive /nix/store/fsn4b9w54h2jdpv546nwvy82vnkszl1w-project 
source root is project 
patching sources 
compileBuildDriverPhase 
setupCompileFlags: -package-db=/tmp/nix-build-project-0.1.0.0.drv-0/package.conf.d -j4 -threaded 
[1 of 1] Compiling Main    (/nix/store/4mdp8nhyfddh7bllbi7xszz7k9955n79-Setup.hs, /tmp/nix-build-project-0.1.0.0.drv-0/Main.o) 
Linking Setup ... 
... 
... 
Building project-0.1.0.0... 
Preprocessing library project-0.1.0.0... 
dist/build/Lib_o_split: getDirectoryContents: does not exist (No such file or 
directory) 
builder for ‘/nix/store/p481alkpm89712n3hnwai0nxhmjrm8b2-project-0.1.0.0.drv’ failed with exit code 1 
error: build of ‘/nix/store/p481alkpm89712n3hnwai0nxhmjrm8b2-project-0.1.0.0.drv’ failed 

Ce qui bien sûr n'est pas bon. Quelle erreur fais-je ici? J'ai réussi dans une tentative similaire qui consistait à construire un exécutable au lieu d'une bibliothèque, donc je suppose que cela a quelque chose à voir avec ça. Le repo de github que je suivais utilisait aussi un exécutable.

+0

Coup de feu dans l'obscurité mais ajoute "enableSplitObjs = false;" à votre fichier default.nix? Si ces erreurs avec 'error: assertion échouent à ....., pourriez-vous essayer' enableDeadCodeElimination = false; 'à la place? – ppb

+0

@ppb 'enableSplitObjs = false;' l'a fait se construire correctement. Pourquoi est-ce que ça arrange les choses? Y a-t-il un endroit où toutes les options de haskell nix sont documentées? Aussi, si vous faites une réponse, je l'accepterai. – phil

Répondre

0

Je crois par Nix par défaut, contrairement à la cabale ordinaire, va essayer de construire un projet Haskell utilisant des objets fractionnés fonction, per cabal's manual:

--enable-split-objs

Use the GHC -split-objs feature when building the library. This reduces the final size of the executables that use the library by allowing them to link with only the bits that they use rather than the entire library. The downside is that building the library takes longer and uses considerably more memory.

Je ne suis pas trop sûr de savoir pourquoi cela peut être défaillant sur système, mais en fonction de votre version nixpkgs peut être désactivé en ajoutant un de:

enableSplitObjs = false;

enableDeadCodeElimination = false;

à la dérivation.

Pour une liste d'autres attributs/options, vous pouvez vous référer à https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/generic-builder.nix Malheureusement, je ne connais pas de documentation officielle décrivant ces plus en détail.