cabal icon indicating copy to clipboard operation
cabal copied to clipboard

cabal-install inconsistently looks through symlinks

Open sheaf opened this issue 1 year ago • 4 comments

cabal-install inconsistently looks through symlinks. Suppose for instance that one has a Cabal project in /public/pkg and that public is a symlink to private. Then, because establishProjectBaseContext canonicalizes paths, when building packages we will use source directories of the form /private/pkg/srcdir, but if we pass a dist dir of /public/pkg/dist (using -builddir) then we end up with a build directory of public/pkg/dist. That is, srcdir looked through symlinks, builddir did not. In such a situation, calls to makeRelative will fail to make the path relative, for example in Distribution.Client.ProjectBuilding.rebuildPhase.

In practice, this can mean that we pass absolute paths to GHC, e.g. for -odir, in cases where we previously passed relative paths. This might seem benign, but it could cause bugs; for example GHC will not respect the -odir flag if the paths to the source files it is given are absolute, as it will place build products next to the original files due to a logic of the form odir </> replaceExtension srcFilePath "o" (which will drop odir if the second argument is absolute).

Task: Calls to canonicalizePath in cabal-install should be audited and potentially replaced with makeAbsolute, or (even better) by keeping the filepaths relative wherever possible. This will be made much easier by #9718.

NB: I am not volunteering to carry out this task at this time.

sheaf avatar Mar 01 '24 15:03 sheaf

@sheaf, would you be able to help review #9578? I'm using canonicalizePath there for normalizing project imports.

philderbeast avatar Mar 01 '24 15:03 philderbeast

@sheaf, would you be able to help review #9578? I'm using canonicalizePath there for normalizing project imports.

I haven't looked in depth, but normalize is sufficient for the purposes of handling a/./b and a/../c in paths. Are there other reasons why you had to use canonicalizePath rather than simply normalize?

sheaf avatar Mar 01 '24 15:03 sheaf

Thanks for suggesting normalize. I'll try it and see if it breaks anything. I need to be able to compare already seen imports for catching cycles and duplicates.

philderbeast avatar Mar 01 '24 15:03 philderbeast

I remember now that I'd considered normalize but it doesn't remove .. whereas canonicalizePath does, (https://github.com/haskell/filepath/commit/01fda37238ab3675d2c2ada9ad0874123c887150).

philderbeast avatar Mar 02 '24 11:03 philderbeast