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

Allow GHCup to build & run on OpenBSD #1138

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

habibalamin
Copy link

@habibalamin habibalamin commented Oct 21, 2024

Fix #707.

This doesn't ensure that GHCup's build scripts/manifests work for OpenBSD, merely that it builds and runs on OpenBSD.

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.
@habibalamin habibalamin changed the title Add OpenBSD support Allow GHCup to build & run on OpenBSD Oct 21, 2024
@@ -229,6 +229,7 @@ data Platform = Linux LinuxDistro
| Darwin
-- ^ must exit
| FreeBSD
| OpenBSD
Copy link
Member

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.

Copy link
Author

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.

Copy link
Collaborator

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.

Copy link
Member

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 new BSD 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?

Copy link
Collaborator

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?

Copy link
Member

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:

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.

Copy link
Collaborator

@dfordivam dfordivam Oct 27, 2024

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 wasm32 or js* will arrive some time in future (never mind we won't be running tools on these archs)
type ArchitectureSpec = MapWithIgnore Architecture PlatformSpec

Copy link
Member

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?

Copy link
Collaborator

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

Copy link
Member

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

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add OpenBSD and NetBSD?
3 participants