There's at least two use-cases for having this code-path
Currently, cabal already has support for two locations,
--bindir=DIR--symlink-bindir=DIRAll that we need is the ability to configure which of those two locations to use; right now v2-install is hardwired to symlink and use --symlink-bindir
This task is about adding a new flag --bindir-method=... to v2-install (whose default ought to be configurable via ~/.cabal/config) which takes takes an enumeration of at least
symlink, symlink into --symlink-bindir location; operation fails if it cannot be symlinkedcopy, copy into --bindir location; operation fails if it cannot be copied to target locationOptional (i.e. not critical for 2.4; can be done later): additionally, we might want a 3rd variant (maybe called auto) which tries to symlink, but falls back to copy if symlink fails (relevant for Windows; see also PR #5684 which tried to hardcode this scheme)
Finally, for the implied defaults (i.e. when there's no explicit default set via ~/.cabal/config) for bindir-method: we should have
symlinkcopy (or maybe the auto method, once it's implemented; however sticking to copy as default might result in more deterministic results)Possible bikeshedding alternative:
--bindir-style--bindir-policy (c.f. --overwrite-policy)Update:
@fgaz's PRs (see #5870) have gone for using a new flag --installdir=DIR instead of --*bindir=DIR, and so the current draft entails to have the following install-flags:
$ cabal --help
...
--overwrite-policy=always|never How to handle already
existing symlinks.
--install-method=copy|symlink How to install the
executables.
--installdir=DIR Where to install (by
symlinking or copying) the
executables in.
Installs one or more packages. This is done by installing them in the store
and symlinking/copying the executables in the directory specified by the
--installdir flag (`~/.cabal/bin/` by default). If you want the installed
executables to be available globally, make sure that the PATH environment
variable contains that directory.
If TARGET is a library, it will be added to the global environment. When doing
this, cabal will try to build a plan that includes all the previously
installed libraries. This is currently not implemented.
For Windows, one could detect developer mode via the registry [1] or detect if the user has elevation rights [2] and on Windows Vista+, then symlinks would work, otherwise default to copy.
This way you don't need to fail the operation to determine if it supports symlinks or not.
One annoyance is that https://github.com/haskell/cabal/issues/4597 is still the case, so we'd store symlinks in a location that is being synched. I'm not sure if this will cause problems or not for network users.
Perhaps we really should fix this for v2-*.
[1] https://stackoverflow.com/questions/41231586/how-to-detect-if-developer-mode-is-active-on-windows-10
[2] https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-gettokeninformation
I think it would be pretty weird to have two different windows defaults that are picked via some "smart" policy. Imho it would be less confusing to end users for windows to always default to copy.
I think it would be pretty weird to have two different windows defaults that are picked via some "smart" policy. Imho it would be less confusing to end users for windows to always default to copy.
I disagree. The end-user doesn't and shouldn't care about which method is being used. copying is just simply slower. and it takes more space especially on a platform where we statically link binaries.
I don't see why it should matter to the end-user as long as it works and works consistently. We shouldn't punish Windows users with an inferior approach. Also "copying" as it currently is implemented in Directory goes through the GHC I/O manager (another limitation that posix apis have but not Windows for when moving files to another physical disk), so we hit another much slower path.
I personally think, users will be much more annoyed by having things be even slower.
What about opening a separate issue for adding an --install-method=auto which does the registry magic? I can't add that in #5869/#5870 since I do not have a windows machine and getting one / a vm would take a bit
Edit: Well, I could get a vps
the cabal 3.0 branch seems to have been cut but v2-install still seems to default to a non-working default on Windows. It's default seems to be symlink but there's no code to support symlinks in cabal so it all fails with
cabal.exe: Symlinking feature not available on Windows
Sounds like something we should try to fix in 3.0.0.1.
and what would be an eta on that? :-)
(btw congrats on 3.0.0.0 !)
2-3 weeks.
I opened an MR changing the default on windows: https://github.com/haskell/cabal/pull/6506
Most helpful comment
the
cabal 3.0branch seems to have been cut butv2-installstill seems to default to a non-working default on Windows. It's default seems to besymlinkbut there's no code to support symlinks in cabal so it all fails with