How to specify import paths for a frontend plugin

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

How to specify import paths for a frontend plugin

Derek Lam

Hi ghc-devs,

 

I’m making a first attempt to make a frontend plugin, to resolve cabal packages in the GHC API. However I’m running into troubles with module resolution in the GHC API, because I can’t control where it will search for modules at all. I've attached a minimal example, with a frontend plugin definition that can’t find modules (Plugin.hs), and an equivalent standalone program that does (Main.hs).

 

Specifically, I'm following a solution Edward Yang published in 2017 (http://blog.ezyang.com/2017/02/how-to-integrate-ghc-api-programs-with-cabal/), where the frontend plugin is called through a helper script that passes flags forwarded from `cabal repl`. To test the plugin directly with GHC, I collected the args through the helper script and filtered them to the minimal set that made the plugin run:

 

  ghc --frontend Plugin -itarget -package-db dist-newstyle/packagedb/ghc-8.6.5 Plugin -plugin-package sandbox -hide-all-packages

 

This, as well as the full argument set, would complain that it can't find the target module under `./target/A.hs`:

 

  <no location info>: error: module ‘A’ cannot be found locally

 

It does when the import path arg `-itarget` is absolute. Still, its `importPaths` are what I expect: [".", "target"], and the standalone program finds the target module with the same `importPaths`. I've tested this in GHC 8.6.5, 8.4.2 and 8.2.2, making me sure I'm just missing something, but I haven’t found help in the docs yet. I really appreciate some help to draw my hours over this to a close!

 

Thanks,

Derek

 

PS the full invocation of the plugin (with absolute paths swapped with relative ones, except `-itarget` which was relative to begin with) is:

 

ghc --frontend Plugin -plugin-package sandbox -fbuilding-cabal-package -O0 -outputdir dist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build -odir dist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build -hidir dist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build -stubdir dist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build -i -idist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build -i. -itarget -idist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build/autogen -idist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build/global-autogen -Idist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build/autogen -Idist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build/global-autogen -Idist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build -optP-include -optPdist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/build/autogen/cabal_macros.h -this-unit-id sandbox-0.1.0.0-inplace -hide-all-packages -Wmissing-home-modules -no-user-package-db -package-db /Users/derek-lam/.cabal/store/ghc-8.6.5/package.db -package-db dist-newstyle/packagedb/ghc-8.6.5 -package-db dist-newstyle/build/x86_64-osx/ghc-8.6.5/sandbox-0.1.0.0/package.conf.inplace -package-id base-4.12.0.0 -package-id ghc-8.6.5 -XHaskell2010 Plugin -hide-all-packages


_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

plugin.tar.gz (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How to specify import paths for a frontend plugin

Ben Gamari-2
Derek Lam <[hidden email]> writes:

> Hi ghc-devs,
>
Hi Derek,

> I’m making a first attempt to make a frontend plugin, to resolve cabal
> packages in the GHC API. However I’m running into troubles with module
> resolution in the GHC API, because I can’t control where it will
> search for modules at all. I've attached a minimal example, with a
> frontend plugin definition that can’t find modules (Plugin.hs), and an
> equivalent standalone program that does (Main.hs).
>
> Specifically, I'm following a solution Edward Yang published in 2017
> (http://blog.ezyang.com/2017/02/how-to-integrate-ghc-api-programs-with-cabal/),
> where the frontend plugin is called through a helper script that
> passes flags forwarded from `cabal repl`. To test the plugin directly
> with GHC, I collected the args through the helper script and filtered
> them to the minimal set that made the plugin run:
>
>   ghc --frontend Plugin -itarget -package-db
> dist-newstyle/packagedb/ghc-8.6.5 Plugin -plugin-package sandbox
> -hide-all-packages
>
> This, as well as the full argument set, would complain that it can't
> find the target module under `./target/A.hs`:
>
>   <no location info>: error: module ‘A’ cannot be found locally
>
> It does when the import path arg `-itarget` is absolute.
By "it does" do you mean "it still fails"?

> Still, its `importPaths` are what I expect: [".", "target"], and the
> standalone program finds the target module with the same
> `importPaths`. I've tested this in GHC 8.6.5, 8.4.2 and 8.2.2, making
> me sure I'm just missing something, but I haven’t found help in the
> docs yet. I really appreciate some help to draw my hours over this to
> a close!
>
Hmm, very interesting. If I recall correctly, the relevant codepath in
GHC is Finder.findImportedModule which should find the module via
Finder.findHomeModule. Unfortunately, in my cursory look I didn't see
any obvious issues; it looks like this might require a build of GHC and
a bit of debugging. If you can produce a minimal, concrete reproducer
(e.g. your plugin and a set of specific instructions to reproduce the
issue) it's possible I can have a look.

Cheers,

- Ben

_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

signature.asc (497 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How to specify import paths for a frontend plugin

Derek Lam
Hi Ben,

Thanks for the pointer. I looked for the error call and it does indeed look like the path from the error in GhcMake.downsweep feeds from GhcMake.summariseModule and then Finder.findImportedModule. A cursory look at Finder seems to suggest that the importPaths retrieved in findInstalledHomeModule go untouched to the doesFileExist through searchPathExts. The working directories, at least as seen in the plugin body, is the directory of execution as expected, and is the same as the standalone program, but I could certainly be missing the whole picture in Finder.

I've attached a package that demonstrates what I've tested so far, along with Edward Yang's original solution I was following.

1. The standalone executable runs with `cabal run standalone`.
2. The plugin runs via ghc with the same command from the last email:

  ghc --frontend Plugin -itarget -package-db dist-newstyle/packagedb/ghc-8.6.5 Plugin -plugin-package plugin-test -hide-all-packages
 
3. Running the plugin per Edward Yang's solution needs to `cabal build` the wrapper and lib first, then invoking via `cabal repl target -w` with an absolute path to the plugin executable:

  cabal repl target -w "$(pwd)/dist-newstyle/build/<build-target>/ghc-<ghc-version>/plugin-test-0.1.0.0/x/plugin-wrapper/build/plugin-wrapper/plugin-wrapper"
 
  ...at least that's the path on my distribution. (Unfortunately it seems resolving the plugin by name alone doesn't seem to work >= 8.4.2).

In case 1, it works. In cases 2 and 3, I get "error: module ‘A’ cannot be found locally".

By the way, by "it does" I meant it does work when I use an absolute path.

Hope this sheds some light! Thanks so much,

Derek

On 2020-01-06, 07:32, "Ben Gamari" <[hidden email]> wrote:

    Derek Lam <[hidden email]> writes:
   
    > Hi ghc-devs,
    >
    Hi Derek,
   
    > I’m making a first attempt to make a frontend plugin, to resolve cabal
    > packages in the GHC API. However I’m running into troubles with module
    > resolution in the GHC API, because I can’t control where it will
    > search for modules at all. I've attached a minimal example, with a
    > frontend plugin definition that can’t find modules (Plugin.hs), and an
    > equivalent standalone program that does (Main.hs).
    >
    > Specifically, I'm following a solution Edward Yang published in 2017
    > (http://blog.ezyang.com/2017/02/how-to-integrate-ghc-api-programs-with-cabal/),
    > where the frontend plugin is called through a helper script that
    > passes flags forwarded from `cabal repl`. To test the plugin directly
    > with GHC, I collected the args through the helper script and filtered
    > them to the minimal set that made the plugin run:
    >
    >   ghc --frontend Plugin -itarget -package-db
    > dist-newstyle/packagedb/ghc-8.6.5 Plugin -plugin-package sandbox
    > -hide-all-packages
    >
    > This, as well as the full argument set, would complain that it can't
    > find the target module under `./target/A.hs`:
    >
    >   <no location info>: error: module ‘A’ cannot be found locally
    >
    > It does when the import path arg `-itarget` is absolute.
   
    By "it does" do you mean "it still fails"?
   
    > Still, its `importPaths` are what I expect: [".", "target"], and the
    > standalone program finds the target module with the same
    > `importPaths`. I've tested this in GHC 8.6.5, 8.4.2 and 8.2.2, making
    > me sure I'm just missing something, but I haven’t found help in the
    > docs yet. I really appreciate some help to draw my hours over this to
    > a close!
    >
    Hmm, very interesting. If I recall correctly, the relevant codepath in
    GHC is Finder.findImportedModule which should find the module via
    Finder.findHomeModule. Unfortunately, in my cursory look I didn't see
    any obvious issues; it looks like this might require a build of GHC and
    a bit of debugging. If you can produce a minimal, concrete reproducer
    (e.g. your plugin and a set of specific instructions to reproduce the
    issue) it's possible I can have a look.
   
    Cheers,
   
    - Ben
   


_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

plugin-test.tar.gz (1K) Download Attachment