haskell / haskell/cabal

Clarify the executables scope

Open
#6,453 3 comments 1 reaction 0 assignees View on GitHub
blocked: decision-needed
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

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
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
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 https://github.com/haskell/cabal/issues/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 https://github.com/haskell/cabal/issues/5411). Then in a single package we could have

```cabal
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, https://github.com/haskell/cabal/issues/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

```bash
$ 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.

Contributor guide

Open the contributing guide

Research direction

Start with the `scope: private` and `build-tool-depends` behavior described here, then trace the solver path for the local-project case linked as issue #6339. Done means private executables cannot be used by other packages or installed directly, with the proposed `run-tool-depends` workflow accounted for.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
build-system
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.