I've seen a number of people get confused over this -- in particular that you _can_ share a source-dir, but then the library modules get rebuilt twice, and the executable stanza needs all the deps the library stanza does, even if the executable doesn't use them directly.
The other option would be to allow this, but to build the executable in such a way that the executable .hs files don't "see" the library .hs files they share a directory with, and so the behavior is _as though_ they were in different directories.
the docs here should also be updated to indicate a dependency on the library in the example, for clarity's sake: http://cabal.readthedocs.io/en/latest/developing-packages.html#example-a-package-containing-executable-programs
sharing a source-dir between library and other stanzas with the intent to compile the same modules but with different flags is quite common and sometimes desirable; warning about that unconditionally would be quite annoying.
One thing I've been wanting however is to warn if you share the same hs-src-dirs between a library and a another component while also having a build-depends relationship with said library component. Since that is almost certainly not intentional.
As for the documentation, I'm not sure which example you're referring to. Example Example: A package containing executable programs seems fine to me; And example A package containing a library and executable programs is fine too; neither of those examples have any hs-source-dir sharing between components.
Ok, the general problem is people just trying to do the lib-with-executable pattern and consistently getting confused by _wanting_ to get the results of the two-directory config but not realizing it.
So perhaps we could resolve this with A) fixing the docs, and B) adding a library _and_ executable option to cabal init to start people off the "right way" while leaving this other functionality for those who want it.
In particular, the warning you suggest is good, but it isn't enough, because often people don't realize they need the build-depends relationship, so they won't hit the warning.
B) adding a library and executable option to cabal init
when did you try cabal init the last time? :-)
(however, the generated template may require tweaking to include the recommended inter-package dep -- and we may need to check whether cabal-version:1.10 already supported this)
Ah, it does do it now. But it does it wrong! It sets up the same source-dir for lib and exe both, and doesn't add a build-depends relationship between the two. I understand if we think this is a possible use case, but I'd argue it certainly isn't the common one, and we should change its behavior.
Relevant part of lib:Cabal for this is Distribution.PackageDescription.Check. Should be a fairly simple local change.
@hvr: One thing I've been wanting however is to warn if you share the same hs-src-dirs between a library and a another component while also having a build-depends relationship with said library component. Since that is almost certainly not intentional.
A huge part of why I like having multiple stanzas in a single cabal file is precisely because I want to share hs-src-dirs.
It allows me to go from:
Org
App
Component
View.hs
Types.hs
client
Org
App
Component
Handler.hs
server
Org
App
Component
Meta.hs
Database.hs
To the much nicer:
Org
App
Component
View.hs
Types.hs
Handler.hs
Meta.hs
Database.hs
So personally I would prefer it if I could have a build-depends that uses the same hs-source-dirs without any weird behavior.
If I import Foo.Bar and Foo.Bar is not listed in other-modules but is listed in the exposed-modules of a dependency, I would personally expect it to use the one from the dependency. In fact I ran into exactly this situation a while ago when first setting things up and I was very confused until I realized what was happening.
It seems like I can use common stanzas to get my desired behavior. However this can lead to more recompilation and doesn't really make the existing behavior any less surprising or beginner-unfriendly.
If I import Foo.Bar and Foo.Bar is not listed in other-modules but is listed in the exposed-modules of a dependency, I would personally expect it to use the one from the dependency.
From a technical POV: I haven't tried to see whether GHC will let us (we'd have to avoid passing -i for the hs-source-dirs flags to GHC); then this should in principle work...
Are there any status updates on this? Or anything I can do to help make this possible?
Having separate interdependent components under a single src honestly has great ergonomics.
I know I personally hate when I'm trying to find the Foo.Bar.Baz module and find out it's not in foo-bar/src/Foo/Bar/Baz.hs because it's actually in foo-bar-core/src/Foo/Bar/Baz.hs.
I'd rather allocate things to different sub-components in the cabal file and let the src structure exactly match the haskell module structure.
One have to teach / find a way to disable GHC to not be too eager in discovering modules. This is not limitation of cabal, it's limitation of ghc --make.
In that case should I create a GHC issue to discuss that possibility?
@bgamari The proposal as written here is a bit underspecified. However, I suspect the real solution will ultimately be for Cabal to stop using --make mode and rather use one-shot compilation.