Skip to content

Clarify build-tool-depends a bit more #5561

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

Merged
merged 4 commits into from
Sep 29, 2018
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 31 additions & 11 deletions Cabal/doc/developing-packages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2063,21 +2063,31 @@ system-dependent values for these fields.
.. pkg-field:: build-tool-depends: package:executable list
:since: 2.0

A list of Haskell programs needed to build this component.
A list of Haskell executables needed to build this component. Executables are provided during the whole duration of the build,
so this field can be used for executables needed during :pkg-section:`test-suite` as well.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Err what do you mean? The tests can invoke the executables when run? I suppose they do work for that, though I hope to make a different sort of dependency for that httpsaskell/cabal/issues/5411 . Either way, I hope the vast majority of use-cases like hspec-discover really are just used when building the tests.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes :) Anything to clarify here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ericson2314 btw, assuming we get run-tool-depends at some point; we'd still need to emulate the current build-tools-depends which conflatedly implies the future run-tool-depends w/ cabal-version:2.* packages; so at that point, @domenkozar wording will still be valid for packages using the respective cabal-version:-values which still had these semantics.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, that sentence implies that running the test-suite is considered part of the build-phase; I think it's worth spelling this out as otherwise it might not be obvious that the respective $PATH-augmentation will also be in effect during the invocation of the test-suite (via e.g. cabal new-test)

Copy link
Contributor

@quasicomputational quasicomputational Sep 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh. So cabal new-run test:blah and cabal new-test test:blah will behave differently wrt the availability of things listed in build-tool-depends?

Edit: Experimentally verified that yes, they do behave differently. That's worrying if we're recommending new-run as the way to pass arguments to tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@quasicomputational you picked up on my subtle hint... ;-)

I consider this a bit of a bug, and I seem to recall we already talked about this in another issue; i.e. ideally

  • cabal new-run test:x behaves close to cabal new-test x
  • cabal new-run bench:x behaves close to cabal new-bench x

as I'd consider it merely a different interface to invoking the test-suites; but the $PATH setup ought to be compatible.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right insofar that there's a bug, I consider the new-run behavior correct :D.


Each is specified by the package containing the executable and the name of the executable itself, separated by a colon, and optionally followed by a version bound.
It is fine for the package to be the current one, in which case this is termed an *internal*, rather than *external* executable dependency.

External dependencies can (and should) contain a version bound like conventional :pkg-field:`build-depends` dependencies.
Internal deps should not contain a version bound, as they will be always resolved within the same configuration of the package in the build plan.
Specifically, version bounds that include the package's version will be warned for being extraneous, and version bounds that exclude the package's version will raise an error for being impossible to follow.
All executables defined in the given Cabal file are termed as *internal* dependencies as opposed to the rest which are *external* dependencies.
Each of the two is handled differently:

1. External dependencies can (and should) contain a version bound like conventional :pkg-field:`build-depends` dependencies.
2. Internal depenedencies should not contain a version bound, as they will be always resolved within the same configuration of the package in the build plan.
Specifically, version bounds that include the package's version will be warned for being extraneous, and version bounds that exclude the package's version will raise an error for being impossible to follow.

Cabal can make sure that specified programs are built and on the ``PATH`` before building the component in question.
It will always do so for internal dependencies, and also do so for external dependencies when using Nix-style local builds.
Cabal tries to make sure that all specified programs are built and provided on the ``PATH`` before building the component in question, but can only do so for Nix-style builds. Specifically:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing worth mentioning explicitly is that those tools' are prepended to the search $PATH; that's important as otherwise a globally same-called executable could interfere (concrete example: if you happen to have a system-wide installed alex executable version 3.1.3 in /usr/bin, but your build-tools-depends: alex:alex ^>= 3.2.4 you'd certainly want to use the one provisioned by new-build satisfying the version constraint to take precedence.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"are built" ... does this mean cabal will do the building automatically or that the user is expected to do the building independently?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fommil would "are atomically built" clarify the intent?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is important addition. I would like to see in the documentation how to specify constraints for build-tool-depends.


:pkg-field:`build-tool-depends` was added in Cabal 2.0, and it will
be ignored (with a warning) with old versions of Cabal. See
:pkg-field:`build-tools` for more information about backwards
compatibility.
a) For Nix-style local builds, both internal and external dependencies.
b) For old-style builds, only for internal dependencies [#old-style-build-tool-depends]_.
It's up to the user to provide needed executables in this case under `$PATH.`


.. note::

:pkg-field:`build-tool-depends` was added in Cabal 2.0, and it will
be ignored (with a warning) with old versions of Cabal. See
:pkg-field:`build-tools` for more information about backwards
compatibility.

.. pkg-field:: build-tools: program list
:deprecated:
Expand Down Expand Up @@ -3478,3 +3488,13 @@ a few options:


.. include:: references.inc

.. rubric:: Footnotes

.. [#old-style-build-tool-depends]

Some packages (ab)use :pkg-field:`build-depends` on old-style builds, but this has a few major drawbacks:

- using Nix-style builds it's considered an error if you depend on a exe-only package via build-depends: the solver will refuse it.
- it may or may not place the executable on $PATH.
- it does not ensure the correct version of the package is installed, so you might end up overwriting versions with each other.