-
Notifications
You must be signed in to change notification settings - Fork 89
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
Allow GHCup to build & run on OpenBSD #1138
base: master
Are you sure you want to change the base?
Conversation
This is necessary to start supporting OpenBSD, as the versions in ports are quite recent (in recent versions of OpenBSD, of course).
`libarchive` (the Haskell package, not its upstream C library) vendors the `config.h` header files generated by autoconf for each platform it supports instead of using autoconf (or even CMake, which the C library offers as an option). So apart from those specific platforms, just use `tar` & `zip`. `lzma-static` currently does the same, but we're gonna fix it upstream then update the minimum version bounds on our dependency of it.
GHCup currently doesn't run on OpenBSD (or any platform not explicitly supported), even if it builds. This adds explicit support for OpenBSD. We may later not block it from running on unsupported platforms, even when we don't explicitly make sure our build scripts work for them or provide bindists or CI for them.
@@ -229,6 +229,7 @@ data Platform = Linux LinuxDistro | |||
| Darwin | |||
-- ^ must exit | |||
| FreeBSD | |||
| OpenBSD |
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.
This is a breaking change and will require us to create a new metadata file/version. So it's good to aggregate breaking changes, as in: add NetBSD
and any other BSD you can think of.
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.
Why is it a breaking change (beyond having to change all the places where Platform
type is used, which is done in this PR)? Aren't the metadata files just YAML (last time I checked)?
Off the top of my head, I can think of NetBSD, PC-BSD, DragonflyBSD, helloSystem; not sure of the status of PC-BSD or helloSystem (which is probably still in early stages, as that one's quite ambitious).
Apart from FreeBSD, though, OpenBSD is probably the next most popular one (or may even be on par, as it's known for having developers that actually use it day-to-day instead of a macOS system).
Anyway, adding these other systems will require some more research. I'm sure they'll package or pre-install xdg-open
, it's unlikely they have their own homerolled solution to that, but what about, e.g. version checking? uname -r
, or do they have their own special one like FreeBSD, especially those that forked off from it?
If we want to expand support as widely as possible, the current approach seems untenable. More troublingly, the idea that any new Platform requires backwards-incompatible changes to the metadata file format, but even the idea of grouping Linux distros under one Platform
and having a Distro
type seems quite arbitrary.
How much more similar to each other are Linux distros compared w/ BSD variants to each other? How about grouping BSDs together, or macOS as a BSD, or all POSIXy systems under a POSIX Platform
? What about formerly Linux distros that now offer the option of running with a BSD kernel but same userland, header locations, package manager, etc.?
We should think about having sensible defaults to standards like POSIX or non-standard but widespread things like xdg-open
, then for anything outside of that, delegating to external adapters which adhere to a formal API for extending GHCup with support for other platforms.
If we wanted to, we could hardcode support for anything with enough popularity/maintainers, but ideally, even officially supported platforms would just use external but first-party adapters. Hell, even the fallback behaviour could just be an adapter, although that seems unnecessary.
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.
@habibalamin this is breaking change because of derived instance for Platform
will break for people using older ghcup
, when the metadata is updated to contain "openbsd". (see ToJSONKey Platform
)
So unless the addition of openbsd happens in LinuxDistros
as "Linux_OpenBSD", any other change would require a metadata version bump.
So I suggest that just like Linux LinuxDistro
, a new BSD BSDDistro
is created to capture all the flavours. And the metadata migration could be simply "FreeBSD:" to "BSD_FreeBSD:" conversion.
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 I suggest that just like
Linux LinuxDistro
, a newBSD BSDDistro
is created to capture all the flavours. And the metadata migration could be simply "FreeBSD:" to "BSD_FreeBSD:" conversion.
From what I know the BSDs are not really binary compatible and even run different kernels. So I'm not sure how we can call those "distros". I know there exist FreeBSD distros, but calling FreeBSD a BSD distro itself seems like a stretch. OpenBSD and FreeBSD are entirely separate operating systems, no?
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 have no idea about BSDs in general.
How about this we add a OtherOS OSType
and capture everything under this umbrella type.
We can keep FreeBSD
as it is in this case, at top level Platform, but do all new additions under OtherOS
?
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.
older ghcup should at least be able to read the metadata containing newer OS fields. Whether it can handle that correctly should not be an expectation
Yes, forward-compatibility is desirable. For the platforms, we use the FromJSONKey
parser:
ghcup-hs/lib/GHCup/Types/JSON.hs
Lines 148 to 168 in 9d6f101
instance FromJSONKey Platform where | |
fromJSONKey = FromJSONKeyTextParser $ \t -> if | |
| T.pack "Darwin" == t -> pure Darwin | |
| T.pack "FreeBSD" == t -> pure FreeBSD | |
| T.pack "Windows" == t -> pure Windows | |
| T.pack "Linux_" `T.isPrefixOf` t -> case | |
T.stripPrefix (T.pack "Linux_") t | |
of | |
Just dstr -> | |
case | |
(decodeStrict (E.encodeUtf8 (T.pack "\"" <> dstr <> T.pack "\"")) :: Maybe | |
LinuxDistro | |
) | |
of | |
Just d -> pure $ Linux d | |
Nothing -> | |
fail | |
$ "Unexpected failure in decoding LinuxDistro: " | |
<> show dstr | |
Nothing -> fail "Unexpected failure in Platform stripPrefix" | |
| otherwise -> fail "Failure in Platform (FromJSONKey)" |
I'm not sure how to write a FromJSONKey parser that ignores keys it doesn't understand, without messing with the types on the Haskell side.
I'm not sure I want an OtherPlatform
constructor.
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.
Yeah no way to fix this without Haskell side type changes or a catch all UnknownPlatform
constructor
The way to ignore unknown keys would require custom instance for Map
. Though we would want to do this only for reading metadata in ghcup, and use the usual instance for check of metadata.
type PlatformReqSpec = MapWithIgnore Platform PlatformReqVersionSpec
It may be good to use this for arch as well. as the (never mind we won't be running tools on these archs)wasm32
or js*
will arrive some time in future
type ArchitectureSpec = MapWithIgnore Architecture PlatformSpec
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.
The way to ignore unknown keys would require custom instance for Map. Though we would want to do this only for reading metadata in ghcup, and use the usual instance for check of metadata.
You mean a newtype for Map? Or a custom overloaded instance?
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 newtype MapIgnoreUnknownKeys
which will only be used for reading yaml, then it will be converted to Map, and rest of code remains same
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.
Sounds ok
@@ -0,0 +1,61 @@ | |||
packages: ./ghcup.cabal |
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.
There's already #1132 and we probably need to merge/fix that first.
Fix #707.
This doesn't ensure that GHCup's build scripts/manifests work for OpenBSD, merely that it builds and runs on OpenBSD.