diff --git a/README.md b/README.md index 37e7b62ce..522e2bd22 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,28 @@ manually. This will be ignored by git. This should work out of the box with Emacs' `lsp-haskell` package. +### Building with Nix + +[Nix](https://nixos.org/) is a functional package manager and build system. + +To build with vanilla Nix: +```bash +$ nix-build +``` + +To build with flakes-enabled Nix: +```bash +$ nix build .#dex +``` +The resulting `dex` binary should be in `result/bin/dex`. + +For development purposes, you can use a Nix environment with +```bash +$ nix-shell +$ nix develop # With flakes +``` +and use `make` to use Stack to build Dex. + ## Running * Traditional REPL: `dex repl` diff --git a/default.nix b/default.nix new file mode 100644 index 000000000..5e8e8e5ab --- /dev/null +++ b/default.nix @@ -0,0 +1,72 @@ +{ pkgs ? import {}, + llvm-hs-src ? pkgs.fetchFromGitHub { + owner = "llvm-hs"; + repo = "llvm-hs"; + rev = "llvm-12"; + sha256 = "IG4Mh89bY+PtBJtzlXKYsPljfHP7OSQk03pV6fSmdRY="; + }, + cudaPackage ? pkgs.cudaPackages.cudatoolkit_11, + cuda ? false, + optimized ? true, + live ? true, +}: +let + llvm-hs-pure = pkgs.haskellPackages.callCabal2nix "llvm-hs-pure" "${llvm-hs-src}/llvm-hs-pure" { + }; + llvm-hs = (pkgs.haskellPackages.callCabal2nix "llvm-hs" "${llvm-hs-src}/llvm-hs" { + inherit llvm-hs-pure; + }).overrideAttrs (oldAttrs: rec { + buildInputs = oldAttrs.buildInputs ++ [ + pkgs.llvm_12 + ]; + }); + buildFlags = pkgs.lib.optionals optimized [ + "-foptimized" + ] ++ pkgs.lib.optionals live [ + "-flive" + ] ++ pkgs.lib.optionals cuda [ + "-fcuda" + "--extra-include-dirs=${cudaPackage}/include" + "--extra-lib-dirs=${cudaPackage}/lib64/stubs" + ]; + cxxFlags = [ + "-fPIC" + "-std=c++11" + "-fno-exceptions" + "-fno-rtti" + ] ++ pkgs.lib.optional cuda "-DDEX_CUDA" + ++ pkgs.lib.optional live "-DDEX_LIVE"; + buildRuntimeCommand = '' + ${pkgs.clang_9}/bin/clang++ \ + ${builtins.concatStringsSep " " cxxFlags} \ + -c \ + -emit-llvm \ + -I${pkgs.libpng}/include \ + src/lib/dexrt.cpp \ + -o src/lib/dexrt.bc + ''; +in + # `callCabal2nix` converts `dex.cabal` into a Nix file and builds it. + # Before we do the Haskell build though, we need to first compile the Dex runtime + # so it's properly linked in when compiling Dex. Normally the makefile does this, + # so we instead sneak compiling the runtime in the configuration phase for the Haskell build. + (pkgs.haskellPackages.callCabal2nix "dex" ./. { + inherit llvm-hs; + inherit llvm-hs-pure; + }).overrideAttrs (attrs: { + configurePhase = '' + # Compile the Dex runtime + echo 'Compiling the Dex runtime...' + set -x + ${buildRuntimeCommand} + set +x + echo 'Done compiling the Dex runtime.' + + # Run the Haskell configuration phase + ${attrs.configurePhase} + ''; + configureFlags = builtins.concatStringsSep " " buildFlags; + buildInputs = attrs.buildInputs ++ (pkgs.lib.optional cuda + cudaPackage + ); + }) diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..c57af1e71 --- /dev/null +++ b/flake.lock @@ -0,0 +1,59 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1644229661, + "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "llvm-hs-src": { + "flake": false, + "locked": { + "lastModified": 1644009200, + "narHash": "sha256-IG4Mh89bY+PtBJtzlXKYsPljfHP7OSQk03pV6fSmdRY=", + "owner": "llvm-hs", + "repo": "llvm-hs", + "rev": "eda85a2bbe362a0b89df5adce0cb65e4e755eac5", + "type": "github" + }, + "original": { + "owner": "llvm-hs", + "ref": "llvm-12", + "repo": "llvm-hs", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1644151317, + "narHash": "sha256-TpXGBYCFKvEN7Q+To45rn4kqTbLPY4f56rF6ymUGGRE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "942b0817e898262cc6e3f0a5f706ce09d8f749f1", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "llvm-hs-src": "llvm-hs-src", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..374b2c56c --- /dev/null +++ b/flake.nix @@ -0,0 +1,35 @@ +{ + description = "Dex (named for \"index\") is a research language for typed, functional array processing."; + + inputs = { + flake-utils.url = "github:numtide/flake-utils"; + llvm-hs-src = { + url = "github:llvm-hs/llvm-hs/llvm-12"; + flake = false; + }; + }; + + outputs = { self, nixpkgs, flake-utils, llvm-hs-src }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = (import nixpkgs { + inherit system; + config.allowUnfree = true; # Needed for CUDA + }); + in rec { + packages.dex = (pkgs.callPackage ./. { + inherit pkgs; + inherit llvm-hs-src; + }); + packages.dex-cuda = (pkgs.callPackage ./. { + inherit pkgs; + inherit llvm-hs-src; + withCudaSupport = true; + }); + defaultPackage = packages.dex; + + devShell = (import ./shell.nix { + inherit pkgs; + }); + }); + } diff --git a/makefile b/makefile index 715fafd80..c3a7fe56a 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ # Set shell to bash to resolve symbolic links when looking up # executables, to support user-account installation of stack. -SHELL=/bin/bash +SHELL=/usr/bin/env bash STACK=$(shell command -v stack 2>/dev/null) ifeq (, $(STACK)) diff --git a/shell.nix b/shell.nix index 93215131e..6d4908e09 100644 --- a/shell.nix +++ b/shell.nix @@ -1,15 +1,16 @@ -{ nixpkgs ? import {} }: -with nixpkgs; -stdenv.mkDerivation { +{ pkgs ? import {} }: +pkgs.stdenv.mkDerivation { name = "dex"; - buildInputs = [ + buildInputs = with pkgs; [ cabal-install + cacert + clang_12 + git haskell.compiler.ghc884 - llvm_9 - clang_9 - pkg-config libpng - git - cacert + llvm_12 + pkg-config + stack + zlib ]; } diff --git a/stack.yaml b/stack.yaml index 18f6d1691..1a6fdbccb 100644 --- a/stack.yaml +++ b/stack.yaml @@ -20,3 +20,7 @@ extra-deps: - store-0.7.8@sha256:0b604101fd5053b6d7d56a4ef4c2addf97f4e08fe8cd06b87ef86f958afef3ae,8001 - store-core-0.4.4.4@sha256:a19098ca8419ea4f6f387790e942a7a5d0acf62fe1beff7662f098cfb611334c,1430 - th-utilities-0.2.4.1@sha256:b37d23c8bdabd678aee5a36dd4373049d4179e9a85f34eb437e9cd3f04f435ca,1869 + +nix: + enable: false + packages: [ libpng llvm_12 pkg-config zlib ]