Using clash binaries within projects #2695
Replies: 3 comments
-
We have been bitten by unexpected issues in the past. What I'm worried about, is that if we go around fiddling with this, we forget about an edge case and make the experience worse without noticing it until someone is assertive enough to open an issue or discussion about it (many users will simply work around it instead of contacting a project). I don't see a compelling reason to change what we do until upstream tools make significant changes. We could assuage your objections by renaming the binary we build in a starter project; if we don't call it [edit] |
Beta Was this translation helpful? Give feedback.
-
Related issue: #2107. As you've noticed all the proposed solutions have some pretty big downsides over the current one. Either they don't invalidate caches, or they don't work at all. In any case, I don't think the issues are quite as bad as being presented here: you only run into "real" issues if you're stubborn enough to ignore the installation instructions on Hackage and clash-lang.org/install - at which point I don't care too much anymore. There is an issue if you add If we'd want it to be an experience similar to vanilla Rust/Haskell, we'd have to host our own version of |
Beta Was this translation helpful? Give feedback.
-
Conceptually I don't like the (bogus) copies of clash binaries in each project either. But the fact that it is the only row in your table that has any ☑️, is the reason that it (via clash-starters) is the recommended way of running clash right now. Here are some of the issues I'm aware of around using a clash installed globally (both at the system level or at the user level):
The way this all works with the current starter project is it chooses options 2b and 4b. And the passing of the library environment to clash is slightly different depending on whether you're using stack or cabal: CabalWe use a cabal.project file to force the setting write-ghc-environment-files: always. StackVia some combination of |
Beta Was this translation helpful? Give feedback.
-
There currently is a confusing mix of options in the wild to use the
clash
compiler binary within a hardware design project:system
: the binary might be installed on the system level (independently of a particular project)cabal
: the binary might be pulled in via the cabal build system taking the project and its dependencies into accountbogus copy
: a bogus copy ofclash
can be created within the project as a new executable to link it with the utilized build system (as for example utilized by clash-startes)Additionally, all these variants can be executed differently within the
cabal
andstack
environments leading to a bunch of possible options.Hence, to get a better overview, I did some experiments with this simple project in order to get some first overview. The results are summarized below. Note that I also utilized a
cabal install + nix shell
setup, in order to work around some problems with my system setup, where I listed both variants for comparison. Binaries that are installed withcabal
are put into a localbin
folder (cabal install --installdir=bin clash-ghc
) to keep them local within the project. You might also note that all of these variants utilize slightly different configurations of GHC and the Clash compiler to see how bad interferences can be.The experiments are split into two stages: one with the
cabal.project
of the referenced project and one without. Note that thiscabal.project
only enforces to always write GHC environment files and pulls in a particular version ofclash
.The
PATH
column indicates either a direct call of the given executable or having it put into thePATH
environment variable first.Without the
cabal.project
PATH
cabal run
cabal exec
stack run
stack exec
Error messages of the different ❌s (click to expand)
With the
cabal.project
PATH
cabal run
cabal exec
stack run
stack exec
Error messages of the different ❌s (click to expand)
(✔): works, but requires
cabal build
/stack build
first__*: uses the clash binary pulled in by the utilized build system, not the one in
PATH
The following observations might also be noteworthy:
cabal repl
andstack repl
work without problems for the referenced setup, being a prerequisite.cabal exec
andcabal run
behave completely differently with and without thecabal.project
being present:Without the
cabal.project
,cabal run
only has access to executables within the project, whilecabal exec
basically can use any executable inPATH
. Nonetheless,cabal exec
is special, as it runs them in the scope of the package's environment files, causing the same effect as putting the respective option to thecabal.project
file.With the
cabal.project
in scope, everyclash
binary inPATH
turns obsolete and is not available any more in that context. Thecabal.project
references it's own copy of clash such that both,cabal run
andcabal exec
, consider this reference as the only option available. Both commands now only behave differently on the bogus copy, whererun
automatically rebuilds the dependencies, whileexec
does not.Automatic rebuilding of the dependencies really only works for the bogus copy in combination with
cabal / stack run
.It seems to be hard/impossible to use
clash
inPATH
under the scope ofcabal
, if acabal.project
is present.The main problem that I see with the currently available mix is that it can turn development to be very confusing for users. Not only for starters, but also for experts. Having multiple
clash
binaries around makes it hard to track the one that is currently utilized. Also starters usually don't know anything aboutstack
orcabal
, so the get confused quickly with these subtleties.A more standard way would be to share the binary via
PATH
instead, which would conform to a standard POSIX work environment at least. Then inspectingPATH
withwhereis clash
for example makes it transparent, whichclash
binary is used and no bogus copies have to be around. Using this in combination withcabal install --instaldir=<local dir>
orstack install --local-bin-path=<local-dir>
still would allow for the option to pull project specific versions ofclash
, where utilities likenix shell
ordirenv
could help in pushing them to yourPATH
automatically (see here for a reference). The only difference against the bogus copy is that the user is responsible on his own tocabal build
first, which is a standard build system dependency tracking issue however.Another minor that I observed is that it might be useful if
clash --version
would also output the commit hash of the given build. This would make distinguishing multiple binaries around easier at least.I am interested on your opinions on this, because I think that in terms of user experience it would be more useful if we could offer a more straightforward solution that what we currenlty have.
Beta Was this translation helpful? Give feedback.
All reactions