-
Notifications
You must be signed in to change notification settings - Fork 698
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
Filter all autogen modules / c-sources #3656
Comments
First, let's talk workarounds. I can think of a few:
OK, how about properly fixing this? First off, your proposed solution doesn't completely work, because if What's the right way to fix this? I don't know. Here are some possibilities:
I like (5) but it requires a (very useful) yak to be shaved first. |
I'm doing workaround 2 ("nub out the list of other-modules/exposed-modules before they get passed to sdist in the sdist hook"), my autogen modules are built with the postConf hook just to be sure that they are there through the whole process that I don' completely understand and at least no problems so far. About a proper fix only 2 and 3 could work for all the cases I can think of, with 1 and 5 a clean sdist will still fail. With 4 if for example if we want to add a cabal hlint command that works without running configure it will still fail or a new flag is needed with much more hooks.
An combination of 2 and 3 could work: |
(6) is an idea. Rather than require I think |
If you're looking at |
OK, I'll start making some cleanup on What fields are |
I believe it's only |
So, maybe a global |
A new stanza wouldn't really fit with what stanzas are currently used for (which is to specify new components in Cabal.) I think that is not a yak that should be shaved right now. |
So, maybe a global |
If you add a top-level |
Yes, putting the
|
It makes less sense to repeat the file name both in |
Yes, but it will be weird having |
I definitely agree it's not ideal to have to create a field for every type of autogenerated source file. Maybe we can come up with some alternative ideas. One possibility is to have |
We can assume (assumption is the mother of all fu**ups) that a module can't be repeated inside a package for different search paths if thats no already part of what we expect, or start to enforce it, and include modules on this new catch all stanza. |
To be precise, a module can appear multiple times in the search path, but we only take the first occurrence of the module.
I don't think this will work for modules. Consider what Now let's consider the situation with Haskell source files, which we search for in the include path. Let's say we have So it still seems useful to have a separate |
I'm talking about filtering modules by
If the module name can't be repeated this is possible, I mean not having two files with On |
Ah, I think I understand you now, we are still talking about an Although it was not historically the case, these days I think it is best to think as a Cabal package as a simple wrapper around multiple components, which actually contain all the interesting bits. If something is declared at the top-level, outside of a stanza, it should be interpreted as meaning, "copy-paste me into each component stanza". (Let me reregister my objection to an
Yes, I misunderstood your proposal. |
What happens now if an
It is a component if we treat it like one, by having I don't say that this is the way to go but I don't like the other options, they seem hackish and difficult to treat as first class citizens of Cabal instead of complex hooks. This below looks wrong, I prefer my own hooks:
Now image this after adding |
You are right, I retract that as an example.
So, we have to be careful here, because there are a few possible situations. We also have to be careful because the behavior changed recently (I think 1.24 has started doing the right behavior, but if you really care I can doublecheck)
How about this as an alternative:
I mean, are you really going to have that many autogenerated files?
That is an interesting suggestion, but it has some trouble. Suppose an autogenerated module wants to import a non-autogenerated module. Then you cannot just put it in the autogenerated stanza; you also have to move all of its dependencies into their own component (convenience library I guess) so that the autogenerated component can depend on them. I don't know how often autogenerated files actually depend on one non-autogenerated ones in this way, but it is something that is allowed in the current model. |
When I do
If it works now It will work if you always put the autogenerated modules besides the
I also like this alternative because it is faster to implement but not to explain, stills feels like mixing UI and business logic. This seems a discussion of convenience and style but I prefer the new stanza because:
|
I rather like the It might have problems how it figures out things when you have different paths for things for includes, c source directories, when you're dumping stuff in the dist/build/autogen dir by hand, etc. given that the autogen dir isn't in a known fixed path relative to the start of your project. |
The executable module is imported in all cases. The reason for this is that GHC has the following precedence rule for module imports: if a module is defined in the local package, it always has precedence when doing an import.
Believe it or not, this is explicitly supported by GHC: if you define a module in the current package named Prelude, GHC will automatically preferentially use it over the actual Prelude.
While I am sympathetic to this perspective (global namespaces are convenient), we should not do this. Here's another reason why not to: Backpack's mechanism of mix-in linking encourages implementation convenience libraries to have the same module name (e.g.
I mean, yes, you can the I think part of the confusion stems from a misunderstanding of how internal
No, no no,
Well, since |
I think the idea is that you specify the unqualified path (you should never mention |
It should work, its just comparing strings. Thats why I don't understand you other comment
|
I can live with |
:) awesome discussion thread!
Haven't tried, I consider really bad practice modules with the same name on the same package because you are creating a new module with a different signature and making it impossible to use the older one. They are not the same and that means violating the only unique ID we have to reference own package modules on source code.
I'm obviously much less than an Backpack expert so I'll just ask and learn, is there a need for autogenerated modules with the same name but different source on the same package? Isn't it the same as above, only if you want to be nasty?
I'll check it with HEAD, at least with 1.24 its always on
I think we are talking about different things. The autogen stanza won't be like I still don't see a red flag on any of the two options and think it's just a matter of taste. Right now I'm loosing 2 to 1 and if nobody else speaks up I'll implement the |
Your point is valid, though I will note that this is not completely true, as you can use package qualified imports to disambiguate (in some cases).
The rule is, first look for a module named this way in the current project. If none is present, look at the exports of all the packages you build-depends on.
In case you haven't looked at Backpack too closely yet, the Motivation/Overview section here https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst should set the setting. The design pattern with Backpack I'm thinking of is this: imagine that you are making a package which is parametrized a large number of modules (imagine that it's parametrized over string representation, file path representation, monad, etc.) When using this parametrized package, a user could explicitly specify how each module should be implemented explicitly, but it would be far more convenient if the signatures and implementations have the same name; in this case, the user can just bring both the parametrized package and the implementations for the parameters into scope, and they magically "get put together". If there are multiple implementations, evidently it's necessary for multiple packages to export the same module names. And if someone wants to use Backpack internally, then they want multiple libraries in the same package to export the same module names. I know this smacks of record wildcards, and many people don't like this sort of implicitness. But what else are you going to do when there are 20+ module parameters to a package? This is a use-case we do want to support.
Here's the relevant snippet from Distribution.Simple.Build:
Right. And so I guess I'm making two points, (1) extra-source-files/data-files are fields, so it makes sense that they behave this way, whereas your proposal is a stanza; there are no stanzas which behave this way, and (2) in most situations, the autogenerated files for each component are going to be different (if you're autogenerating some C code for the library, you're unlikely to autogen it AGAIN for the test suites, unless you're doing the "rebuild the library as part of the test suite hack", which is a hack and we shouldn't encourage). So it makes sense to specify it per component.
I'm OK with this! |
This issue is subsumed by #3702 |
This issue is not resovled. |
Hmm. Actually this is solved by |
Currently when calling sdist the autogenerated module Paths_* is ignored, this is a problem for packages with built type custom that generate other modules like this one because you get "Error: Could not find module: ..."
My quick fix was just not using sdist because I don't need to, not really an elegant solution but it worked until I added my package as source to a sandbox and discovered that when building on the sandbox sdist is called on my package!
My proposed solution is to list all modules on the autogen directory and filter them from exposed-modules and other-modules, not just Paths_* like function filterAutogenModule on Distribution.Simple.SrcDist does. This is what I'm actually doing with a hook on my setup script.
The text was updated successfully, but these errors were encountered: