-
Notifications
You must be signed in to change notification settings - Fork 105
Foreign Library Stanza #518
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
base: main
Are you sure you want to change the base?
Conversation
I do not know why the CI is failing for Windows/'system' GHC (being GHC 9.6.2). I logged https://gitlab.haskell.org/ghc/ghc/-/issues/23533 as it seems to be GHC-related. Locally, I can build and test ( resolver: nightly-2023-06-18 # GHC 9.4.5
compiler: ghc-9.6.2
extra-deps:
# GHC 9.6.2 boot libaries
- Cabal-3.10.1.0
- Cabal-syntax-3.10.1.0
- directory-1.3.8.1
- time-1.12.2
- process-1.6.17.0
- Win32-2.13.3.0
# Required because the Stackage snapshot versions do not support GHC 9.6.2
- semigroupoids-6.0.0.1
- bifunctors-5.6.1 |
Thanks @mpilgrem. |
d7a929d
to
1283b79
Compare
I have rebased on the |
a6b1a8c
to
19e49dc
Compare
@sol, I think this is good to merge. Do you want to review? |
@mpilgrem I rebased again. But commits don't seem to be squashed yet. |
@sol, I've squashed but I was not sure if your review was complete subject to that? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First, despite what I was saying earlier, I want to raise the questions "Do we really want this?" and "Is this within the scope of Hpack?"
For Linux I don't know, I think you usually would go the other way around and use foreign imports. Are there any plausible use cases? If it is just for experimentation, then it would probably be outside the scope of Hpack.
For Windows however, the GHC documentation provides a VBA example. So if people wanna move business logic from Excel to Haskell then I can sympathize with that.
Maybe that's enough as a justification?
EDIT: I think this can actually be useful in combination with Python and ctypes
, so let's go for it.
Regarding the implementation, I think type
is a no-brainer, just remove it.
options
on the other hand is more complicated. From what I understand, if we drop options
then you would unconditionally need to generate
if os(Windows)
options: standalone
While this is in line with "Don't require the user to state the obvious" I'm still puzzled how we would achieve "Give the user 100% control when needed" here? I think a user will not be able to override this with verbatim
. But maybe just drop it anyway and address the 100% control thing once somebody asks for it?
BTW: I kind of think that if we decide to include this feature then we should probably include a complete example in the README, similar to what the GHC documentation contains, so that a user does not need to traverse three different manuals to make sense of this. EDIT: Even simple examples are still more complicated than I would hope for, so I'm not gonna insist on this just yet.
executableMap <- toExecutableMap packageName packageConfigExecutables packageConfigExecutable | ||
let | ||
globalVerbatim = commonOptionsVerbatim g | ||
globalOptions = g {commonOptionsVerbatim = Nothing} | ||
|
||
executableNames = maybe [] Map.keys executableMap | ||
componentNames = maybe [] Map.keys executableMap ++ maybe [] Map.keys foreignLibraryMap |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specifically I think the old is just fine, we don't need to update this.
@@ -611,6 +640,8 @@ data PackageConfig_ library executable = PackageConfig { | |||
, packageConfigCustomSetup :: Maybe CustomSetupSection | |||
, packageConfigLibrary :: Maybe library | |||
, packageConfigInternalLibraries :: Maybe (Map String library) | |||
, packageConfigForeignLibraries :: Maybe (Map String foreignLib) | |||
, packageConfigForeignLibrary :: Maybe foreignLib |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the idea here is that in addition to foreign-libraries
, we also accept foreign-library
where the name defaults to the package name.
I'm still undecided whether I think this is a good idea or not, but if you're gonna do that, then we need a test for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it is actually a good idea, so let's add the test.
content = [i| | ||
foreign-library #{name} | ||
other-modules: | ||
Paths_my_package |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding the Paths_
module is a historic mistake. Maybe we shouldn't repeat that mistake for foreign libraries?
@@ -151,6 +151,7 @@ library: | |||
| `custom-setup` | · | | See [Custom setup](#custom-setup) | | | | |||
| `flags` | `flag <name>` | | Map from flag name to flag (see [Flags](#flags)) | | | | |||
| `library` | · | | See [Library fields](#library-fields) | | | | |||
| `foreign-libraries` | `foreign-library <name>` | | Map from foreign library name to a dict of [Foreign library fields](#foreign-library-fields) and global top-level fields. | | UNRELEASED | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation for foreign-library
is missing here.
options: | ||
standalone | ||
|]) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A test for foreign-library
is missing here.
| `type` | . | | | | ||
| `lib-version-info` | . | | | | ||
| `options` | . | | | | ||
| `mod-def-file` | . | | | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though Cabal and GHC support this, I don't really see a use case for it. Why the hell would you add a foreign export
declaration for something, only to later hide it with a mod-def-file
?
My verdict is, unless we can come up with a sensible use case for this, remove it.
| `lib-version-info` | . | | | | ||
| `options` | . | | | | ||
| `mod-def-file` | . | | | | ||
| `other-modules` | · | All modules in `source-dirs` less `main` less any modules mentioned in `when` | | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the documentation actually correct?
| `options` | . | | | | ||
| `mod-def-file` | . | | | | ||
| `other-modules` | · | All modules in `source-dirs` less `main` less any modules mentioned in `when` | | | ||
| `generated-other-modules` | | | Added to `other-modules` and `autogen-modules`. Since `0.23.0`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was just copied from executables! At least the Since
annotation is not needed anymore.
@@ -194,6 +197,7 @@ renameDependencies old new sect@Section{..} = sect {sectionDependencies = (Depen | |||
packageDependencies :: Package -> [(String, DependencyInfo)] | |||
packageDependencies Package{..} = nub . sortBy (comparing (lexicographically . fst)) $ | |||
(concatMap deps packageExecutables) | |||
++ (concatMap deps packageForeignLibraries) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to this pull request, but I think this code does not handle internal libraries correctly. I think we need a separate issue or PR for that.
@@ -176,6 +178,7 @@ package name version = Package { | |||
renamePackage :: String -> Package -> Package | |||
renamePackage name p@Package{..} = p { | |||
packageName = name | |||
, packageForeignLibraries = fmap (renameDependencies packageName name) packageForeignLibraries |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, internal libraries are not handled here. If internal libraries cannot depend on the main library, then we are actually good. I'm not sure what's the situation here.
I think currently nobody is using this code, so maybe not a big issue. We could potentially deprecate it.
@mpilgrem I'm probably busy tomorrow, but gonna try to look at it again on Monday. |
hpack
?test/EndToEndSpec.hs
?Addresses #258.
Adds the following syntax to support foreign / shared libraries so we dont need to use the verbatim block anymore: