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

Specify components when configuring, not building #2802

Closed
snoyberg opened this issue Aug 30, 2015 · 10 comments
Closed

Specify components when configuring, not building #2802

snoyberg opened this issue Aug 30, 2015 · 10 comments

Comments

@snoyberg
Copy link
Collaborator

I'd like to share an idea and get feedback as to whether such a change would be accepted in Cabal. Currently, selection of which components to build is done as part of the build step. I know of at least three issues with this:

  • Dependencies for components we don't want to build must still be present. Consider a .cabal file with 2 executables: A has very few dependencies, and B has many dependencies. In order to build executable A, we have to provide all of the dependencies for B. (Related: dependencies are checked even if buildable is False #1725)
  • Suppose a package has a library and two executables. If you build the library and one executable and then run the copy command, it will fail since the second executable is not present (see: copy command fails when building only some components #2780)
  • If an executable relies on a library in the cabal file, there's no way to say "use the already installed version of the library, and don't rebuild the library here." This can be useful for avoiding unnecessary recompilation, especially in the presence of changing cabal_macros.h files (see: Disable library building, only build other components #2775)

My proposal: add a new command line option to the configure command, which will take a command-separated list of components to include, ignoring all other components. E.g.:

runghc Setup.hs configure --components=lib,exe:foo,test:bar,bench:baz

The semantics would be: all further commands run will implicitly filter out all non-listed components from the .cabal file.

An alternative- and possibly simpler- implementation that would be a bit hairier but still probably work would be providing a --cabal-file argument that would force Cabal to read from a given .cabal file. Then we could create temporary .cabal files with the necessary components stripped out.

Can someone comment on whether such a patch would be accepted, and give any insight into best approach to implementing if so?

@23Skidoo
Copy link
Member

This seems reasonable to me, and we already do this for benchmarks and test suites. Default behaviour could be the same as it is now.

/cc @dcoutts

@snoyberg
Copy link
Collaborator Author

snoyberg commented Sep 8, 2015

@23Skidoo Just to confirm: do we need to wait for @dcoutts to sign off on this proposal, or is this an acceptable idea to start implementing?

@23Skidoo
Copy link
Member

23Skidoo commented Sep 8, 2015

Duncan seems to be busy right now.

I think it's fine to start implementing as long as the patch is backwards-compatible, i.e. cabal configure; cabal build exe:foo still works as before (but cabal configure --components=lib; cabal build exe:foo fails like it now does for disabled test suites).

@snoyberg
Copy link
Collaborator Author

snoyberg commented Sep 8, 2015

Cool, sounds like a reasonable requirement for the new feature.

@phadej
Copy link
Collaborator

phadej commented Oct 5, 2015

Could the first stage be to provide --enable-library, --enable-executables and disable counterparts to be consistent with existing --enable-tests and --enable-benchmarks?

One immediate feature would be to be able to run tests against installed library, with

cabal configure --disable-library --enable-tests
cabal test

when test suite depends on the library and not hs-source-dirs: test src.

Either this first stage, or original issue could be doable task for this week hackathon?

@ezyang
Copy link
Contributor

ezyang commented Dec 21, 2015

@dcoutts hasn't responded here, but based on communication with him at last ICFP, my understanding is that Duncan is keen to resolve issues 1 and 2 differently, by having Cabal continue to configure all components by default, but making it non-fatal if some components cannot be configured. (And then fixing copy to not attempt to copy components which failed configuration.)

This doesn't fix 3, but maybe you just need a different flag to override internal dependencies.

@ezyang
Copy link
Contributor

ezyang commented Jan 19, 2016

(I guess I should add, my natural inclination is to do everything per component.)

@ezyang
Copy link
Contributor

ezyang commented Apr 5, 2016

@phadej You are right. In fact, this should be very straightforward to implement. Here's how to do it:

  1. Add exeEnabled and libraryEnabled fields to Executable and Library data types in Distribution.PackageDescription, and then update allBuildInfo and other use sites of testEnabled and benchmarkEnabled to respect these new fields.
  2. Update configureFinalizedPackage in Distribution.Simple.Configure to also update libraries/executables based on the new flag you introduce. For simple flags like --enable-executables it will look exactly just like the current code; if you want to implement --component you'll have to look more closely at the name of the component.

Willing to advise someone who want so to do this.

ezyang added a commit that referenced this issue Jul 30, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit that referenced this issue Jul 30, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit that referenced this issue Jul 30, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit that referenced this issue Jul 30, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit that referenced this issue Jul 30, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 2, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 3, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 5, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 5, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 5, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 7, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 7, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 7, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 11, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
@ezyang
Copy link
Contributor

ezyang commented Aug 12, 2016

CC @mgsloan. I just realized that my patchset doesn't solve this feature request in its entirety, because it only supports configuring a single component at a time, rather than multiple components. I suppose it would not be too difficult to extend the patchset to also support multiple components, but if you can configure one component at a time, is it still necessary?

By the way, --cabal-file was implemented in #3553.

@dcoutts
Copy link
Contributor

dcoutts commented Aug 12, 2016

For our general sanity I suggest we stick with one. This isn't useful as a human interface anyway, only as a machine for tools.

ezyang added a commit to ezyang/cabal that referenced this issue Aug 12, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.  I dropped
the package name match sanity check to handle convenience library
package name munging.  I also had to make register/copy unconditionally
install internal libraries; otherwise you can't refer to them
from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 12, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.

I dropped the package name match sanity check to handle convenience
library package name munging.  Consider an internal library named
'q' in package 'p'.  When we install it to the package database,
we munged the package name into 'z-p-z-q', so that it doesn't
conflict with the actual package named 'q'.  Now consider when
we feed it in with --dependency q=p-0.1-hash-q.  Previously,
Cabal checked that the 'q' in --dependency matched the package
name in the database... which it doesn't. So I dropped the check.

I also had to make register/copy unconditionally install internal
libraries; otherwise you can't refer to them from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 14, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.

I dropped the package name match sanity check to handle convenience
library package name munging.  Consider an internal library named
'q' in package 'p'.  When we install it to the package database,
we munged the package name into 'z-p-z-q', so that it doesn't
conflict with the actual package named 'q'.  Now consider when
we feed it in with --dependency q=p-0.1-hash-q.  Previously,
Cabal checked that the 'q' in --dependency matched the package
name in the database... which it doesn't. So I dropped the check.

I also had to make register/copy unconditionally install internal
libraries; otherwise you can't refer to them from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 15, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.

I dropped the package name match sanity check to handle convenience
library package name munging.  Consider an internal library named
'q' in package 'p'.  When we install it to the package database,
we munged the package name into 'z-p-z-q', so that it doesn't
conflict with the actual package named 'q'.  Now consider when
we feed it in with --dependency q=p-0.1-hash-q.  Previously,
Cabal checked that the 'q' in --dependency matched the package
name in the database... which it doesn't. So I dropped the check.

I also had to make register/copy unconditionally install internal
libraries; otherwise you can't refer to them from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 18, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.

I dropped the package name match sanity check to handle convenience
library package name munging.  Consider an internal library named
'q' in package 'p'.  When we install it to the package database,
we munged the package name into 'z-p-z-q', so that it doesn't
conflict with the actual package named 'q'.  Now consider when
we feed it in with --dependency q=p-0.1-hash-q.  Previously,
Cabal checked that the 'q' in --dependency matched the package
name in the database... which it doesn't. So I dropped the check.

I also had to make register/copy unconditionally install internal
libraries; otherwise you can't refer to them from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 21, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.

I dropped the package name match sanity check to handle convenience
library package name munging.  Consider an internal library named
'q' in package 'p'.  When we install it to the package database,
we munged the package name into 'z-p-z-q', so that it doesn't
conflict with the actual package named 'q'.  Now consider when
we feed it in with --dependency q=p-0.1-hash-q.  Previously,
Cabal checked that the 'q' in --dependency matched the package
name in the database... which it doesn't. So I dropped the check.

I also had to make register/copy unconditionally install internal
libraries; otherwise you can't refer to them from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
ezyang added a commit to ezyang/cabal that referenced this issue Aug 21, 2016
Described in: ghc-proposals/ghc-proposals#4

./Setup configure now takes an argument to specify a specific
component name that should solely be configured.

Most of the gyrations in Configure are all about making it so that
we can feed in internal dependencies via --dependency.

I dropped the package name match sanity check to handle convenience
library package name munging.  Consider an internal library named
'q' in package 'p'.  When we install it to the package database,
we munged the package name into 'z-p-z-q', so that it doesn't
conflict with the actual package named 'q'.  Now consider when
we feed it in with --dependency q=p-0.1-hash-q.  Previously,
Cabal checked that the 'q' in --dependency matched the package
name in the database... which it doesn't. So I dropped the check.

I also had to make register/copy unconditionally install internal
libraries; otherwise you can't refer to them from later builds.

Also a miscellaneous refactor: convenience libraries are printed with a
"header" stanza now (not really a stanza header).

Signed-off-by: Edward Z. Yang <[email protected]>
@ezyang ezyang closed this as completed in a090a49 Aug 21, 2016
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

5 participants