Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task: Implement v2-install --bindir-method={copy,symlink} #5837

Closed
hvr opened this issue Jan 11, 2019 · 10 comments
Closed

Task: Implement v2-install --bindir-method={copy,symlink} #5837

hvr opened this issue Jan 11, 2019 · 10 comments

Comments

@hvr
Copy link
Member

hvr commented Jan 11, 2019

There's at least two use-cases for having this code-path

  1. On Windows, symlink support requires extra configuration; file copying however works without trouble (but we might need to use "ADS" to store some metadata to support store garbage-collection) (see also No clear way to install executables on Windows #5748)
  2. When using Docker or other custom workflows, symlinks might easily break; there a way to copy instead of symlink is desirable as well (see e.g. Allow v2-install to copy executables instead of symlinking #5628)

Currently, cabal already has support for two locations,

  1. --bindir=DIR
  2. --symlink-bindir=DIR

All 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

  1. symlink, symlink into --symlink-bindir location; operation fails if it cannot be symlinked
  2. copy, copy into --bindir location; operation fails if it cannot be copied to target location

Optional (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

  1. on non-Windows platforms: symlink
  2. on Windows: copy (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)
@hvr
Copy link
Member Author

hvr commented Feb 4, 2019

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.

@Mistuke
Copy link
Collaborator

Mistuke commented Feb 4, 2019

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 #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

@gbaz
Copy link
Collaborator

gbaz commented Feb 4, 2019

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.

@Mistuke
Copy link
Collaborator

Mistuke commented Feb 4, 2019

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.

@fgaz
Copy link
Member

fgaz commented Feb 4, 2019

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

@Mistuke
Copy link
Collaborator

Mistuke commented Aug 24, 2019

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

@23Skidoo
Copy link
Member

Sounds like something we should try to fix in 3.0.0.1.

@gbaz
Copy link
Collaborator

gbaz commented Aug 27, 2019

and what would be an eta on that? :-)

(btw congrats on 3.0.0.0 !)

@23Skidoo
Copy link
Member

2-3 weeks.

@AndreasPK
Copy link
Collaborator

AndreasPK commented Jan 23, 2020

I opened an MR changing the default on windows: #6506

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants