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

UCRT64 support for msys2 on Windows? #982

Closed
karamellpelle opened this issue Jan 21, 2024 · 20 comments · Fixed by #992
Closed

UCRT64 support for msys2 on Windows? #982

karamellpelle opened this issue Jan 21, 2024 · 20 comments · Fixed by #992

Comments

@karamellpelle
Copy link

msys2 suggest using the UCRT64 environment. GHCup's msys2 uses the MINGW64 environment.

UCRT64 is the environment that links to the newer Windows UCRT library1, and MINGW64 links to the older MSVCRT library2.

Is it possible to build Haskell using the newer UCRT64 environment? And are there any benefits? I like being progressive.

Footnotes

  1. Differences between msvcrt, ucrt and vcruntime libraries

  2. MSYS2: What's the difference between UCRT 64 and x64?

@hasufell
Copy link
Member

I don't know, I've never tried.

@bgamari
Copy link
Collaborator

bgamari commented Jan 21, 2024

GHC upstream has not used MINGW64 since #21019. I suspect that ghcup should migrate as well.

@karamellpelle
Copy link
Author

karamellpelle commented Jan 21, 2024

I have no experience with Haskell development on Windows.

How am I supposed to "professionally" build Haskell on Windows, i.e., build .exe files that can be released public? I can either build Haskell code using the msys2 environment (which I like because it works like Linux), or PowerShell (ghc, stack, etc are available here too). Are there any differences in builds between msys2 or PowerShell build environments?

@hasufell
Copy link
Member

hasufell commented Jan 22, 2024

It's recommended to use PowerShell.

Msys2 shell environment should not be needed to build haskell packages.

@hasufell
Copy link
Member

GHC upstream has not used MINGW64 since #21019. I suspect that ghcup should migrate as well.

Why exactly UCRT64 and not CLANG64? Can you elaborate?

Afais, stack also uses MINGW64: https:/commercialhaskell/stack/blob/4ad539e34b3689dfa3039412fddd9f5c69988f16/src/Stack/Setup/Installed.hs#L161-L174

@mpilgrem @Mistuke

@mpilgrem
Copy link
Contributor

I am a Windows user. On Windows, Stack uses (and supplies, in the Stack environment) the same MSYS2 you get if you install MSYS2 from MSYS2's web site: https://docs.haskellstack.org/en/stable/maintainers/msys/. Once Stack has fetched MSYS2, it does not fetch it again unless you delete it from Stack's programs directory: https://docs.haskellstack.org/en/stable/stack_root/#programs-directory.

I bump the MSYS2 version that Stack fetches when somebody says it needs bumping for some reason. Currently Stack fetches MSYS2 as it was on 2023-05-26.

As to how Stack currently uses MSYS2, I do not have the full inventory to hand, but I think it is relatively minor; I think in a few places it makes use of the sh, env and locale commands supplied by MSYS2.

Sometime, I have found a Haskell package needs a C library (packages depending on the GTK project come to mind) and I've used the Stack-supplied MSYS2/pacman to fetch that library and put it somewhere Stack knows about.

@hasufell
Copy link
Member

@mpilgrem as indicated above, MSYS2 has multiple environments. Stack will add include/lib/bindir of the MINGW64 environment: https:/commercialhaskell/stack/blob/4ad539e34b3689dfa3039412fddd9f5c69988f16/src/Stack/Setup/Installed.hs#L161-L174

@bgamari and @karamellpelle suggest that this environment is "deprecated". This affects installing C packages/linking etc.

E.g. see:

@mpilgrem
Copy link
Contributor

mpilgrem commented Jan 22, 2024

Do the environments 'conflict'? That is, should Stack switch from adding one set of directories to adding another set, or should Stack augment the existing directories by also adding other directories? EDIT: If they conflict, I guess I should add a configuration option to Stack to allow users to choose which MSYS2 environment they prefer.

@karamellpelle
Copy link
Author

It's recommended to use PowerShell.

Msys2 shell environment should not be needed to build haskell packages.

So the msys2 installed (and added to Desktop) by GHCup should be considered as a playground for Haskell?

Will compiled executables differ if compiled through PowerShell or msys2 (i.e. MINGW64)?

I ask since I have no Windows programming experience in general, only Linux and macOS. I would like to know how I am supposed to do professional Haskell programming on Windows, that is, building applications that can be released publicly. I bought a laptop with Windows for other work, but found Windows 11 to actually be a pretty well working OS I can enjoy in other ways.

@mpilgrem
Copy link
Contributor

mpilgrem commented Jan 22, 2024

@karamellpelle, I understand you to ask: How can I build executables using Haskell on Windows? There is more than one way to do that, but this is what I do:

  1. Get Windows Terminal (comes with Windows 11), Visual Studio Code, the Haskell extension for VS Code, and Stack (https://docs.haskellstack.org/en/stable/).
  2. Use Stack to create a simple project from a template: command stack new my-project.
  3. Edit the project to be what I want, using VS Code.
  4. Build the project using Stack, creating executables: command stack build. Stack will fetch the compiler (GHC) that it needs, if it does not have it. Stack will fetch MSYS2, if it does not have it.
  5. Sometimes, build executable and also install on the path, using Stack: stack install.

(Some people use Cabal (the tool) in preference to Stack. Unlike Stack, Cabal will not fetch things. However, people also use GHCup. GHCup can install various things related to Haskell: GHC, Cabal, Stack, HLS (the technology behind the Haskell extension for VS Code). I use GHCup to manage HLS and use Stack to manage GHC and Stack. EDIT: You can also get Stack to manage GHC via GHCup.)

@karamellpelle
Copy link
Author

Yes, stack is the way to go for Haskell development. I prefer console development, but I see there is a (neo)vim plugin for VS/VS Code, so maybe I should develop Haskell through Visual Studio (could be a nice thing to learn anyway because I understand that's how professional Windows development are done, like XCode on macOS).

The included msys2 from GHCup is very nice. I started using it for all kind of things on Windows like git, ssh and gpg. So I could really like to do my Haskell development through msys2. I'm just unsure if the msys2 (i.e. MINGW32) build environment is good enough since it is so closely connected to Linux. Will it for example link to local MINGW64 libraries so that the compiled executables are not portable?

Will the same Stack project built through Windows PowerShell produce a different kind of executables that are of "professional"/"Windows native" sort?

My uncertainty is also the reason behind my question if a the modern environment UCRT64 for msys2 is the better choice.


I'm going to install a dual boot Arch Linux on my new laptop, but I would like to learn and do some Haskell Windows development too.

@mpilgrem
Copy link
Contributor

@karamellpelle, what Visual Studio (proper) and XCode provide is an environment where the software provides hints etc to help you code. That is what the Haskell extension for VS Code does too; it provides hints etc to help you code in Haskell.

You don't need MSYS2 to use tools like git, ssh and gpg. All of them available for, or come with, Windows.

The short answer to your question "Will the same Stack project built through Windows PowerShell produce a different kind of executable?" is No.

If you want to use Windows and Linux on the same machine, WSL2 is the way to go. Through my own Windows Terminal tabs I use Windows 11/PowerShell, Ubuntu Linix and Alpine Linux.

@mpilgrem
Copy link
Contributor

@karamellpelle, an issue at the haskell/ghcup-hs GitHub repository is likely not the best place to have this broader discussion. I suggest you raise things in the Learn category of this place: https://discourse.haskell.org/. People there are generally helpful; a thoughtful question usually prompts a thoughtful answer.

@Mistuke
Copy link

Mistuke commented Jan 22, 2024

GHC upstream has not used MINGW64 since #21019. I suspect that ghcup should migrate as well.

Why exactly UCRT64 and not CLANG64? Can you elaborate?

Afais, stack also uses MINGW64: https:/commercialhaskell/stack/blob/4ad539e34b3689dfa3039412fddd9f5c69988f16/src/Stack/Setup/Installed.hs#L161-L174

@mpilgrem @Mistuke

The package by no means is deprecated. It's GHC that doesn't use it anymore. But both of these are still active.

The only difference between MINGW64 and CLANG64 is that the former is compiled by GCC and the latter by clang.

So in general it does not matter which one you pick. They should both work interchangeably.

In practice the clang64 one will potentially give more errors as clang had several non-standard extensions that are not yet supported in the GHC dynamic linker.

Conversely however because of the deprecation status of the Windows POSIX extensions in msvcrt but undeprecation in ucrt one program may fail with the one and succeed with the other so it's better to be consistent.

The best answer here is probably that it's best to stick to whatever environment the compiler is with (so of you install pre 9.6 versions it shouldn't use clang64). But again this does have the risk of having constructs in the import libraries that GHC doesn't support and that aren't documented.

@mpilgrem
Copy link
Contributor

mpilgrem commented Jan 22, 2024

@Mistuke, may I pick your brains on my question above #982 (comment)?

At the moment, Stack on Windows 64-bit automatically adds mingw64\include to extra-include-dirs, and mingw64\lib and mingw64\bin to extra-library-dirs.

I am thinking that perhaps Stack should have a configuration option:

msys2-environment: mingw64 # Default value if not set (for historical consistency)

that would allow a user, say, to swap ucrt64\include for mingw64\include etc if it was set to ucrt64 etc.

@hasufell
Copy link
Member

From the comments above, my gut feeling is that we will stick to MINGW64 for now.

However, I think ghcup should expose an env var that allows users to pick the environment during installation. This will also require a new release to the binary, because e.g. ghcup run --mingw-path hardcodes the mingw64 subdir.

@Mistuke
Copy link

Mistuke commented Jan 26, 2024

@Mistuke, may I pick your brains on my question above #982 (comment)?

At the moment, Stack on Windows 64-bit automatically adds mingw64\include to extra-include-dirs, and mingw64\lib and mingw64\bin to extra-library-dirs.

I am thinking that perhaps Stack should have a configuration option:

msys2-environment: mingw64 # Default value if not set (for historical consistency)

that would allow a user, say, to swap ucrt64\include for mingw64\include etc if it was set to ucrt64 etc.

Possibly. The by far. Most important thing is consistency. That is to say. When using mingw64 you shouldn't install clang64 libraries. And vise versa.

When it comes to the compiler it's pretty self contained. Also dynamically linking will always go right. It's static linking that may cause issues.

So a config can be useful, but even with that it's more important to have consistency in whatever the user picks

@hasufell hasufell added this to the 0.1.22.0 milestone Jan 26, 2024
@mpilgrem
Copy link
Contributor

An observation: This GHC wiki page refers only to the MINGW64 environment of MSYS2: https://gitlab.haskell.org/ghc/ghc/-/wikis/building/preparation/windows.

hasufell added a commit that referenced this issue Jan 29, 2024
hasufell added a commit that referenced this issue Jan 29, 2024
hasufell added a commit that referenced this issue Jan 29, 2024
hasufell added a commit that referenced this issue Feb 1, 2024
hasufell added a commit that referenced this issue Feb 2, 2024
hasufell added a commit that referenced this issue Feb 9, 2024
@hasufell
Copy link
Member

haskell/cabal#9713

hasufell added a commit that referenced this issue Feb 17, 2024
hasufell added a commit that referenced this issue Feb 17, 2024
hasufell added a commit that referenced this issue Feb 18, 2024
hasufell added a commit that referenced this issue Feb 18, 2024
@Febbe
Copy link

Febbe commented Oct 15, 2024

The only difference between MINGW64 and CLANG64 is that the former is compiled by GCC and the latter by clang.

So in general it does not matter which one you pick. They should both work interchangeably.

Not directly true, all C libraries are linked to ucrt. libraries with UCRT are not interchangeably linkable with libs linked to msvcrt.

On top, all c++ libraries are linked and compiled to libc++ instead of libstdc++. So C++ libraries are incompatible to those compiled by gcc.

Only C libraries of UCRT64 are therefore vice versa compatible to clang64 libraries.

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

Successfully merging a pull request may close this issue.

6 participants