On Stack 2.5.1, I am using the following resolver file:
name: clash-HEAD
resolver: lts-16.21
packages:
- github: gergoerdi/clash-compiler
commit: d83b5cc58816654c84537b0b049b32ce899e179e
subdirs:
- clash-ghc
- clash-prelude
- clash-lib
- concurrent-supply-0.1.8
- ghc-typelits-extra-0.4.1
flags:
clash-prelude:
multiple-hidden: false
After a full stack build in my project, I then want to change the version of Clash used, so I change the git commit hash to 62411778020b09433744d267acd5aa3deb85b04f. Subsequently, stack build fails at link time with an error message referencing a symbol that has been removed from Clash between the two Git commits:
17:47:46 [cactus@galaxy space-invaders-book2]$ stack build
Building all executables for `clashilator' once. After a successful build of all of them, only specified executables will be rebuilt.
clash-shake > configure (lib)
clash-shake > Configuring clash-shake-0.0.0...
clash-shake > build (lib)
clashilator > configure (lib + exe)
clash-shake > Preprocessing library for clash-shake-0.0.0..
clash-shake > Building library for clash-shake-0.0.0..
clash-shake > [2 of 3] Compiling Clash.Shake.Xilinx
clashilator > Configuring clashilator-0.1.0...
clashilator > build (lib + exe)
retroclash-lib > configure (lib)
clashilator > Preprocessing library for clashilator-0.1.0..
clashilator > Building library for clashilator-0.1.0..
clashilator > [1 of 3] Compiling Clash.Clashilator
retroclash-lib > Configuring retroclash-lib-0.0.0...
clashilator > <command line>: /home/cactus/sdk/stack/snapshots/x86_64-linux-tinfo6/ec9124c0759d4a86157169cae10f6eb8fa7c593cc5806c7a1c85f1b2d4175440/8.8.4/lib/x86_64-linux-ghc-8.8.4/libHSclash-ghc-1.3.0-J8pqPdvV3DI3lqfzkVaQji-ghc8.8.4.so: undefined symbol: clashzmpreludezm1zi3zi0zmBPZZ7kiQNy99ISBL1Pghy2m_ClashziAnnotationsziPrimitive_zdfDataPrimitiveGuard5_info
retroclash-lib > build (lib)
retroclash-lib > Preprocessing library for retroclash-lib-0.0.0..
retroclash-lib > Building library for retroclash-lib-0.0.0..
clash-shake > <command line>: /home/cactus/sdk/stack/snapshots/x86_64-linux-tinfo6/ec9124c0759d4a86157169cae10f6eb8fa7c593cc5806c7a1c85f1b2d4175440/8.8.4/lib/x86_64-linux-ghc-8.8.4/libHSclash-ghc-1.3.0-J8pqPdvV3DI3lqfzkVaQji-ghc8.8.4.so: undefined symbol: clashzmpreludezm1zi3zi0zmBPZZ7kiQNy99ISBL1Pghy2m_ClashziAnnotationsziPrimitive_zdfDataPrimitiveGuard5_info
retroclash-lib > <command line>: /home/cactus/sdk/stack/snapshots/x86_64-linux-tinfo6/ec9124c0759d4a86157169cae10f6eb8fa7c593cc5806c7a1c85f1b2d4175440/8.8.4/lib/x86_64-linux-ghc-8.8.4/libHSclash-ghc-1.3.0-J8pqPdvV3DI3lqfzkVaQji-ghc8.8.4.so: undefined symbol: clashzmpreludezm1zi3zi0zmBPZZ7kiQNy99ISBL1Pghy2m_ClashziAnnotationsziPrimitive_zdfDataPrimitiveGuard5_info
Progress 3/6
-- While building package clash-shake-0.0.0 (scroll up to its section to see the error) using:
/home/cactus/sdk/stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_3.0.1.0_ghc-8.8.4 --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.0.1.0 build lib:clash-shake --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
-- While building package retroclash-lib-0.0.0 (scroll up to its section to see the error) using:
/home/cactus/sdk/stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_3.0.1.0_ghc-8.8.4 --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.0.1.0 build lib:retroclash-lib --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
-- While building package clashilator-0.1.0 (scroll up to its section to see the error) using:
/home/cactus/sdk/stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_3.0.1.0_ghc-8.8.4 --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.0.1.0 build lib:clashilator exe:clashilator --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
I tried removing .stack-work and */.stack-work, but the problem persists. It seems like I would need to nuke ~/.stack/, just like in the bad old Cabal days.
@gergoerdi would you mind creating a simple project to reproduce this? In that case I could take a look into what's going on here.
Thanks for reporting this anyway.
Sure, I will try to make a small self-contained way of reproducing it (hopefully by tomorrow). In the meantime, https://github.com/gergoerdi/clash-issue-1536/tree/memory-map-th should be the full code, including the stack.yaml and clash-HEAD.yaml files.
Minimizing preproduction will help a lot, thank you.
OK I have uploaded a fully self-contained, reproducing repo to https://github.com/gergoerdi/stack-issue-5473
stack buildcp clash-HEAD2.yaml clash-HEAD.yamlstack buildYeah, great, reproduced it locally
@gergoerdi it looks like you've found a hole in Pantry design :)
the problem is that clash-ghc directory has the same contents for both commits but its dependencies differ. As contents doesn't change (and the deps have the same versions) Stack reuses already built version which results in the failure you're getting.
Not sure yet what to do about this but there is a workaround which doesn't require nuking ~/.stack - use stack exec -- ghc-pkg unregister clash-ghc
So wouldn't a straightforward fix here be to include, in the identifier of a dependency, a hash of (the hash of) all its dependencies?
Nix-like way (when all inputs in theory determine the resulting output) makes sense but that's not quite how Stack works. In principle when checking already compiled libraries deps are also taken into account but it looks like in this case for some reason package identifiers (from ghc-pkg) for cabal-lib and cabal-prelude stay the same. So probably there's some lurking bug - I'll try to dig deeper into it.
@qrilka Thank you for looking into this. I'm hitting this bug as well, and I reported it as #5501 (before I found this issue).
I've experienced this a couple of times now, and I very often update git dependencies, so it happens fairly rarely. I was quite happy that I was able to reproduce it in a Docker container (see #5501). This reproduction may provide an extra data point in figuring out what's going on. But I'm happy to see that this issue has a more minimal reproduction.
For both reproductions, the bug is triggered when a git dependency commit hash is changed to a version where an export is added to an existing module. This is the diff between the dependency versions that causes the error for this issue's reproduction: https://github.com/gergoerdi/clash-compiler/compare/d83b5cc58816654c84537b0b049b32ce899e179e...62411778020b09433744d267acd5aa3deb85b04f, and this is the diff between the dependency version that causes the error for my reproduction: https://github.com/runeksvendsen/bellman-ford/compare/a089bfe9d449afbc1907ded5223bba23a5de9e8a...45bfb65d16a635fadb4097cdb8f3ec9281784083. In both cases the linker error refers to the added exports (modules Clash.Annotations.Primitive and Data.Graph.Digraph respectively).
@runeksvendsen as I've written above it looks like Stack doesn't see the update and reusing old library clearly causes problems. Unfortunately I didn't have time yet to look more into it.
After coming back to this ticket now I see that stack exec -- ghc-pkg unregister clash-ghc I advised above doesn't work - after unregistering Stack picks up incorrect version as precompiled. Will dig more into why that happens.
Most helpful comment
Nix-like way (when all inputs in theory determine the resulting output) makes sense but that's not quite how Stack works. In principle when checking already compiled libraries deps are also taken into account but it looks like in this case for some reason package identifiers (from ghc-pkg) for
cabal-libandcabal-preludestay the same. So probably there's some lurking bug - I'll try to dig deeper into it.