nix可以帮我们构建一个静态编译环境,我们选定一个特定的版本,这个版本可以从 postgrest 这个应用里面获取。
我们建立 nix
目录,新建 nix/nix/nixpkgs-version.nix
, 内容如下:
{
date = "2020-12-22";
rev = "2a058487cb7a50e7650f1657ee0151a19c59ec3b";
tarballHash = "1h8c0mk6jlxdmjqch6ckj30pax3hqh6kwjlvp2021x3z4pdzrn9p";
}
我们要使用 static-haskell-nix 来帮我们搞定各个软件包静态编译的处理。
我们新建 nix/static-haskell-package.nix
, 内容如下:
# Derive a fully static Haskell package based on musl instead of glibc.
{ nixpkgs, compiler, allOverlays }:
name: src:
let
# The nh2/static-haskell-nix project does all the hard work for us.
static-haskell-nix =
let
rev = "749707fc90b781c3e653e67917a7d571fe82ae7b";
in
builtins.fetchTarball {
url = "https://github.com/nh2/static-haskell-nix/archive/${rev}.tar.gz";
sha256 = "155spda2lww378bhx68w6dxwqd5y6s9kin3qbgl2m23r3vmk3m3w";
};
extraOverrides =
final: prev:
rec {
# We need to add our package needs to the package set that we pass to
# static-haskell-nix. Using callCabal2nix on the haskellPackages that
# it returns would result in a dynamic build based on musl, and not the
# fully static build that we want.
"${name}" =
prev.callCabal2nix name src { };
};
overlays =
[
(allOverlays.haskell-packages { inherit compiler extraOverrides; })
];
# Apply our overlay to the given pkgs.
normalPkgs =
import nixpkgs { inherit overlays; };
# Each version of GHC needs a specific version of Cabal.
defaultCabalPackageVersionComingWithGhc =
{
ghc884 = "Cabal_3_2_1_0";
}."${compiler}";
# The static-haskell-nix 'survey' derives a full static set of Haskell
# packages, applying fixes where necessary.
survey =
import "${static-haskell-nix}/survey" { inherit normalPkgs compiler defaultCabalPackageVersionComingWithGhc; };
in
survey.haskellPackages."${name}"
将要编译的软件包和自定义库添加到 static-haskell-nix/survey 里面,
我们添加 overlays 库,定义我们要用到的软件包
新建目录 nix/overlays
添加文件 nix/overlays/haskell-packages.nix
内容如下:
{ compiler, extraOverrides ? (final: prev: { }) }:
self: super:
let
lib =
self.haskell.lib;
overrides =
final: prev:
rec {
# To pin custom versions of Haskell packages:
# protolude =
# prev.callHackageDirect
# {
# pkg = "protolude";
# ver = "0.3.0";
# sha256 = "0iwh4wsjhb7pms88lw1afhdal9f86nrrkkvv65f9wxbd1b159n72";
# }
# { };
#
# To get the sha256:
# nix-prefetch-url --unpack https://hackage.haskell.org/package/protolude-0.3.0/protolude-0.3.0.tar.gz
ptr =
lib.dontCheck (lib.unmarkBroken prev.ptr);
} // extraOverrides final prev;
in
{
haskell =
super.haskell // {
packages = super.haskell.packages // {
"${compiler}" =
super.haskell.packages."${compiler}".override { inherit overrides; };
};
};
}
添加文件nix/overlays/gitignore.nix
内容如下:
self: super:
# Overlay that adds the `gitignoreSource` function from Hercules-CI.
# This function is useful for filtering which files are added to the Nix store.
# See: https://github.com/hercules-ci/gitignore.nix
# To update to a newer revision, the simplest way is to add a new commit hash
# from GitHub under `rev` and to then add the hash that Nix suggests on first
# use.
{
gitignoreSource =
let
gitignoreSrc = super.fetchFromGitHub {
owner = "hercules-ci";
repo = "gitignore";
rev = "c4662e662462e7bf3c2a968483478a665d00e717";
sha256 = "1npnx0h6bd0d7ql93ka7azhj40zgjp815fw2r6smg8ch9p7mzdlx";
};
in
(super.callPackage gitignoreSrc { }).gitignoreSource;
}
添加文件nix/overlays/default.nix
内容如下:
{
gitignore = import ./gitignore.nix;
haskell-packages = import ./haskell-packages.nix;
}
添加 release.nix
内容如下:
let
# We are using lts-15.13 stack resolver which uses ghc883 (cf https://www.stackage.org/lts-15.13)
compiler = "ghc884";
# pin nixpkgs for reproducible build
nixpkgsVersion = import nix/nixpkgs-version.nix;
nixpkgs =
builtins.fetchTarball {
url = "https://github.com/nixos/nixpkgs/archive/${nixpkgsVersion.rev}.tar.gz";
sha256 = nixpkgsVersion.tarballHash;
};
# overlays define packages we need to build our project
allOverlays = import nix/overlays;
overlays = [
allOverlays.gitignore # helper to use gitignoreSource
(allOverlays.haskell-packages { inherit compiler; })
];
pkgs = import nixpkgs { inherit overlays; };
# We define our packages by giving them names and a list of source files
youpkg = {
name = "youpkg";
src = pkgs.lib.sourceFilesBySuffices (pkgs.gitignoreSource ./.)[ ".cabal" ".hs" "LICENSE" ];
};
# Some patches are unfortunately necessary to work with libpq
patches = pkgs.callPackage nix/patches {};
lib = pkgs.haskell.lib;
# call our script which add our packages to nh2/static-haskell-nix project
staticHaskellPackage = import nix/static-haskell-package.nix { inherit nixpkgs compiler patches allOverlays; } ;
in
rec {
inherit nixpkgs pkgs;
# if instead we want to generated a fully static executable we need:
haskell-hole-static = lib.justStaticExecutables (lib.dontCheck staticHaskellPackage youpkg.name youpkg.src);
}
最后我们通过 nix-build release.nix
来编译,最终完成静态编译。
网友评论