| 3 Sep 2024 |
jean-paul. |
is there a nice way to set up a somewhat "ad hoc" haskell environment with nix? I'd like to do some tinkering around with some data and I'm not quite sure what I'm looking for yet. I want to have access to packages from the package set but I just want to use runhaskell or maybe `cabal repl`, but don't really want to write a cabal file and do a native build before being able to run code. | 12:42:52 |
ymeister | I believe you might be interested in she-bangs:
#! /usr/bin/env nix-shell
#! nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [])" -i runhaskell
main :: IO ()
main = do
putStrLn "Hello World!"
Or, my personal favorite (requires nix >= 2.19), which actually compiles and caches the binary:
#!/usr/bin/env nix
#!nix shell nixpkgs#cached-nix-shell --command sh -c ``nix store add "$(readlink -f "$1")" | xargs -I % cached-nix-shell -p 'runCommand "cached-nix-script" {} "mkdir -p $out/bin; ${(haskellPackages.ghcWithPackages (pkgs: with pkgs; []))}/bin/ghc -O2 -o $out/bin/cached-nix-script ${builtins.storePath %}"' --exec cached-nix-script "${@:2}"`` sh
main :: IO ()
main = do
putStrLn "Hello World!"
| 13:47:33 |
ymeister | * I believe you might be interested in she-bangs:
#! /usr/bin/env nix-shell
#! nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [])" -i runhaskell
main :: IO ()
main = do
putStrLn "Hello World!"
Or, my personal favorite (requires nix >= 2.19), which actually compiles and caches both nix evaluation and the binary:
#!/usr/bin/env nix
#!nix shell nixpkgs#cached-nix-shell --command sh -c ``nix store add "$(readlink -f "$1")" | xargs -I % cached-nix-shell -p 'runCommand "cached-nix-script" {} "mkdir -p $out/bin; ${(haskellPackages.ghcWithPackages (pkgs: with pkgs; []))}/bin/ghc -O2 -o $out/bin/cached-nix-script ${builtins.storePath %}"' --exec cached-nix-script "${@:2}"`` sh
main :: IO ()
main = do
putStrLn "Hello World!"
Then just run the file as normal executable.
| 13:48:39 |
ymeister | * I believe you might be interested in she-bangs:
#! /usr/bin/env nix-shell
#! nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [])" -i runhaskell
main :: IO ()
main = do
putStrLn "Hello World!"
Or, my personal favorite (requires nix >= 2.19), which actually compiles and caches both nix evaluation and the binary (i.e. ~0 start up cost + maximum performance):
#!/usr/bin/env nix
#!nix shell nixpkgs#cached-nix-shell --command sh -c ``nix store add "$(readlink -f "$1")" | xargs -I % cached-nix-shell -p 'runCommand "cached-nix-script" {} "mkdir -p $out/bin; ${(haskellPackages.ghcWithPackages (pkgs: with pkgs; []))}/bin/ghc -O2 -o $out/bin/cached-nix-script ${builtins.storePath %}"' --exec cached-nix-script "${@:2}"`` sh
main :: IO ()
main = do
putStrLn "Hello World!"
Then just run the file as normal executable.
| 13:52:34 |
ymeister | Last message kind of reminded me of this "cool" nix she-bang that gives instant-startup + portable + performant haskell scripting I managed to slap together, so I guess I'll leave it outside of the reply thread for more visibility in case it helps anybody.
#!/usr/bin/env nix
#!nix shell nixpkgs#cached-nix-shell --command sh -c ``nix store add "$(readlink -f "$1")" | xargs -I % cached-nix-shell -p 'runCommand "cached-nix-script" {} "mkdir -p $out/bin; ${(haskellPackages.ghcWithPackages (pkgs: with pkgs; []))}/bin/ghc -O2 -o $out/bin/cached-nix-script ${builtins.storePath %}"' --exec cached-nix-script "${@:2}"`` sh
main :: IO ()
main = do
putStrLn "Hello World!"
nix shell nixpkgs#cached-nix-shell uses flakes eval-cache to instantly bring cached-nix-shell from cache if it's already in store, or store it if it isn't
nix store add "$(readlink -f "$1")" adds the script to the nix store
cached-nix-shell runs a wrapper around nix-shell that caches it's evaluation
runCommand actually compiles the script instead of simply interpreting it like runhaskell/runghc
haskellPackages.ghcWithPackages (pkgs: with pkgs; [ ]) is where you put your haskell dependencies
At first run it compiles and runs the script, after that it merely runs an already compiled executable.
The reason it's so complicated is because in v3 nix shell --expr "..." you can't reference neither flake nor channel nixpkgs without running it with --impure which disables eval-cache. Old nix-shell doesn't have eval-cache at all, so even if we use it to bring up cached-nix-shell we waste time even if cached-nix-shell is already in store.
| 14:02:25 |
ymeister | * Last message kind of reminded me of this "cool" nix she-bang that gives instant-startup + portable + performant haskell scripting I managed to slap together, so I guess I'll leave it outside of the reply thread for more visibility in case it helps anybody.
#!/usr/bin/env nix
#!nix shell nixpkgs#cached-nix-shell --command sh -c ``nix store add "$(readlink -f "$1")" | xargs -I % cached-nix-shell -p 'runCommand "cached-nix-script" {} "mkdir -p $out/bin; ${(haskellPackages.ghcWithPackages (pkgs: with pkgs; []))}/bin/ghc -O2 -o $out/bin/cached-nix-script ${builtins.storePath %}"' --exec cached-nix-script "${@:2}"`` sh
main :: IO ()
main = do
putStrLn "Hello World!"
nix shell nixpkgs#cached-nix-shell uses flakes eval-cache to instantly bring cached-nix-shell from cache if it's already in store, or store it if it isn't
nix store add "$(readlink -f "$1")" adds the script to the nix store
cached-nix-shell runs a wrapper around nix-shell that caches it's evaluation
runCommand actually compiles the script instead of simply interpreting it like runhaskell/runghc
haskellPackages.ghcWithPackages (pkgs: with pkgs; [ ]) is where you put your haskell dependencies
At first run it compiles and runs the script, after that it merely runs an already compiled executable.
The reason it's so complicated is because in new nix shell --expr "..." you can't reference neither flake nor channel nixpkgs without running it with --impure which disables eval-cache. Old nix-shell doesn't have eval-cache at all, so even if we use it to bring up cached-nix-shell we waste time even if cached-nix-shell is already in store.
| 14:05:01 |
alexfmpe | I've been meaning to come back to this snippet and read it properly but it getting buried in chat will make it hard - maybe a gist would fit as a better home? | 14:11:45 |
alexfmpe | * I've been meaning to come back to this snippet and digest it properly but it getting buried in chat will make it hard - maybe a gist would fit as a better home? | 14:12:00 |
alexfmpe | description and all | 14:14:37 |
alexfmpe | also more convenient for re-sharing | 14:14:47 |
ymeister | alexfmpe: sure! https://gist.github.com/ymeister/aa14273ce6cc6fa5c4b14c0922648b27 | 14:14:54 |
alexfmpe | thanks, I put this near the top of my tab-queue | 14:16:23 |
ymeister | * Last message kind of reminded me of this "cool" nix she-bang (requires nix >= 2.19) that gives instant-startup + portable + performant haskell scripting I managed to slap together, so I guess I'll leave it outside of the reply thread for more visibility in case it helps anybody.
#!/usr/bin/env nix
#!nix shell nixpkgs#cached-nix-shell --command sh -c ``nix store add "$(readlink -f "$1")" | xargs -I % cached-nix-shell -p 'runCommand "cached-nix-script" {} "mkdir -p $out/bin; ${(haskellPackages.ghcWithPackages (pkgs: with pkgs; []))}/bin/ghc -O2 -o $out/bin/cached-nix-script ${builtins.storePath %}"' --exec cached-nix-script "${@:2}"`` sh
main :: IO ()
main = do
putStrLn "Hello World!"
nix shell nixpkgs#cached-nix-shell uses flakes eval-cache to instantly bring cached-nix-shell from cache if it's already in store, or store it if it isn't
nix store add "$(readlink -f "$1")" adds the script to the nix store
cached-nix-shell runs a wrapper around nix-shell that caches it's evaluation
runCommand actually compiles the script instead of simply interpreting it like runhaskell/runghc
haskellPackages.ghcWithPackages (pkgs: with pkgs; [ ]) is where you put your haskell dependencies
At first run it compiles and runs the script, after that it merely runs an already compiled executable.
The reason it's so complicated is because in new nix shell --expr "..." you can't reference neither flake nor channel nixpkgs without running it with --impure which disables eval-cache. Old nix-shell doesn't have eval-cache at all, so even if we use it to bring up cached-nix-shell we waste time even if cached-nix-shell is already in store.
| 14:20:34 |
jean-paul. |
In reply to
ymeister
I believe you might be interested in she-bangs:
#! /usr/bin/env nix-shell
#! nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [])" -i runhaskell
main :: IO ()
main = do
putStrLn "Hello World!"
Or, my personal favorite (requires nix >= 2.19), which actually compiles and caches the binary:
#!/usr/bin/env nix
#!nix shell nixpkgs#cached-nix-shell --command sh -c ``nix store add "$(readlink -f "$1")" | xargs -I % cached-nix-shell -p 'runCommand "cached-nix-script" {} "mkdir -p $out/bin; ${(haskellPackages.ghcWithPackages (pkgs: with pkgs; []))}/bin/ghc -O2 -o $out/bin/cached-nix-script ${builtins.storePath %}"' --exec cached-nix-script "${@:2}"`` sh
main :: IO ()
main = do
putStrLn "Hello World!"
ah, neat, going to try that, thank you | 14:38:17 |
| 4 Sep 2024 |
chreekat | In reply to @b:chreekat.net What I thought you should do is specify your package and its modified dependencies in the same haskellPackages override, but that results in "This package indirectly depends on multiple versions of the same package." @maralorn:maralorn.de: I thought I remembered you having some recommendation somewhere for a better way of doing this kind of thing? | 04:31:35 |
maralorn | I mean I prefer using cabal2nix directly over callCabal2nix but I don't think that would have changed much. Apart from that I can assist debugging when I see some code, but am uncertain what you are talking about. | 07:17:53 |
MangoIV | I am a bit confused
- how is it possible that cabal fails to build with non-matching unix constraint on pkgsStatic while it doesn’t on normal pkgs?
- why is semaphore-compat set to null on ghc 9.10 when it’s needed to e.g. build cabal-install?
| 09:19:51 |
maralorn | The first one sounds weird indeed. | 09:20:58 |
maralorn | Re the second: We generally set packages to null, when they are distributed with ghc. semaphore-compat sounds definitely like a package to which this applies. | 09:21:58 |
MangoIV | In reply to @maralorn:maralorn.de Re the second: We generally set packages to null, when they are distributed with ghc. semaphore-compat sounds definitely like a package to which this applies. Yeah second one was my mistake. First one is still confusing. | 09:36:08 |
MangoIV | (I had an jailbreak override (which didn’t fix the unix issue) for semaphore compat) | 09:36:49 |
MangoIV | Static ghc 9.10 is not cached 🥲 | 09:38:37 |
cdepillabout | In reply to @mangoiv.:matrix.org Static ghc 9.10 is not cached 🥲 Did you try the haskell-updates branch? That's what Hydra builds for us, and I think it should still contain the pkgsStatic ghc. | 10:21:31 |
cdepillabout | You could check in pkgs/top-level/release-haskell.nix (I think that's the name) to be sure | 10:22:06 |
MangoIV | In reply to @cdepillabout:matrix.org Did you try the haskell-updates branch? That's what Hydra builds for us, and I think it should still contain the pkgsStatic ghc. Nah, I’m good with unstable for now, don’t wanna spend time fiddling around to get HLS building. I just use ghc910 haskell packages for the static build | 10:30:51 |
cdepillabout | In reply to @mangoiv.:matrix.org Nah, I’m good with unstable for now, don’t wanna spend time fiddling around to get HLS building. I just use ghc910 haskell packages for the static build Ah, I mean if you want to get ghc for pkgsStatic from the cache, you should use a commit from haskell-updates. Not the current haskell-updates, since like you say stuff may be broken, but one of the last commits from the previous haskell-updates. That way you can get everything from the cache, and almost nothing should be broken. | 10:39:42 |
MangoIV | In reply to @cdepillabout:matrix.org Ah, I mean if you want to get ghc for pkgsStatic from the cache, you should use a commit from haskell-updates. Not the current haskell-updates, since like you say stuff may be broken, but one of the last commits from the previous haskell-updates. That way you can get everything from the cache, and almost nothing should be broken. Oh! That’s neat - why would the GHC derivation change though when it’s built on haskell-updates? I thought all the tools that GHC itself needs are relatively stable? | 10:44:43 |
alexfmpe | Does the merge-to-master commit itself get the fancy caching? | 10:48:22 |
alexfmpe | That's what I usually point to when I need recent stuff | 10:48:38 |
MangoIV | I built GHC but everything following this was pointless - I’m forced to use haskell-updates for now. | 11:08:22 |