haskell / filepath

Haskell FilePath core library
BSD 3-Clause "New" or "Revised" License
66 stars 33 forks source link

On MinGW, POSIX-style paths should be considered absolute #208

Closed jasagredo closed 7 months ago

jasagredo commented 7 months ago

The function isRelative considers a path to be relative if it has no drive on it. For that matter, /mingw64 is considered a relative path, although it is an absolute one, as MinGW understands POSIX-style filepaths

❯ cabal repl --build-depends filepath
ghci> isRelative "/mingw64/include"
True
ghci> takeDrive "/mingw64/include"
""
ghci>
Leaving GHCi
❯ test -d /mingw64 && echo $?
0

The Windows Haskell installation seem to need to run in mingw and not directly on a fresh windows system. Therefore filepaths there could either be Windows-like or POSIX-like, and both should work.

This is the root-cause for haskell/cabal#9479 (and the issues referenced there) and I have the suspicion that this is a very fundamental issue (nothing that receives POSIX-like paths on MinGW can work if it checks whether they are relative).

Note that MinGW sometimes offer full paths as /c/... instead of C:\..., which would lead to the same result (they would be considered relative).

hasufell commented 7 months ago

The Windows Haskell installation seem to need to run in mingw and not directly on a fresh windows system.

That's not correct.


I'm also not sure what you are proposing.

This library can't magically know what you mean. The posix and windows variants are always available on both platforms:

Then there is a 3rd module where the implementation depends on the compile time platform:

"Being inside an msys2 shell" is not something you can detect during compile time, so it's up to the application to figure out what paths to accept and how to interpret them.

Note that msys2 shell can convert the paths via cygpath: https://www.msys2.org/docs/filesystem-paths/

Which also states:

When calling native executables from the context of Cygwin then all the arguments that look like Unix paths will get auto converted to Windows.

So I'm assuming cabal does something wrong here.

jasagredo commented 7 months ago

I thought Haskell was meant to be run in mingw because the binaries for GHC on Windows are labeled mingw. But I imagine it can run then in whatever Windows environment?

About the path translation, I think this is not a cabal issue (I could be wrong) as I could t find where it is calling for the cflags. I think ghc-pkg does that regardless of Cabal.

However, taking into account the point you make about the application being responsible for the translation, this can probably be an issue of pkgconf itself not translating the posix paths it finds in the pc config files.

However, by the same reasoning, ghc (or ghc-pkg for that matter) could be also considered responsible for translating any posix paths it finds into windows paths? That claim says "all the arguments that look like Unix paths". Are the results of calling pkgconf considered "arguments"?

jasagredo commented 7 months ago

The issue that brought all this seem to be solved as seen here https://github.com/haskell/cabal/issues/9479#issuecomment-1826772061. It is a bug in the package itself as @hasufell suggested (thanks!).

And for that matter, arguments that are given to ghc or ghc-pkg indeed are translated before being passed:

❯ ghc-pkg --package-db /c/Users/Javier list
C:/Users/Javier
    (no packages)

I wonder however what happens when Haskell calls another native program providing a posix path. Will it be translated on the fly? I might try later today 😌

But I guess that would be a different issue, i.e. the conclusion should probably be that filepath needs not to understand posix paths because any argument should be translated before calling the executable.

hasufell commented 7 months ago

I thought Haskell was meant to be run in mingw because the binaries for GHC on Windows are labeled mingw. But I imagine it can run then in whatever Windows environment?

Yes, you can invoke ghc via powershell just fine. Only cabal needs to know the mingw/msys2 paths, but only if you link against such a library.

That's why e.g. ghcup adds the following entries to your cabal.config:

extra-include-dirs: C:\msys64\mingw64\include
extra-lib-dirs: C:\msys64\mingw64\lib
extra-prog-path: C:\ghcup\bin,
                 C:\cabal\bin,
                 C:\msys64\mingw64\bin,
                 C:\msys64\usr\bin

Then there's no point in being in an msys2 shell.

jasagredo commented 7 months ago

Why was that needed again? Wasn't setting the PKG_CONFIG_ALLOW_SYSTEM_LIBS env var enough?

For the record, I'm working just fine with this:

-- extra-include-dirs:
-- deterministic:
-- extra-lib-dirs:
-- extra-lib-dirs-static:
-- extra-framework-dirs:
extra-prog-path: C:\cabal\bin
-- instantiate-with:

(Perhaps the paths are needed in pwsh and not in msys2 shell, but the include and lib dirs seem to not be needed I think?)

Aah, nevermind. One might want to link without using pkgconf and that is why, as pwsh doesn't know about the standard lib locations.