Ответ 1
В наши дни я делаю все свое развитие, используя Nix и cabal, и я могу с радостью сказать, что они работают в гармонии очень хорошо. Мой текущий рабочий процесс очень новый, поскольку он полагается на функции в nixpkgs
, которые только что достигли главной ветки. Таким образом, первое, что вам нужно сделать, это clone nixpkgs
от Github:
cd ~
git clone git://github.com/nixos/nixpkgs
(В будущем это не понадобится, но прямо сейчас).
Использование одного проекта
Теперь, когда у нас есть клон nixpkgs
, мы можем начать использовать набор пакетов haskellng
. haskellng
- это переписывание того, как мы упаковываем вещи в Nix, и представляет интерес для нас, чтобы быть более предсказуемым (имена пакетов соответствуют именам пакетов Hackage) и более настраиваемыми. Сначала мы установим инструмент cabal2nix
, который может автоматизировать некоторые вещи для нас, и мы также установим cabal-install
для обеспечения исполняемого файла cabal
:
nix-env -f ~/nixpkgs -i -A haskellngPackages.cabal2nix -A haskellngPackages.cabal-install
С этого момента все это довольно ясно проплывает.
Если вы начинаете новый проект, вы можете просто вызвать cabal init
в новом каталоге, как обычно. Когда вы будете готовы к созданию, вы можете превратить этот файл .cabal
в среду разработки:
cabal init
# answer the questions
cabal2nix --shell my-project.cabal > shell.nix
Это дает вам файл shell.nix
, который можно использовать с nix-shell
. Вам не нужно использовать это очень часто, но - единственный раз, когда вы обычно используете его с помощью cabal configure
:
nix-shell -I ~ --command 'cabal configure'
cabal configure
кэширует абсолютные пути ко всему, поэтому теперь, когда вы хотите построить, вы просто используете cabal build
как обычно:
cabal build
Всякий раз, когда ваш файл .cabal
изменяется, вам необходимо восстановить shell.nix
- просто запустите команду выше, а затем cabal configure
после.
Использование нескольких проектов
Подход хорошо подходит для нескольких проектов, но для этого требуется немного более ручная работа, чтобы "склеить" все вместе. Чтобы продемонстрировать, как это работает, рассмотрим мою библиотеку socket-io
. Эта библиотека зависит от engine-io
, и я обычно разрабатываю оба одновременно.
Первым шагом для Nix-ifying этого проекта является генерация выражений default.nix
вдоль каждого отдельного файла .cabal
:
cabal2nix engine-io/engine-io.cabal > engine-io/default.nix
cabal2nix socket-io/socket-io.cabal > socket-io/default.nix
Эти выражения default.nix
являются функциями, поэтому мы не можем делать многое прямо сейчас. Чтобы вызвать функции, мы пишем наш собственный файл shell.nix
, в котором объясняется, как объединить все. Для engine-io/shell.nix
нам не нужно делать ничего особенно умного:
with (import <nixpkgs> {}).pkgs;
(haskellngPackages.callPackage ./. {}).env
Для socket-io
нам нужно зависеть от engine-io
:
with (import <nixpkgs> {}).pkgs;
let modifiedHaskellPackages = haskellngPackages.override {
overrides = self: super: {
engine-io = self.callPackage ../engine-io {};
socket-io = self.callPackage ./. {};
};
};
in modifiedHaskellPackages.socket-io.env
Теперь у нас есть shell.nix
в каждой среде, поэтому мы можем использовать cabal configure
, как и раньше.
Основное замечание здесь состоит в том, что всякий раз, когда engine-io
изменяется, нам нужно перенастроить socket-io
, чтобы обнаружить эти изменения. Это так же просто, как запуск
cd socket-io; nix-shell -I ~ --command 'cabal configure'
Nix заметит, что ../engine-io
изменился и перестроит его перед запуском cabal configure
.