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

Allow conditions that check for the cabal(-install?) version used. #10386

Open
AndreasPK opened this issue Sep 27, 2024 · 5 comments
Open

Allow conditions that check for the cabal(-install?) version used. #10386

AndreasPK opened this issue Sep 27, 2024 · 5 comments

Comments

@AndreasPK
Copy link
Contributor

Describe the feature request

The gist of it is that I have a .cmm file in a project that should be linked into the final executable.

Pre-3.12 we used a workaround to deal with #8639 where we would add the cmm file to ghc-options and that worked as it would add Foo.cmm to the link step invocation of ghc which would then compile and linke the resulting .o file into the executable as well.

With >= Cabal 3.12 this results in linker errors as cabal hands the cmm derived .o file to the linker now as it always should have and the workaround adds it another time, resulting in duplicate symbols.

Ideally I would work around this using something like if cabal < 3.12: ghc-options: Foo.cmm but there does not seem to be a obvious way to do so.

Concretely I have:

executable run-it
    main-is:          Run.hs
    cmm-sources:      Trampoline.cmm

    -- Workaround Cabal < 3.12 since Cabal doesn't link cmm-sources into executables
    ghc-options:      Trampoline.cmm
    build-depends:    base,
                      unix,
                      mmap
    ghc-options:      -Wall -Wno-unticked-promoted-constructors
    default-language: Haskell2010

In this specific case the package is typically only built via a script so I can add a flag that corresponds to a cabal version predicate that I compute in the bash script. But having the ability to do this in the cabal file itself seems a lot cleaner and not all that far fetched.

@philderbeast
Copy link
Collaborator

I asked for a similar thing for projects with #8933.

@dcoutts
Copy link
Contributor

dcoutts commented Sep 30, 2024

The theory is that .cabal files declare the version of the Cabal spec that they follow, and then tools interpret that into the behaviours. So .cabal files don't talk about the version of a particular build tool in use (stack, cabal-install, Setup.hs whatever).

So arguably that bux fix ought to be conditional on the declared version of cabal in the package's .cabal file. That is the bug fix should be a change in specified behaviour between Cabal spec version X and X+1, and then .cabal files can either follow the old or new behaviour.

Allowing "if spec( < 3.12)" is arguably not completely implausible, but now it changes the interpretation of .cabal files from "I follow this version of the spec" into "I follow some base version of the spec but tell me a version of the spec and I'll try to adapt". In that case, how does a build tool know what range it can support, and what behaviours it should apply. Currently build tools can say "if the package is pre spec-vX then I'll use this behaviour, else that", but if the package supports a range, then what behaviour should the tool use?

@philderbeast
Copy link
Collaborator

Between cabal-3.8 and cabal-3.10 project imports changed from being "project root" relative to being "importing file" relative. With Updo, I worked around that with a CABAL_RELATIVITY flag as project files, unlike package description files, are not versioned nor do they allow if impl(cabal ...) conditionals.

@AndreasPK
Copy link
Contributor Author

The theory is that .cabal files declare the version of the Cabal spec that they follow, and then tools interpret that into the behaviours. So .cabal files don't talk about the version of a particular build tool in use (stack, cabal-install, Setup.hs whatever).

All if this is sensible. A predicate would just be there to work around cases where Cabal fails to uphold this ideal standard of a given spec always being interpreted the same way.

At this point cabal interprets a spec (say 3.0) differently between cabal version <3.12 and >=3.12, and just like people sometimes add flags conditional on specific ghc versions to work around bugs it would make sense to me to be able to do so for Cabal.

Maybe it's not worth adding this feature, but it seems inevitable that issues such like this one will occur again where Cabal interprets the same spec differently in different versions. After all despite best efforts, the Cabal spec is and most likely always will be partially implementation defined. Which means it's expected that sometimes with newer versions the interpretation of the spec will accidentally change.

Allowing "if spec( < 3.12)" is arguably not completely implausible, but now it changes the interpretation of .cabal files from "I follow this version of the spec" into "I follow some base version of the spec but tell me a version of the spec and I'll try to adapt".

I don't understand where the "try to adapt" comes into play. I would argue the predicate would only check the version of the interpreter of the spec, and would not change how the given file should be interpreted in regards to the spec used. It woudn't be different than checking if the ghc version used has some known bug and working around that in the cabal file.

@AndreasPK
Copy link
Contributor Author

AndreasPK commented Sep 30, 2024

One suggestion that I was made ware of would be to:

  • For specs < 3.12 consider the old behaviour, and perhaps cmm-sources as a whole, a bug and therefore deprecate cmm-sources for Cabal specs before 3.12.
  • Add a warning to cabal-check to check for the use of cmm-sources with older specs.

This would ensure well defined behavior going forward, prevent packages using cmm-sources with specs <3.12 making their way onto hackage and would be reasonably easy to implement. The downside of this approach is that it removes the ability to use a spec <3.12 while using cmm-sources. Which might be alright. I was told there are essentially no packages on hackage currently using this combination anyway.

edit: I haven't verified this but based on the changelog/other reports this issue only affects executables with cmm-sources. Not cmm-sources in general.

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

3 participants