Skip to content

Clarify the executables scope #6453

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

Open
phadej opened this issue Dec 21, 2019 · 3 comments
Open

Clarify the executables scope #6453

phadej opened this issue Dec 21, 2019 · 3 comments

Comments

@phadej
Copy link
Collaborator

phadej commented Dec 21, 2019

Currently one could depend on scope: private executables in the other packages.
For example the setup as https://gist.github.com/phadej/0a299e255f00031625da8de4ed190e34

foo.cabal

cabal-version: 2.2
name:          foo
version:       0

library
  default-language:   Haskell2010
  build-tool-depends: foo:foo -any
  exposed-modules:    Foo
  build-depends:
    , base
    , process
    , template-haskell

executable foo
  default-language: Haskell2010
  scope:            private
  main-is:          FooExe.hs
  build-depends:    base

bar.cabal

cabal-version: 2.2
name:          bar
version:       0

library
  default-language:   Haskell2010
  build-tool-depends: foo:foo -any
  exposed-modules:    Bar
  build-depends:
    , base
    , process
    , template-haskell

The following works (at least in local project, see #6339)


I can see a three way distinction in scope:

  1. executables meant to be run by user.
  2. executables not run by user, but which users or developers are aware of
  3. executables internal to the package

The first group is clear, those include cabal, pandoc etc. I.e. executables you want to be in your PATH.
Third group is clear too. For whatever reason an executable my-pkg-helper should stay as an implementation detail.

The second group is however tricky. Sometimes you want happy to be in your PATH, but most often it's handled by cabal for you. If we had run-tool-depends (we should, see #5411). Then in a single package we could have

executable my-compiler
   run-tool-depends: my-compiler-linker

executable my-compiler-linker

Then when user installs only a single executable cabal v2-install my-compiler:my-compiler (the syntax not supported atm, #6369), cabal-install would

  1. solve that also my-compiler-linker is needed
  2. build my-compiler-linker and install it "privately" into the store
  3. build my-compiler telling it somehow (via new fields in Paths_pkgname hs or via CPP directives?) where the my-compiler-link is
  4. install my-compiler into installdir, thus making it available to user

Note: my-compiler-linker is built, and is in store; but isn't directly available to the user.

Yet, if developer of my-compiler decides to keep existence of my-compiler-linker private, it can do that by adding scope:private. Then

$ cabal v2-install my-compiler

won't install my-compiler-linker into installdir, neither other packages may use it for built-tool-depends nor run-tool-depends.


Given above rationale, I suggest that scope: private executables would be only the 3rd group, i.e. the example I started with SHOULD NOT work, i.e. already in the solver we'd refuse to proceed. This however require run-tool-depends.

cc @Ericson2314, @luite, @nomeata, @harpocrates who I think are interested in this to be resolved in a way or another. Also @fgaz and @grayjay as this is related to multi-libs and solver.

@Ericson2314
Copy link
Collaborator

I think I agree with all that. Perhaps cause it's in the 3rd category it should only be for build-tool-depends and not run-tool-depends as otherwise it would leak.

@phadej
Copy link
Collaborator Author

phadej commented Dec 21, 2019

@Ericson2314 It wouldn't. When if the executable is scope: private, then you shouldn't be able to (IMO) be able to depend nor cabal v2-install it. So in above my-compiler case, where my-compiler-linker is scope: private.

  • cabal v2-install my-compiler won't put it into installdir,
  • cabal v2-install my-compiler:my-compiler-linker would fail with solver error
  • my-other-compiler (in different package) couldn't depend on my-compiler-linker not in the build-tool-depends nor run-tool-depends.

I think it helps to think about visibility: private i.e. default internal libraries. They are installed if they are dependencies of components of package they are part of. But you cannot depend on them from outside, nor you should be able to install them (disclaimer: you probably should be able to ask to populate the store, but I don't consider that installing: installing a lib is putting it into the environment/... file)

@Ericson2314
Copy link
Collaborator

Ericson2314 commented Dec 21, 2019

Ah so it's fine for installed things to at run-time depend on non-installed things (in the store)?

I thought the answer was "no" but I have no problem with "yes", this is how Nix works after all.

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

2 participants