haskell / cabal

Official upstream development repository for Cabal and cabal-install
https://haskell.org/cabal
Other
1.61k stars 691 forks source link

Discover ghc-pkg from $LibDir/bin/ghc-pkg #6648

Open phadej opened 4 years ago

phadej commented 4 years ago
% ghc --info|grep LibDir                     
 ,("LibDir","/opt/ghc/8.6.5/lib/ghc-8.6.5")
% ls /opt/ghc/8.6.5/lib/ghc-8.6.5/bin/ghc-pkg
/opt/ghc/8.6.5/lib/ghc-8.6.5/bin/ghc-pkg

I think this better than whatever path guessing we do now, and should be tried first for GHC.

cc @hvr

EDIT: looks like the bin might be missing for older GHCs, and the executables are directly in lib

/opt/ghc/7.0.4/lib/ghc-7.0.4/ghc-pkg
...
/opt/ghc/7.6.3/lib/ghc-7.6.3/ghc-pkg
/opt/ghc/7.8.4/lib/ghc-7.8.4/bin/ghc-pkg
...
/opt/ghc/8.10.1/lib/ghc-8.10.1/bin/ghc-pkg
hvr commented 4 years ago

hrm... ok, so this would require to execute ghc --info before being able to locate ghc-pkg...

phadej commented 4 years ago

  -- NOTE: Here we guess `ghc-pkg` location:

  -- This is slightly tricky, we have to configure ghc first, then we use the
  -- location of ghc to help find ghc-pkg in the case that the user did not
  -- specify the location of ghc-pkg directly:
  (ghcPkgProg, ghcPkgVersion, progdb2) <-
    requireProgramVersion verbosity ghcPkgProgram {
      programFindLocation = guessGhcPkgFromGhcPath ghcProg
    }
    anyVersion (userMaybeSpecifyPath "ghc-pkg" hcPkgPath progdb1)

  when (ghcVersion /= ghcPkgVersion) $ die' verbosity $
       "Version mismatch between ghc and ghc-pkg: "
    ++ programPath ghcProg ++ " is version " ++ prettyShow ghcVersion ++ " "
    ++ programPath ghcPkgProg ++ " is version " ++ prettyShow ghcPkgVersion

  -- Likewise we try to find the matching hsc2hs and haddock programs.
  let hsc2hsProgram' = hsc2hsProgram {
                           programFindLocation = guessHsc2hsFromGhcPath ghcProg
                       }
      haddockProgram' = haddockProgram {
                           programFindLocation = guessHaddockFromGhcPath ghcProg
                       }
      hpcProgram' = hpcProgram {
                        programFindLocation = guessHpcFromGhcPath ghcProg
                    }
      runghcProgram' = runghcProgram {
                        programFindLocation = guessRunghcFromGhcPath ghcProg
                    }
      progdb3 = addKnownProgram haddockProgram' $
              addKnownProgram hsc2hsProgram' $
              addKnownProgram hpcProgram' $
              addKnownProgram runghcProgram' progdb2

  languages  <- Internal.getLanguages verbosity implInfo ghcProg
  extensions0 <- Internal.getExtensions verbosity implInfo ghcProg

  -- NOTE: abit later we ask for `ghcInfo`

  ghcInfo <- Internal.getGhcInfo verbosity implInfo ghcProg

So not much code needs to be moved around.

EDIT (that is part of Distribution.Simple.GHC.configure)

phadej commented 4 years ago

@bgamari another alternative is that GHC would tell where the ghc-pkg (and other tools) are, like it does for unlit

 ,("unlit command","/opt/ghc/8.10.1/lib/ghc-8.10.1/bin/unlit")
bgamari commented 3 years ago

I have proposed a solution to this in #7390 .

phadej commented 3 years ago

The new ghc --info field doesn't solve problem with old(er) GHCs.

bgamari commented 3 years ago

No, it doesn't. I consider older releases to be out-of-scope. However, I'm happy to backport as the patch is about as low-risk as patches can be.