on master help sign in
Local hidir and hiedir folders to avoid conflicts with Cabal (#441)
48a7867Pepe Iborra
exe/Main.hs+54−2
@@ -19,6 +19,9 @@ import Control.DeepSeq (NFData)
19import Control.Exception
19import Control.Exception
20import Control.Monad.Extra
20import Control.Monad.Extra
21import Control.Monad.IO.Class
21import Control.Monad.IO.Class
22+import qualified Crypto.Hash.SHA1 as H
23+import qualified Data.ByteString.Char8 as B
24+import Data.ByteString.Base16
22import Data.Default
25import Data.Default
23import System.Time.Extra
26import System.Time.Extra
24import Development.IDE.Core.Debouncer
27import Development.IDE.Core.Debouncer
@@ -57,15 +60,28 @@ import qualified Data.Map.Strict as Map
57import GHC hiding (def)
60import GHC hiding (def)
58import GHC.Generics (Generic)
61import GHC.Generics (Generic)
59import qualified GHC.Paths
62import qualified GHC.Paths
63+import DynFlags
60
64
65+import HIE.Bios.Environment
61import HIE.Bios
66import HIE.Bios
62import HIE.Bios.Cradle
67import HIE.Bios.Cradle
63import HIE.Bios.Types
68import HIE.Bios.Types
64
69
70+-- Prefix for the cache path
71+cacheDir :: String
72+cacheDir = "ghcide"
73+
65-- Set the GHC libdir to the nix libdir if it's present.
74-- Set the GHC libdir to the nix libdir if it's present.
66getLibdir :: IO FilePath
75getLibdir :: IO FilePath
67getLibdir = fromMaybe GHC.Paths.libdir <$> lookupEnv "NIX_GHC_LIBDIR"
76getLibdir = fromMaybe GHC.Paths.libdir <$> lookupEnv "NIX_GHC_LIBDIR"
68
77
78+getCacheDir :: [String] -> IO FilePath
79+getCacheDir opts = IO.getXdgDirectory IO.XdgCache (cacheDir </> opts_hash)
80+ where
81+ -- Create a unique folder per set of different GHC options, assuming that each different set of
82+ -- GHC options will create incompatible interface files.
83+ opts_hash = B.unpack $ encode $ H.finalize $ H.updates H.init (map B.pack opts)
84+
69ghcideVersion :: IO String
85ghcideVersion :: IO String
70ghcideVersion = do
86ghcideVersion = do
71 path <- getExecutablePath
87 path <- getExecutablePath
@@ -224,14 +240,50 @@ getComponentOptions cradle = do
224
240
225
241
226createSession :: ComponentOptions -> IO HscEnvEq
242createSession :: ComponentOptions -> IO HscEnvEq
227−createSession opts = do
243+createSession (ComponentOptions theOpts _) = do
228 libdir <- getLibdir
244 libdir <- getLibdir
245+
246+ cacheDir <- Main.getCacheDir theOpts
247+
229 env <- runGhc (Just libdir) $ do
248 env <- runGhc (Just libdir) $ do
230− _targets <- initSession opts
249+ dflags <- getSessionDynFlags
250+ (dflags', _targets) <- addCmdOpts theOpts dflags
251+ _ <- setSessionDynFlags $
252+ -- disabled, generated directly by ghcide instead
253+ flip gopt_unset Opt_WriteInterface $
254+ -- disabled, generated directly by ghcide instead
255+ -- also, it can confuse the interface stale check
256+ dontWriteHieFiles $
257+ setHiDir cacheDir $
258+ setDefaultHieDir cacheDir $
259+ setIgnoreInterfacePragmas $
260+ setLinkerOptions $
261+ disableOptimisation dflags'
231 getSession
262 getSession
232 initDynLinker env
263 initDynLinker env
233 newHscEnvEq env
264 newHscEnvEq env
234
265
266+-- we don't want to generate object code so we compile to bytecode
267+-- (HscInterpreted) which implies LinkInMemory
268+-- HscInterpreted
269+setLinkerOptions :: DynFlags -> DynFlags
270+setLinkerOptions df = df {
271+ ghcLink = LinkInMemory
272+ , hscTarget = HscNothing
273+ , ghcMode = CompManager
274+ }
275+
276+setIgnoreInterfacePragmas :: DynFlags -> DynFlags
277+setIgnoreInterfacePragmas df =
278+ gopt_set (gopt_set df Opt_IgnoreInterfacePragmas) Opt_IgnoreOptimChanges
279+
280+disableOptimisation :: DynFlags -> DynFlags
281+disableOptimisation df = updOptLevel 0 df
282+
283+setHiDir :: FilePath -> DynFlags -> DynFlags
284+setHiDir f d =
285+ -- override user settings to avoid conflicts leading to recompilation
286+ d { hiDir = Just f}
235
287
236cradleToSession :: Maybe FilePath -> Cradle a -> Action HscEnvEq
288cradleToSession :: Maybe FilePath -> Cradle a -> Action HscEnvEq
237cradleToSession mbYaml cradle = do
289cradleToSession mbYaml cradle = do
ghcide.cabal+3
@@ -171,7 +171,10 @@ executable ghcide
171 hslogger,
171 hslogger,
172 base == 4.*,
172 base == 4.*,
173 binary,
173 binary,
174+ base16-bytestring >=0.1.1 && <0.2,
175+ bytestring,
174 containers,
176 containers,
177+ cryptohash-sha1 >=0.11.100 && <0.12,
175 data-default,
178 data-default,
176 deepseq,
179 deepseq,
177 directory,
180 directory,
src/Development/IDE/GHC/Compat.hs+18
@@ -12,6 +12,8 @@ module Development.IDE.GHC.Compat(
12 mkHieFile,
12 mkHieFile,
13 writeHieFile,
13 writeHieFile,
14 readHieFile,
14 readHieFile,
15+ setDefaultHieDir,
16+ dontWriteHieFiles,
15 hPutStringBuffer,
17 hPutStringBuffer,
16 includePathsGlobal,
18 includePathsGlobal,
17 includePathsQuote,
19 includePathsQuote,
@@ -156,3 +158,19 @@ pattern IEThingAll a <-
156#else
158#else
157 GHC.IEThingAll a
159 GHC.IEThingAll a
158#endif
160#endif
161+
162+setDefaultHieDir :: FilePath -> DynFlags -> DynFlags
163+setDefaultHieDir _f d =
164+#if MIN_GHC_API_VERSION(8,8,0)
165+ d { hieDir = hieDir d `mappend` Just _f}
166+#else
167+ d
168+#endif
169+
170+dontWriteHieFiles :: DynFlags -> DynFlags
171+dontWriteHieFiles d =
172+#if MIN_GHC_API_VERSION(8,8,0)
173+ gopt_unset d Opt_WriteHie
174+#else
175+ d
176+#endif
src/Development/IDE/GHC/Util.hs+3−1
@@ -19,6 +19,8 @@ module Development.IDE.GHC.Util(
19 textToStringBuffer,
19 textToStringBuffer,
20 readFileUtf8,
20 readFileUtf8,
21 hDuplicateTo',
21 hDuplicateTo',
22+ setDefaultHieDir,
23+ dontWriteHieFiles
22 ) where
24 ) where
23
25
24import Control.Concurrent
26import Control.Concurrent
@@ -27,7 +29,6 @@ import Data.Maybe
27import Data.Typeable
29import Data.Typeable
28import qualified Data.ByteString.Internal as BS
30import qualified Data.ByteString.Internal as BS
29import Fingerprint
31import Fingerprint
30−import GHC
31import GhcMonad
32import GhcMonad
32import GhcPlugins hiding (Unique)
33import GhcPlugins hiding (Unique)
33import Data.IORef
34import Data.IORef
@@ -52,6 +53,7 @@ import Lexer
52import StringBuffer
53import StringBuffer
53import System.FilePath
54import System.FilePath
54
55
56+import Development.IDE.GHC.Compat as GHC
55import Development.IDE.Types.Location
57import Development.IDE.Types.Location
56
58
57
59