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
Don't fail on haskell configure warning #51971
Don't fail on haskell configure warning #51971
Conversation
I assume that the build issues that prevented us from using versions beyond 0.10.1 have been fixed by now.
This update was generated by hackage2nix v2.12-5-g7b287a8 from Hackage revision commercialhaskell/all-cabal-hashes@ce1988e.
This update was generated by hackage2nix v2.12-8-g7b07d27 from Hackage revision commercialhaskell/all-cabal-hashes@ae41ad7.
This update was generated by hackage2nix v2.12-8-g7b07d27 from Hackage revision commercialhaskell/all-cabal-hashes@574fb20.
This update was generated by hackage2nix v2.12-8-g7b07d27 from Hackage revision commercialhaskell/all-cabal-hashes@6b2a686.
The current Haskell builder fails when it encounters the a warning from Setup about "indirectly depending on multiple versions of the same pacakge". There is a call to grep which exits if the warning string is in the output of Setup. While indirectly depending on different versions of the same package *can* be a problem, it can also be the desired behavior. I ran into this limitation when I was intentionally building a project that indirect dependencies on megaparsec 6 and megaparsec 7 in a way that did not interfere—the different indirect dependency not only worked but was also the only way I could get the project to build. The cases where this *is* a fundamental problem will be caught at compile time further into the build process with a reasonably readable error message, so it should be fine to let the warning remain a warning rather than exiting the build when we encounter it.
@shlevy worked with Shea to figure this issue out. |
@@ -336,10 +336,6 @@ stdenv.mkDerivation ({ | |||
|
|||
echo configureFlags: $configureFlags | |||
${setupCommand} configure $configureFlags 2>&1 | ${coreutils}/bin/tee "$NIX_BUILD_TOP/cabal-configure.log" | |||
if ${gnugrep}/bin/egrep -q -z 'Warning:.*depends on multiple versions' "$NIX_BUILD_TOP/cabal-configure.log"; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you've removed the only call to gnugrep
so you can remove it from the inherit
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but definitely should be reviewed by someone else.
@@ -336,10 +336,6 @@ stdenv.mkDerivation ({ | |||
|
|||
echo configureFlags: $configureFlags | |||
${setupCommand} configure $configureFlags 2>&1 | ${coreutils}/bin/tee "$NIX_BUILD_TOP/cabal-configure.log" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can drop the tee
here too... Are we looking at cabal-configure.log anywhere else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am very much opposed to the notion that we'd ever link two separate versions of the same library into one executable. Making that possible feels like an anti-feature. Therefore, I am against this change.
There are real cases that need it, it's perfectly sound if you use it carefully, and if you make a mistake it will fail at compile time. What's the issue? |
Also, it's not clear to me why nixpkgs should be making this decision in any case. The haskell ecosystem has decided it should be a warning, why should we overrule that here? If it's the wrong call we should change it upstream... It's not like nix itself makes this situation any worse than it would be otherwise. |
Is there any technical documentation to back that up? Where does this assertion come from? |
This post from Well Typed has a good overview. The relevant bits:
From Haskell's point of view, the "same" definition in two different packages is actually two totally separate definitions that are namespaced implicitly. If you try to use a type from one version of a package in a function that expects the other, you will get a type error:
From the language's point of view, this is no different from using This is the failure case for linking two different versions of the same dependency: code that looks like it should compile won't because the implicit package namespace of two types is different. This behavior is confusing for less experienced Haskellers because you normally don't have to think about different versions of the same package as different namespaces—which is why there is a warning—but the resulting behavior is consistent and is manageable if you understand what's going on. |
Also, let me spell out my usecase here a bit more clearly than I did in the PR description. I am developing Haskell packages locally using Nix and Nixpkgs. Our team has one tool (let's call it The problem comes up when we have packages that require both As it stands right now, we can't build tools that depend on both |
I think it's fine to remove that check if, and only if, the compiler can guarantee that all improper uses of multiple versions of the same dependency will be caught and lead to an error at compile time or at link time.
If it's possible to compile and link an executable that will break at runtime or behave strangely at runtime, then we cannot remove that check.
I would like this answered in a reasonably deep technical analysis, i.e. I'm not excited about trusting someone feelings about this topic. I'd like evidence of some deep understanding of the problem we're taking about. Preferably, we would get a ghc compiler developer to answer that question with some degree of conviction.
|
I really don't understand this. First, again I ask why this is a nixpkgs issue? If you think Cabal is wrong here then shouldn't we fix it there? Second, Third, there are real use cases that are doing a completely reasonable thing here that are broken by this. If this approach is not OK, what do you suggest we do? |
This is a Nixpkgs issue, because the PR is directed to a repository called "nixpkgs". I have no opinion on whether Cabal is doing the right thing or not. I just have an opinion on what I want the Nixpkgs generic Haskell builder to do.
That is the bar we've had for the last couple of years and I see no reason to lower it.
There you go. Fortunately, we don't have any of that crap in Nixpkgs because our generic builder makes sure that you cannot do such a thing.
I don't know for sure. I haven't thought about these problems long enough to feel comfortable having an opinion. I don't know how these things interact with FFI or inlineable class methods or any other of the advanced type machinery modern ghc versions offer. I am not an expert in these things.
"When we compile a Haskell executable that references multiple versions of the same library in its dependency tree, will the compiler guarantee that the resulting binary works properly? Or rather, can we rely on the compiler (or linker) to fail if it won't?"
|
0b0cada
to
df6abca
Compare
Let me rephrase: Why should nixpkgs be opinionated here at all? I have a package that builds just fine with the normal build tools/build system of my language/ecosystem, why is nixpkgs telling me it's wrong if it's not breaking any Nix invariants?
We've never had that bar and it's fundamentally impossible. No language is free of potentially confusing runtime behavior and nothing Nix can do will fix that. Should we ban the partial prelude functions? Those can easily lead to breaking/strange behavior at runtime. What about lazy IO? The C FFI? Maybe we should restrict ourselves to Safe Haskell and write a static analyzer to ensure we upper bound our stack space as runtime?
OK, this was meant to be an example of why your demand was too strong. Yes, you can get weird behavior if you bypass the type system, but that's not at all unique to this situation. But sure let's spell it out.
If you're fine with 1-4, all of which our generic builder allow without a blink, why is it suddenly a problem now?
If you're not comfortable having an opinion, why are you pushing back against those who do, especially when we can back it up? I do know for sure that this is safe: To the typechecker and to the runtime, Again, to the compiler nothing here is meaningfully different from
Again, "resulting binary works properly" is an impossible bar. No, ghc won't magically tell us that we wrote the program we wanted to right. No, ghc won't prevent us from logic errors, specification errors, etc. No, ghc is not dependently typed, linearly typed, etc. But allowing multiple versions of the same package doesn't change any of this.
The code is not broken and it is sheer coincidence that the two DSLs in question in our example happen to be in-house projects.
Well yes obviously we can fork if our use case can't be supported. Are you uninterested in supporting it? |
I agree that if it's allowed by Cabal, it should be allowed by nixpkgs. |
Executables that link multiple, mutually incompatible versions of their dependencies are wasteful and, more importantly, dangerous. Now, there's a chance that such an executable is going to work fine, but there's also a chance that it's going to misbehave or crash at run-time. And if it does, then those errors are extremely hard to debug. I am not aware of a single distribution that exposes its users to that kind of risk.
Your package does not build fine. Your build system prints a big, fat warning telling you that you are doing something that it thinks is a bad idea. Furthermore, if you'll try to run the same build with It is mind boggling to me that you don't mind exposing our users to that kind of risk.
What are you talking about? The bar is "we don't distribute binaries that link inconsistent versions of their dependencies". That quality standard has existed forever, and it's enforced by the very configure-time check that you apparently wish to drop. What can i tell you? If you want a loaded gun pointed at your foot, then please go ahead and do it. But please don't make Nixpkgs point that gun at all the feet of all its users, too, just because you personally happen to enjoy that kind of situation.
Why are we talking about this hypothetical situation? What does this have to do with anything? Nixpkgs can detect builds that link multiple inconsistent versions of their dependencies and it does prohibit those kinds of builds from succeeding.
Honestly, I don't see how this is relevant for this PR.
(1) to (4) are hypothetical problems that you've made up and which are not the subject of this PR. The subject of this PR is that you want to remove a check which detects inconsistent build configurations. There is no relationship between (1) to (4) and this PR. Your argument here is: "Since you cannot detect my made up issues (1) to (4), why should we bother detecting inconsistent builds, which we can detect and have been detecting for years?" That is not a very convincing argument. The technical term is "non sequitur".
Nutritionists from all over the world ague about the perfect diet. Should we eat sugar? Or rather not? How much fat is healthy? And so on and so forth. Now, if someone comes to me asks me what my opinion on this matter is, then I'll say that I don't have an opinion because I am not a nutritionist. I don't know enough about the subject to talk about it with any kind of authority. However, when my 4 year old daughter comes to me and suggests that she wants to eat nothing but chocolate, then I'll push back on that idea because clearly my opinion -- which is naive and uninformed -- is still a hell of a lot more informed than hers.
Ab, lbh qba'g. Lbh qba'g haqrefgnaq gur vzcyvpngvbaf bs gur punatr lbh ner cebcbfvat. Lbh qba'g haqrefgnaq gur pbafrdhraprf guvf punatr jvyy unir sbe bhe hfref, naq lbh frrz bqqyl qvfvagrerfgrq va svaqvat bhg jung gurl ner. Lbh unir snyyra va ybir jvgu n arj srngher naq abj lbh'yy fnl nalguvat naq qb nalguvat gb znxr vg unccra jvgubhg pbafvqrevat gur vzcyvpngvbaf sbe bgure crbcyr.
What we could do is to make the consistency check configurable, i.e. we could add an argument to the generic builder, like |
I think you are wrong on the technical merits and are continually moving the goal posts. If we can get back to a purely technical discussion, I'm happy to try to clarify my points here or on a call. But I don't see how that can be productive given that you've brought the discussion to the level of personal attacks, condescension, and dismissiveness. If you want to have a conversation between mutually respected peers each with their own expertise and understandable technical concerns, let me know. To be absolutely clear, this is what I'm objecting to:
I think comments like this are part of a pattern, both in this conversation and in broader interactions, but for the sake of this discussion I'm happy to limit my concerns to these two comments. |
this is just being childish. Rise above. |
I am happy to admit that i am NOT an expert on the technical details here... The point I’d like to make though, is that I believe this really isn’t an issue on technical details and implications - which this thread went into discussing. I think that what it boils down to is: Should nixpkgs incorporate modifications to potentially improve/secure or generally augment the way haskell packages are built even if that means it will then differ from upstream/everyone else. “This works just fine with vanilla cabal but not via nix” doesn’t seem like something desirable? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am sorry, but this modification has very bad consequences for our ability to detect broken configurations in Nixpkgs. I cannot in good consciousness merge this PR.
What we could do is to make the consistency check configurable, i.e. we could add an argument to the generic builder, like allowInconsistentDependencies
, that disables the configure-time check for that particular build, but defaults to false for everyone who doesn't set it otherwise explicitly.
Removing that check unconditionally is not an option.
Implemented in #52257 |
Closed by #52257 |
Motivation for this change
The current Haskell builder fails when it encounters the a warning
from Setup about "indirectly depending on multiple versions of the
same pacakge". There is a call to grep which exits if the
warning string is in the output of Setup.
While indirectly depending on different versions of the
same package can be a problem, it can also be the desired
behavior. I ran into this limitation when I was intentionally building
a project that indirect dependencies on megaparsec 6 and megaparsec 7
in a way that did not interfere—having different indirect dependency not
only worked but was also the only way I could get the project to
build.
The cases where this does cause problems will be caught at
compile time further into the build process with a reasonably readable
error message, so it should be fine to let the warning remain a
warning rather than exiting the build when we encounter it.
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)nix path-info -S
before and after)