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

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

Merged
merged 14 commits into from
Nov 4, 2018

Conversation

fgaz
Copy link
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
Collaborator

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

pretty (CFLibName str) = Disp.text "flib:" <<>> pretty str
pretty (CExeName str) = Disp.text "exe:" <<>> pretty str
pretty (CTestName str) = Disp.text "test:" <<>> pretty str
pretty (CBenchName str) = Disp.text "bench:" <<>> pretty str

instance Text ComponentName where
parse = parseComposite <++ parseSingle
Copy link
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)


instance Text Dependency where
parse = do name <- parse
Parse.skipSpaces
ver <- parse Parse.<++ return anyVersion
Parse.skipSpaces
return (Dependency name ver)
Copy link
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
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


instance Parsec Dependency where
parsec = do
name <- lexemeParsec
ver <- parsec <|> pure anyVersion
return (Dependency name ver)
Copy link
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
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
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
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
Collaborator

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

@phadej
Copy link
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
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
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
Member

@fgaz Yes, sure.


instance Parsec Dependency where
parsec = do
name <- lexemeParsec
libs <- option [LMainLibName]
Copy link
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
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
Member Author

fgaz commented Sep 7, 2018

@phadej Just tested it and only direct deps are passed

@phadej
Copy link
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
Contributor

ezyang commented Sep 15, 2018

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

@fgaz
Copy link
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"
}
haskell-pushbot pushed a commit to haskell-pushbot/cabal-binaries that referenced this pull request Nov 3, 2018
"url":"pull/5526",
"account":"haskell",
"repo":"cabal",
"commit": "a9fee729d714c06518183ad67a9fb4c4c44f14b9",
"tag":"linux-8.0.2"
}
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
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

@fgaz fgaz merged commit f8fe5d2 into haskell:master Nov 4, 2018
@Ericson2314
Copy link
Collaborator

Congrats!!!

fgaz added a commit to fgaz/cabal that referenced this pull request Jun 23, 2019
fgaz added a commit to fgaz/cabal that referenced this pull request Jun 26, 2019
fgaz added a commit that referenced this pull request Jun 26, 2019
(cherry picked from commit 4d2ca52)
23Skidoo pushed a commit to 23Skidoo/cabal that referenced this pull request Aug 9, 2019
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