Skip to content

[GSoC2018] Add support for multiple public libraries in a single package#5526

Merged
fgaz merged 14 commits into
haskell:masterfrom
fgaz:multiple-libraries-v4
Nov 4, 2018
Merged

[GSoC2018] Add support for multiple public libraries in a single package#5526
fgaz merged 14 commits into
haskell:masterfrom
fgaz:multiple-libraries-v4

Conversation

@fgaz
Copy link
Copy Markdown
Member

@fgaz fgaz commented Aug 14, 2018

This is my work for Google Summer of Code 2018.

It adds support for multiple public libraries, as described in #4206.

See https://github.com/fgaz/gsoc/blob/master/2018/final-report.md for a more detailed report. I'll expand a bit this description shortly.

There are still a few nonessential things to do and some things to clean, so don't review yet! (see the link above or the checklist below). It should all work though. Go ahead!

Closes #4206

/cc @ezyang @23Skidoo

Things to fix/clean/update before merging:

  • Add a few comments in crucial places
  • Unbreak the few tests that still fail
    • Adapt tests to new output
    • Legit breakages
      • Duplicate output on some tests
  • Clean the history
  • Make sure roundtripping works
    • Generate only LMainLibName libraries in ProjectConfig's extra-packages and show them as pkg-only syntax, either in Dependency itself or only in ProjectConfig
    • and/or remove Dependency from there
  • Clean up in a few places (memptys and todos)
  • Version guard the new functionality

After merging (better to merge soon and avoid to let it rot) (moved to #5660)

  • Add a visibility field to sublibraries
  • Maybe: remove all the bits of code that handle the old syntax (there's lots of them) and do it all in a single spot (hint: grep for packageNameToUnqualComponentName)
  • Add tests
  • Update changelog
  • Update docs
  • Maybe more source comments
  • Deprecate old syntax
  • Update cabal init to take into account sublibraries when populating build-depends

@fgaz fgaz added this to the 3.0 milestone Aug 14, 2018
@Ericson2314
Copy link
Copy Markdown
Collaborator

Oh man this overlaps a lot with my old #4265 . I wish I could have gotten you that earlier.

pretty (CBenchName str) = Disp.text "bench:" <<>> pretty str

instance Text ComponentName where
parse = parseComposite <++ parseSingle
Copy link
Copy Markdown
Collaborator

@phadej phadej Aug 14, 2018

Choose a reason for hiding this comment

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

This is used in command line parsers, doesn't it? Can you add a comment, as it's surprising to see Text instance in use. (and without corresponding Parsec instance)

Parse.skipSpaces
ver <- parse Parse.<++ return anyVersion
Parse.skipSpaces
return (Dependency name ver)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

... but editing this Text instance shouldn't affect anything.

Copy link
Copy Markdown
Member Author

@fgaz fgaz Aug 20, 2018

Choose a reason for hiding this comment

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

Why not? Isn't it used for display? display appears in quite a few places

parsec = do
name <- lexemeParsec
ver <- parsec <|> pure anyVersion
return (Dependency name ver)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Note: we need to case on askCabalSpecVersion.

@phadej
Copy link
Copy Markdown
Collaborator

phadej commented Aug 15, 2018

Also a dumb question, are all internal sublibraries public with this change? EDIT i.e. can be dependent upon.

@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Aug 15, 2018

@phadej Yup. But I'll add a visibility field shortly. (I just added a todo list to the description)

@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Aug 15, 2018

@Ericson2314 Yeah, I discovered that pr halfway through GSoC (and I actually tried to rebase it), but at that point my work diverged too much from that :-/ (I use Set LibraryName instead of a single library per dep).

I did not manage to separate the dependency-as-constraint from the dependency-dependency as you did, but I really think it should be done: https://github.com/fgaz/gsoc/blob/master/2018/final-report.md#the-dependency-as-constraint-problem

@Ericson2314
Copy link
Copy Markdown
Collaborator

Glad you found it and it was of some use :)

@phadej
Copy link
Copy Markdown
Collaborator

phadej commented Aug 16, 2018

@fgaz is there any part which can be separated into own PR and merged already (even it's little or even no use by itself alone)? ComponentName refactor looks like that at a first glance.

@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Aug 16, 2018

@phadej yup, that and the GivenComponent one probably.

Also note that the LibraryName refactor could be much more complete, but I ran into some problems (I probably just forgot something. I'll have to recheck why the tests broke)

@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Aug 16, 2018

Is it ok if I add the visibility field in another pr after the merge, so we merge soon and avoid conflicts?

@23Skidoo
Copy link
Copy Markdown
Member

@fgaz Yes, sure.

@fgaz fgaz force-pushed the multiple-libraries-v4 branch from 56a3c0d to b57838f Compare August 29, 2018 20:21
instance Parsec Dependency where
parsec = do
name <- lexemeParsec
libs <- option [LMainLibName]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Note: this should be guarded by askCabalSpecVersion

@phadej
Copy link
Copy Markdown
Collaborator

phadej commented Sep 5, 2018

23:21 phadej what if there is pkgA:lib; then pkgB depends on pkgA:lib but looks like "ordinary" package outside. These both are required to have recent cabal-version: 3.0 or like that
23:21 phadej but then there's pkgC which depends on pkgB, and has cabal-version: 1.12 and build-type: Custom
23:21 phadej will its Setup.hs be passed --dependency=pkg:component=id ?

or is only direct dependencies are passed. Anyway, build-type: Custom have to we thought out properly, as there we have to speak with old Cabal code.

@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Sep 7, 2018

@phadej Just tested it and only direct deps are passed

@phadej
Copy link
Copy Markdown
Collaborator

phadej commented Sep 7, 2018

@fgaz that's good news 👍

hvr added a commit to hvr/cabal that referenced this pull request Sep 8, 2018
…nfigure`

In the course of 4466310 (see haskell#5526) the
`Setup.hs haddock` CLI was extended to allow component ids to be passed
as positional arguments. However, `autoconfUserHooks` which is used in
case of `build-type: Configure` wasn't updated accordingly, and consequently
this caused `new-haddock` to break for packages using `Configure`.

Fixes haskell#5503
hvr added a commit to hvr/cabal that referenced this pull request Sep 8, 2018
…nfigure`

In the course of 4466310 (see haskell#5526) the
`Setup.hs haddock` CLI was extended to allow component ids to be passed
as positional arguments. However, `autoconfUserHooks` which is used in
case of `build-type: Configure` wasn't updated accordingly, and consequently
this caused `new-haddock` to break for packages using `Configure`.

cc @alexbiehl

Fixes haskell#5503
hvr added a commit that referenced this pull request Sep 8, 2018
…nfigure`

In the course of 4466310 (see #5526) the
`Setup.hs haddock` CLI was extended to allow component ids to be passed
as positional arguments. However, `autoconfUserHooks` which is used in
case of `build-type: Configure` wasn't updated accordingly, and consequently
this caused `new-haddock` to break for packages using `Configure`.

cc @alexbiehl

Fixes #5503

(cherry picked from commit 86dabda)
@ezyang
Copy link
Copy Markdown
Contributor

ezyang commented Sep 15, 2018

@fgaz Do you want us to review now? :)

@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Sep 16, 2018

@ezyang Sorry, not yet. Just wait a literal couple of days

haskell-pushbot pushed a commit to haskell-pushbot/cabal-binaries that referenced this pull request Sep 17, 2018
"url":"pull/5526",
"account":"haskell",
"repo":"cabal",
"commit": "63f4c37a1b0a267029e5b9e12d58fb0759a22e11",
"tag":"linux-7.6.3"
}
haskell-pushbot pushed a commit to haskell-pushbot/cabal-binaries that referenced this pull request Sep 17, 2018
"url":"pull/5526",
"account":"haskell",
"repo":"cabal",
"commit": "63f4c37a1b0a267029e5b9e12d58fb0759a22e11",
"tag":"linux-7.8.4"
}
haskell-pushbot pushed a commit to haskell-pushbot/cabal-binaries that referenced this pull request Sep 17, 2018
"url":"pull/5526",
"account":"haskell",
"repo":"cabal",
"commit": "63f4c37a1b0a267029e5b9e12d58fb0759a22e11",
"tag":"osx-7.8.4"
}
haskell-pushbot pushed a commit to haskell-pushbot/cabal-binaries that referenced this pull request Sep 18, 2018
"url":"pull/5526",
"account":"haskell",
"repo":"cabal",
"commit": "887eb3352fc6f923e46bc3cb24c0de89292165bb",
"tag":"linux-7.10.3"
}
haskell-pushbot pushed a commit to haskell-pushbot/cabal-binaries that referenced this pull request Sep 18, 2018
"url":"pull/5526",
"account":"haskell",
"repo":"cabal",
"commit": "887eb3352fc6f923e46bc3cb24c0de89292165bb",
"tag":"linux-8.0.2"
}
@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Oct 5, 2018

@ezyang

Thanks for the review! Good catches!

I'll remove those todos and that undefined and merge then

If default visibility is public there are no objections here.

I think you mean private?

Sublibraries do become public by default with this pr, but only because there's no visibility flag yet, which will default to private

@ezyang
Copy link
Copy Markdown
Contributor

ezyang commented Oct 5, 2018

Sublibraries do become public by default with this pr, but only because there's no visibility flag yet, which will default to private

I'm primarily pointing out that changing the default from public to private is a BC-breaking change. If you do it quickly enough no one will notice, but if you don't...

brought into scope by mixins: fail:postgresql (Database.PostgreSQL as Database)
While filling requirements of build-depends: fail:mylib
While filling requirements of build-depends: fail:mylib
and build-depends: fail:mylib
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@ezyang

Any pointers on fixing the duplicate output? I think it may be some only-main-lib code I didn't delete when adding multilib handling. It does not affect functionality

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No, I'd have to investigate.

@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Oct 17, 2018

I'm going to merge this later today unless someone objects.

@ezyang I'll make sure to add the visibility field before the 3.0 release

@23Skidoo
Copy link
Copy Markdown
Member

23Skidoo commented Oct 17, 2018

What about the duplicate output on some tests?

edit: ...and the "add a few comments in crucial places" bit?

@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Oct 18, 2018

@23Skidoo I wasn't able to pinpoint the cause, but it seems not to affect functionality. Should I delay the merge until I fix it?

@23Skidoo
Copy link
Copy Markdown
Member

23Skidoo commented Nov 1, 2018

Well, it's just that you have that in your "to be fixed before merge" column.

@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Nov 2, 2018

@23Skidoo please don't merge yet. I think I found the issue. I'll merge it myself when it's fixed

fgaz added 14 commits November 3, 2018 15:46
The old --dependency could only do --dependency=pkg=cid,
but with public sublibraries this will become insufficient.

Now there is the option to also specify a component name using
--dependency=pkg:component=cid
Before, a 3-tuple was used
This gives us more type safety when dealing with libraries only
Create a new syntax for depending on any library of any package.
The syntax is

    build-depends: pkgname:{pkgname, sublibname} -any

where the second `pkgname` specifies a dependency on the main unnamed
library.

Closes haskell#4206.
Dependency is used in two seemingly related but now incompatible ways:

* As a dependency specification ("I want this component from this package,
  version range xy")
* As a constraint ("Package p must be in version range xy")

This commit begins to separate the two concepts.
We generated them both the old way (only internal libs) and the new way
(arbitrary sublibraries), leading to this:

    $ cabal new-configure my-package -v
    [...]
    Component graph for my-package-0.2.0.0: component exe:my-exe
    component my-package-0.2.0.0-inplace-my-exe
        include base-4.11.1.0
        include base-4.11.1.0
        include word8-0.1.3-968d6922e82a4ae480d10bc205e047a27af7804ae8fb577c4b6eeb868f99ee3b
        include word8-0.1.3-968d6922e82a4ae480d10bc205e047a27af7804ae8fb577c4b6eeb868f99ee3b
    [...]

...which didn't have any effect on the build except for some duplicate
output, but could lead to problems in the future.

Now we only generate them the new way.
This reverts commit 1c4ad06.

The previous commit fixed it
@fgaz
Copy link
Copy Markdown
Member Author

fgaz commented Nov 3, 2018

It's ready, but appveyor continues to fail with this error:

ghc-pkg.exe: cannot create: C:\Users\appveyor\AppData\Roaming\cabal\store\ghc-8.0.2\package.db already exists

Is that normal/something that happens often?

edit: I don't have a windows machine on which to test it.
edit2: fixed

@Ericson2314
Copy link
Copy Markdown
Collaborator

Congrats!!!

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.

Multiple public libraries in a package

5 participants