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

Add show-build-info command #2771

Closed
wants to merge 1 commit into from
Closed

Conversation

bgamari
Copy link
Contributor

@bgamari bgamari commented Aug 16, 2015

Interaction with Cabal poses a few challenges to third-party tooling authors,

  1. The interfaces are rather unstable and tend to be verbose
  2. Some features are provided instead by cabal-install, which currently has no publicly accessible programmatic interfaces
  3. Linking against Cabal directly has unfortunate interactions with cabal-install in the presence of upgrades

While (1) can be addressed with library support easing common use-casese (see, for instance, https://github.com/bgamari/cabal-ghc-dynflags), (2) and (3) pose severe impediments to tooling development. This patch seeks to address this by removing the need to link against Cabal to retrieve build information. It does this by introducing the show-build-info command, which produces a small JSON document describing the compiler arguments Cabal would use to build the various components of the package. For instance,

{ "cabal_version": "1.23.0.0",
  "compiler": {
    "flavor": "GHC",
    "compiler_id": "ghc-7.10.2",
    "path": "/usr/bin/ghc",
  },
  "components": [
    { "type": "library",
      "name": "CLibName",
      "compiler_args":
        ["-O", "-XHaskell98", "-Wall",
         "-package-id", "parallel-3.2.0.6-b79c38c5c25fff77f3ea7271851879eb"]
      "modules": ["Project.ModA", "Project.ModB", "Paths_project"],
      "source_files": [],
      "source_dirs": ["src"]
    }
  ]
}

The goal here is not to replace the Cabal library as the primary means of querying package information. Rather, this command is supposed to target the narrow but important use-case of querying for build information, only providing enough information to allow a third-party tool to reconstruct the compiler configuration and relevant modules without having to link against Cabal. The format is small with the goal of making it relatively easy to ensure compatibility going forwards.

@bgamari
Copy link
Contributor Author

bgamari commented Aug 16, 2015

Bringing in @edsko, who provided the motivation for this feature.

@bgamari
Copy link
Contributor Author

bgamari commented Aug 16, 2015

At the moment I think it is fair to say that this is a bit rough still. For instance, note the fact that Paths_project in the modules list above is generated by Cabal and therefore will not be found in any of the directories listed in source_dirs. Perhaps the solution here is just to eliminate source_dirs entirely (although I can envision a variety of uses for it).

@23Skidoo
Copy link
Member

I guess that this needs a corresponding user guide update? And please also update the changelog. Code looks OK on a first glance.

May be worth making show-build-info a hidden command, since it's not something that ordinary users care about.

/cc @dcoutts

@bgamari
Copy link
Contributor Author

bgamari commented Aug 16, 2015

Yes, absolutely. Really I would first like to get some feedback from other tooling authors. I know what I need but others may want information beyond what I provide here.

/cc @alanz @kazu-yamamoto

@23Skidoo
Copy link
Member

@bgamari There's also a Travis failure.

maybeWithSandboxDirOnSearchPath useSandbox $
showBuildInfo verbosity config distPref buildFlags extraArgs

-- | Actually do the work of building the package. This is separate from
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment was probably copied from somewhere else and needs to be updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, thanks for catching that.

@ttuegel
Copy link
Member

ttuegel commented Aug 16, 2015

Except for the comment and the Travis failure, LGTM.

This allows users to get a JSON representation of various information
about how Cabal would go about building a package. The output of this
command is intended for external tools and therefore the format should
remain stable.
@bgamari
Copy link
Contributor Author

bgamari commented Aug 17, 2015

Brining in @GanielG as well.

@DanielG
Copy link
Collaborator

DanielG commented Aug 17, 2015

Who's @GanielG? :P

I fully support this in theory but just getting the complete set of renered GHC options turned out not to be sufficient for ghc-mod. I had to extract various subsets of options too: https://github.com/DanielG/cabal-helper/blob/master/CabalHelper/Main.hs#L95

@bgamari
Copy link
Contributor Author

bgamari commented Aug 17, 2015

Oh dear, it's apparently still early in the morning.

Indeed you do scrape a lot out of Cabal. My original goal was to avoid reimplementing a JSON representation of the Cabal API and instead just focus on those cases which are complicated by linking considerations (e.g. user installs tool linked against Cabal-1.x.0, later updates cabal-install linking against Cabal-1.y.0; now every time the user switches between running tool and cabal-install the build information will need to be recomputed).

That was merely my original idea, however, and I'm not opposed to adding more surface area to the interface so long as we can do so in a way that is unlikely to pose compatibility issues going forward. Could you offer some more details on precisely what subsets of flags are needed and why?

My understanding is that there are a few classes of options that should be reasonably easy to isolate,

  • Language flags (e.g. -X...)
  • Package flags (e.g. -package-id)
  • Paths (e.g. -I, -i)
  • Perhaps CPP options (e.g. -DMACRO flags)

To get any more specific then this begins to wear away at Cabal's (perhaps not unnecessary) compiler independence. I'm not sure whether we want to enter this territory (@23Skidoo, thoughts?).

@edsko
Copy link
Contributor

edsko commented Aug 17, 2015

Yes yes yes. +1.

@edsko
Copy link
Contributor

edsko commented Aug 17, 2015

@chrisdone / @mgsloan I don't know if you guys still read the cabal data in stack-ide, but if you do, this may be relevant to you guys as well.

@DanielG
Copy link
Collaborator

DanielG commented Aug 17, 2015

  • write-autogen-files

    Just calls writeAutogenFiles since cabal configure doesn't do that and
    cabal build is too heavy.

  • ghc-options

    Pretty much what you already do.

  • ghc-src-options

    Only the search path related options so I can run module graph resolution
    without also pulling in the package database and all the other stuff.

  • ghc-pkg-options

    Only -package-db and -package flags. For ghc-mod commands like browse that
    only need the package database.

  • ghc-merged-pkg-options

    Like above but mconcat'ed together for contexts where we want the entire
    project's dependencies in scope. It's a bit of a hack but would be much worse
    to do at the flag level.

  • ghc-lang-options

    -X flags essentially

  • package-db-stack

    withPackageDB from LocalBuildInfo, we used to just resolve sandboxes
    ourselfs but getting that this way turned out to make supporting stack much
    easier and just seems like a better way to get that anyways.

  • entrypoints

    List of components and source files / other- and exposed-modules
    see componentEntrypoints in the cabal-helper source.

The other commands should be obvious.

@23Skidoo
Copy link
Member

@bgamari I think this PR can go in since it's low-risk and marked as unstable anyway. Do you want me to merge it in the current form or do you think it still needs more work?

@DanielG
Copy link
Collaborator

DanielG commented Sep 23, 2015

I would still like to see the subsets of options added to the interface before this gets merged. Otherwise I'd not be able to use it in ghc-mod which would be a pitty. It would also be nice if I could more or less implement all the stuff in cabal-helper using this interface so we can have a smooth transition from current cabal-install versions to ones that have support for this natively.

I might be able to find some time to work on this unless @bgamari wants to do it. But my schedule is pretty packed so I'm not sure when that would be.

where
go [] = id
go [x] = x
go (x:xs) = x . showString sep . go xs
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Just a casual observer, not a contributor) I assume the intention is to avoid adding another dependency to Cabal, but this still feels like a candidate for a separate library, even if it is a small library that is a minimal subset of Aeson... cabal-aeson-lite or something. I am sure others have already thought this through though..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kanishka-azimi This part of the patch is actually going to vanish anyway, since we already have a aeson-ish mini library in cabal-install (which generates plan.json). But more generally, there is IMO no point to release a small trivial mini-aeson library unless somebody other than cabal wants to actually use it. But I don't see this happening, as aeson is so ubiquitous that virtually everyone just uses aeson if they need JSON capabilities. Last but not least, there's a significant cost involved in maintaining a library on Hackage in a responsible manner (writing proper documentation, testing, keeping it working with updated dependencies and compilers, being careful about API breakges, reacting to feature requests and bug reports etc.).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I wrote that comment I ended up releasing an extended version of my llightweight JSON library as https://hackage.haskell.org/package/microaeson as I ended up needing a dependency-minimal JSON library...

In any case, this PR ought to get rid of the redundant JSON impl in favor of the one we're using already for plan.json.

@23Skidoo
Copy link
Member

@robinp BTW, you might be interesting in reviving this PR for haskell-indexer. The idea here is to add an easier way to integrate "processors" with Cabal, so that new ones could be added with zero/minimal changes to Cabal code.

@robinp
Copy link

robinp commented Jun 11, 2017

@23Skidoo thank you, will consider. For now a GHC frontend plugin might work, but for long-term when we need to capture the precise inputs (for later compilation) this looks required.

@merijn
Copy link
Collaborator

merijn commented Jul 7, 2017

So, essentially the only thing blocking this from being merged is the option subsets DanielG's described?

@hvr hvr mentioned this pull request Aug 3, 2017
@gbaz
Copy link
Collaborator

gbaz commented Apr 9, 2018

what's the status on this?

@23Skidoo
Copy link
Member

23Skidoo commented Apr 9, 2018

Stalled. Someone needs to take action to revive it.

@cfraz89
Copy link
Contributor

cfraz89 commented May 28, 2018

FWIW I've forked @bgamari's commit and updated it against cabal master, over here. @DanielG could you please explain the options subsets bit? Is it the equivalent of ghc-merged-pkg-options in cabal-helper?

There is now the additional complication of having this work against new-build however, at this point I'm well out of my depth. I've added the scaffolding for it, and will work on figuring it out. Could take a while though.

@DanielG
Copy link
Collaborator

DanielG commented Sep 16, 2018

@cfraz89 I've finally found some time to work on new-build support for my packages and ghc-merged-pkg-options is going to go away in the next release so don't worry about it.

@samuelpilz
Copy link

What is the status of this? If reasonable, @fendor and me could pick up at the current state during the next

Could someone familiar with this issue list a roadmap of next steps required for completing this PR?

@mpickering
Copy link
Collaborator

Can we please rebase and merge this? Any future changes can be made incrementally.

@23Skidoo
Copy link
Member

23Skidoo commented Feb 27, 2019

OK with me, if it's clearly marked as unstable/experimental.

Copy link
Member

@hvr hvr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove redundant JSON implementation

where
go [] = id
go [x] = x
go (x:xs) = x . showString sep . go xs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I wrote that comment I ended up releasing an extended version of my llightweight JSON library as https://hackage.haskell.org/package/microaeson as I ended up needing a dependency-minimal JSON library...

In any case, this PR ought to get rid of the redundant JSON impl in favor of the one we're using already for plan.json.

@fendor fendor mentioned this pull request Mar 20, 2019
4 tasks
@phadej phadej closed this Jul 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.