Hannes Siebenhandl pushed to branch wip/fendor/dep-json at Glasgow Haskell Compiler / GHC

Commits:

11 changed files:

Changes:

  • compiler/GHC/Driver/MakeFile.hs
    ... ... @@ -11,7 +11,8 @@
    11 11
     {-# LANGUAGE RecordWildCards #-}
    
    12 12
     
    
    13 13
     module GHC.Driver.MakeFile
    
    14
    -   ( doMkDependHS
    
    14
    +   ( doMkDepend
    
    15
    +   , doMkDependHS
    
    15 16
        , doMkDependModuleGraph
    
    16 17
        )
    
    17 18
     where
    
    ... ... @@ -80,6 +81,8 @@ import System.IO.Error (isEOFError)
    80 81
     import qualified System.OsString as OsString
    
    81 82
     import qualified Data.Monoid as Monoid
    
    82 83
     import qualified System.FilePath as FilePath
    
    84
    +import GHC.Unit.Home.Graph (HomeUnitEnv(homeUnitEnv_dflags))
    
    85
    +import GHC (setProgramHUG)
    
    83 86
     
    
    84 87
     -----------------------------------------------------------------
    
    85 88
     --
    
    ... ... @@ -117,7 +120,39 @@ doMkDependHS srcs = do
    117 120
         module_graph <- GHC.depanal excl_mods True {- Allow dup roots -}
    
    118 121
         doMkDependModuleGraph dflags module_graph
    
    119 122
     
    
    123
    +doMkDepend :: GhcMonad m => m ()
    
    124
    +doMkDepend = do
    
    125
    +    hug_ <- hsc_HUG <$> getSession
    
    126
    +
    
    127
    +    let hug =
    
    128
    +          fmap (\ hue ->
    
    129
    +            let
    
    130
    +              -- We kludge things a bit for dependency generation. Rather than
    
    131
    +              -- generating dependencies for each way separately, we generate
    
    132
    +              -- them once and then duplicate them for each way's osuf/hisuf.
    
    133
    +              -- We therefore do the initial dependency generation with an empty
    
    134
    +              -- way and .o/.hi extensions, regardless of any flags that might
    
    135
    +              -- be specified.
    
    136
    +              dflags1 = (homeUnitEnv_dflags hue)
    
    137
    +                { targetWays_ = Set.empty
    
    138
    +                , hiSuf_      = "hi"
    
    139
    +                , objectSuf_  = "o"
    
    140
    +                }
    
    141
    +            in
    
    142
    +              hue {homeUnitEnv_dflags = dflags1}
    
    143
    +              ) hug_
    
    144
    +
    
    145
    +    _ <- setProgramHUG hug
    
    146
    +
    
    147
    +    dflagsGlobal <- GHC.getSessionDynFlags
    
    148
    +    -- If no suffix is provided, use the default -- the empty one
    
    149
    +    let dflags = if null (depSuffixes dflagsGlobal)
    
    150
    +                 then dflagsGlobal { depSuffixes = [""] }
    
    151
    +                 else dflagsGlobal
    
    120 152
     
    
    153
    +    let excl_mods = depExcludeMods dflags
    
    154
    +    module_graph <- GHC.depanal excl_mods True {- Allow dup roots -}
    
    155
    +    doMkDependModuleGraph dflags module_graph
    
    121 156
     
    
    122 157
     doMkDependModuleGraph :: GhcMonad m =>  DynFlags -> ModuleGraph -> m ()
    
    123 158
     doMkDependModuleGraph dflags module_graph = do
    
    ... ... @@ -610,127 +645,188 @@ writeJsonFile doc p = do
    610 645
     --------------------------------------------------------------------------------
    
    611 646
     -- Payload for -dep-json
    
    612 647
     
    
    613
    -newtype PackageDeps
    
    614
    -  = PackageDeps (Map.Map (String, UnitId, DPackageId) DepsImports)
    
    615
    -  deriving newtype (Monoid)
    
    616
    -
    
    617 648
     newtype DPackageId = DPackageId PackageId
    
    618 649
       deriving newtype (Eq)
    
    619 650
     
    
    620 651
     instance Ord DPackageId where
    
    621 652
       DPackageId (PackageId d1) `compare` DPackageId (PackageId d2) = d1 `lexicalCompareFS` d2
    
    622 653
     
    
    623
    -instance Semigroup PackageDeps where
    
    624
    -  PackageDeps l <> PackageDeps r = PackageDeps (Map.unionWith (Semigroup.<>) l r)
    
    625
    -
    
    626
    -data Deps = Deps
    
    627
    -  { sources :: Set.Set OsPath
    
    628
    -  , moduleImports :: DepsImports
    
    629
    -  , sourceImports :: DepsImports
    
    630
    -  , packages :: PackageDeps
    
    654
    +data ModuleNodeDeps = ModuleNodeDeps
    
    655
    +  { source :: OsPath
    
    656
    +  , imports :: ImportDeps
    
    631 657
       , cpp :: Set.Set OsPath
    
    632 658
       , options :: [String]
    
    633 659
       , preprocessor :: Maybe FilePath
    
    634 660
       }
    
    635 661
       deriving stock (Generic)
    
    636
    -  deriving (Semigroup, Monoid) via (Generically Deps)
    
    662
    +  deriving (Semigroup, Monoid) via (Generically ModuleNodeDeps)
    
    637 663
     
    
    638
    -data DepsImports
    
    639
    -  = DepsImports
    
    640
    -  { normalImport :: Set.Set Module
    
    641
    -  , spliceImport :: Set.Set Module
    
    642
    -  , quoteImport :: Set.Set Module
    
    643
    -  }
    
    664
    +addImport :: ImportDep -> ModuleNodeDeps -> ModuleNodeDeps
    
    665
    +addImport import_dep mod_node_deps =
    
    666
    +  mod_node_deps
    
    667
    +    { imports = ImportDeps $ Map.insertWith Set.union uid (Set.singleton import_dep) (getImports $ imports mod_node_deps)
    
    668
    +    }
    
    669
    +  where
    
    670
    +    uid = toUnitId $ moduleUnit $ imp_mod import_dep
    
    671
    +
    
    672
    +addCpp :: OsPath -> ModuleNodeDeps -> ModuleNodeDeps
    
    673
    +addCpp p mod_node_deps =
    
    674
    +  mod_node_deps
    
    675
    +    { cpp = Set.insert p (cpp mod_node_deps)
    
    676
    +    }
    
    677
    +
    
    678
    +newtype ImportDeps = ImportDeps { getImports :: Map.Map UnitId (Set.Set ImportDep) }
    
    644 679
       deriving stock (Generic)
    
    645
    -  deriving (Semigroup, Monoid) via (Generically DepsImports)
    
    680
    +  deriving (Semigroup, Monoid) via (Generically ImportDeps)
    
    681
    +
    
    682
    +data ImportDep = ImportDep
    
    683
    +  { imp_mod :: Module
    
    684
    +  , imp_level :: ImportLevel
    
    685
    +  , imp_isBoot :: IsBootInterface
    
    686
    +  } deriving (Eq, Ord)
    
    687
    +
    
    688
    +mkImportDep :: Module -> ImportLevel -> IsBootInterface -> ImportDep
    
    689
    +mkImportDep modl level isBoot = ImportDep
    
    690
    +  { imp_mod = modl
    
    691
    +  , imp_level = level
    
    692
    +  , imp_isBoot = isBoot
    
    693
    +  }
    
    646 694
     
    
    647
    -newtype DepJson = DepJson (Map.Map ModuleWithIsBoot Deps)
    
    695
    +data HomeUnitDeps = HomeUnitDeps
    
    696
    +  { homeModules :: Map.Map ModuleWithIsBoot ModuleNodeDeps
    
    697
    +  }
    
    698
    +  deriving stock (Generic)
    
    699
    +  deriving (Semigroup, Monoid) via (Generically HomeUnitDeps)
    
    700
    +
    
    701
    +data ExtUnitDep = ExtUnitDep
    
    702
    +  { extUnitId :: UnitId
    
    703
    +  -- ^ The 'UnitId' of a unit. This is assumed to be globally unique.
    
    704
    +  , extUnitName :: String
    
    705
    +  , extUnitPackageId :: DPackageId
    
    706
    +  } deriving (Eq, Ord)
    
    707
    +
    
    708
    +data DepJson = DepJson
    
    709
    +  { homeUnitDeps :: Map.Map UnitId HomeUnitDeps
    
    710
    +  , externalDeps :: Set.Set ExtUnitDep
    
    711
    +  }
    
    648 712
     
    
    649 713
     instance ToJson DepJson where
    
    650
    -  json (DepJson m) =
    
    651
    -    JSObject
    
    652
    -      [ (homeUnitModuleKey target, homeUnitModule deps)
    
    653
    -      | (target, deps) <- Map.toList m
    
    714
    +  json (DepJson homeUnits extDeps) =
    
    715
    +    JSObject $
    
    716
    +      [ homeUnit huid hud
    
    717
    +      | (huid, hud) <- Map.toList homeUnits
    
    718
    +      ] ++
    
    719
    +      [ mkExtDepObj dep
    
    720
    +      | dep <- Set.toList extDeps
    
    654 721
           ]
    
    655 722
         where
    
    723
    +      homeUnit uid hud =
    
    724
    +        ( unitIdString uid
    
    725
    +        , JSObject
    
    726
    +            [
    
    727
    +              ( "modules"
    
    728
    +              , JSObject
    
    729
    +                  [ (homeUnitModuleKey modl, homeUnitModule deps)
    
    730
    +                  | (modl, deps) <- Map.toList $ homeModules hud
    
    731
    +                  ]
    
    732
    +              )
    
    733
    +            ]
    
    734
    +        )
    
    735
    +
    
    656 736
           homeUnitModuleKey :: ModuleWithIsBoot -> String
    
    657
    -      homeUnitModuleKey t = moduleNameString (moduleName (gwib_mod t)) ++ case gwib_isBoot t of
    
    737
    +      homeUnitModuleKey t = moduleKey (gwib_mod t) (gwib_isBoot t)
    
    738
    +
    
    739
    +      moduleKey :: Module -> IsBootInterface -> String
    
    740
    +      moduleKey t b = moduleNameString (moduleName t) ++ case b of
    
    658 741
             IsBoot -> "[boot]"
    
    659 742
             NotBoot -> ""
    
    660 743
     
    
    661
    -      homeUnitModule :: Deps -> JsonDoc
    
    662
    -      homeUnitModule Deps {packages = PackageDeps packages, ..} =
    
    744
    +      homeUnitModule :: ModuleNodeDeps -> JsonDoc
    
    745
    +      homeUnitModule ModuleNodeDeps {source, imports, cpp, options, preprocessor} =
    
    663 746
             JSObject
    
    664
    -          [ ("sources", array sources (showOsPath . normalise))
    
    665
    -          , ("modules", JSObject $ importsObj moduleImports)
    
    666
    -          , ("modules-boot", JSObject $ importsObj sourceImports)
    
    667
    -          , ("packages", JSArray
    
    668
    -              [ package name unit_id package_id mods
    
    669
    -              | ((name, unit_id, dpkd_id), mods) <- Map.toList packages
    
    670
    -              , let DPackageId package_id = dpkd_id
    
    671
    -              ]
    
    672
    -            )
    
    673
    -          , ("cpp", array cpp showOsPath)
    
    747
    +          [ ("source", JSString . showOsPath $ normalise source)
    
    748
    +          , ("imports", importsObj imports)
    
    749
    +          , ("includes", strArray cpp showOsPath)
    
    674 750
               , ("options", JSArray $ map JSString options)
    
    675 751
               , ("preprocessor", maybe JSNull JSString preprocessor)
    
    676 752
               ]
    
    677 753
     
    
    678
    -      package :: String -> UnitId -> PackageId -> DepsImports -> JsonDoc
    
    679
    -      package name unit_id (PackageId package_id) mods =
    
    754
    +      importsObj :: ImportDeps -> JsonDoc
    
    755
    +      importsObj importDeps = JSArray $ map importObj (Map.toList $ getImports importDeps)
    
    756
    +
    
    757
    +      importObj :: (UnitId, Set.Set ImportDep) -> JsonDoc
    
    758
    +      importObj (uid, importSet) =
    
    680 759
             JSObject
    
    681
    -          [ ("id", JSString (unitIdString unit_id))
    
    682
    -          , ("name", JSString name)
    
    683
    -          , ("package-id", JSString (unpackFS package_id))
    
    684
    -          , ("modules", JSObject $ importsObj mods)
    
    760
    +          [ (unitIdString uid, array importSet importDepObj )
    
    685 761
               ]
    
    686 762
     
    
    687
    -      array values render = JSArray (fmap (JSString . render) (Set.toList values))
    
    763
    +      importDepObj :: ImportDep -> JsonDoc
    
    764
    +      importDepObj ImportDep {imp_mod, imp_level, imp_isBoot}
    
    765
    +        | NormalLevel <- imp_level = JSString (moduleKey imp_mod imp_isBoot)
    
    766
    +        | otherwise = JSObject
    
    767
    +          [ ("module", JSString (moduleKey imp_mod imp_isBoot))
    
    768
    +          , ("level" , importLevel imp_level)
    
    769
    +          ]
    
    688 770
     
    
    689
    -      showOsPath = unsafeDecodeUtf
    
    771
    +      importLevel :: ImportLevel -> JsonDoc
    
    772
    +      importLevel lvl =
    
    773
    +        JSString $ case lvl of
    
    774
    +          NormalLevel -> "normal"
    
    775
    +          SpliceLevel -> "splice"
    
    776
    +          QuoteLevel -> "quote"
    
    777
    +
    
    778
    +      mkExtDepObj :: ExtUnitDep -> (String, JsonDoc)
    
    779
    +      mkExtDepObj ExtUnitDep{..} =
    
    780
    +        ( unitIdString extUnitId
    
    781
    +        , JSObject
    
    782
    +            [ ("package-name", JSString extUnitName)
    
    783
    +            , ("package-id", JSString $ showPackageId extUnitPackageId)
    
    784
    +            ]
    
    785
    +        )
    
    786
    +
    
    787
    +      array values render = JSArray (fmap render (Set.toList values))
    
    788
    +      strArray values render = JSArray (fmap (JSString . render) (Set.toList values))
    
    690 789
     
    
    691
    -      importsObj  :: DepsImports -> [(String, JsonDoc)]
    
    692
    -      importsObj DepsImports{..} =
    
    693
    -        [ ("normal", array normalImport (moduleNameString . moduleName))
    
    694
    -        , ("quote" , array quoteImport  (moduleNameString . moduleName))
    
    695
    -        , ("splice", array spliceImport (moduleNameString . moduleName))
    
    696
    -        ]
    
    790
    +      showOsPath = unsafeDecodeUtf
    
    791
    +      showPackageId (DPackageId (PackageId pid)) = unpackFS pid
    
    697 792
     
    
    698 793
     initDepJson :: IO (IORef DepJson)
    
    699
    -initDepJson = newIORef $ DepJson Map.empty
    
    794
    +initDepJson = newIORef $ DepJson Map.empty Set.empty
    
    700 795
     
    
    701
    -insertDepJson :: [ModuleWithIsBoot] -> Deps -> DepJson -> DepJson
    
    702
    -insertDepJson targets dep (DepJson m0) =
    
    796
    +insertDepJson :: ModuleWithIsBoot -> ModuleNodeDeps -> Set.Set ExtUnitDep -> DepJson -> DepJson
    
    797
    +insertDepJson target modNode extUnits (DepJson m0 e0) =
    
    703 798
       DepJson
    
    704
    -    $ foldl'
    
    705
    -      ( \acc target ->
    
    706
    -          Map.insertWithKey
    
    707
    -            (\ k _l _r -> pprPanic "insertDepJson" (text "Conflicting entries for: " <+> ppr k))
    
    708
    -            target
    
    709
    -            dep
    
    710
    -            acc
    
    711
    -      )
    
    712
    -      m0
    
    713
    -      targets
    
    799
    +    { homeUnitDeps =
    
    800
    +        Map.insertWith
    
    801
    +          (Semigroup.<>)
    
    802
    +          modUnitId
    
    803
    +          (HomeUnitDeps $ Map.singleton target modNode)
    
    804
    +          m0
    
    805
    +    , externalDeps =
    
    806
    +        Set.union e0 extUnits
    
    807
    +    }
    
    808
    +  where
    
    809
    +    modUnitId = toUnitId $ moduleUnit $ gwib_mod target
    
    714 810
     
    
    715 811
     updateDepJson :: Bool -> DepNode -> [Dep] -> DepJson -> DepJson
    
    716 812
     updateDepJson include_pkgs DepNode {..} deps =
    
    717
    -  insertDepJson [dn_mod] payload
    
    813
    +  insertDepJson dn_mod payload externalDeps
    
    718 814
       where
    
    719
    -    payload = node_data Semigroup.<> foldMap mkDep deps
    
    815
    +    (externalDeps, payload) = foldl' go (Set.empty, initial_node_data) deps
    
    720 816
     
    
    721
    -    node_data =
    
    722
    -      mempty
    
    723
    -        { sources = Set.singleton dn_src
    
    817
    +    initial_node_data =
    
    818
    +      ModuleNodeDeps
    
    819
    +        { source = dn_src
    
    724 820
             , preprocessor = pn_preprocessor dn_preprocessing
    
    725 821
             , options = pn_options dn_preprocessing
    
    822
    +        , cpp = Set.empty
    
    823
    +        , imports = ImportDeps Map.empty
    
    726 824
             }
    
    727 825
     
    
    728
    -    mkDep = \case
    
    826
    +    go (extDeps, node_data) = \ case
    
    729 827
           DepHi {dep_mod, dep_local, dep_unit, dep_boot, dep_level}
    
    730 828
             | dep_local
    
    731
    -        -> case dep_boot of
    
    732
    -          IsBoot -> mempty {sourceImports = depsImportForImport dep_mod dep_level}
    
    733
    -          NotBoot -> mempty {moduleImports = depsImportForImport dep_mod dep_level }
    
    829
    +        -> (extDeps, addImport (mkImportDep dep_mod dep_level dep_boot) node_data)
    
    734 830
     
    
    735 831
             | include_pkgs
    
    736 832
             , Just unit <- dep_unit
    
    ... ... @@ -738,19 +834,21 @@ updateDepJson include_pkgs DepNode {..} deps =
    738 834
                   name = unpackFS nameFS
    
    739 835
                   withLibName (PackageName c) = name ++ ":" ++ unpackFS c
    
    740 836
                   lname = maybe name withLibName (unitComponentName unit)
    
    741
    -              key = (lname, unitId unit, DPackageId $ unitPackageId unit)
    
    742
    -        -> mempty {packages = PackageDeps (Map.singleton key (depsImportForImport dep_mod dep_level))}
    
    837
    +              newExtDep = ExtUnitDep
    
    838
    +                { extUnitId = unitId unit
    
    839
    +                , extUnitName = lname
    
    840
    +                , extUnitPackageId = DPackageId $ unitPackageId unit
    
    841
    +                }
    
    842
    +        ->
    
    843
    +          ( Set.insert newExtDep extDeps
    
    844
    +          , addImport (mkImportDep dep_mod dep_level dep_boot) node_data
    
    845
    +          )
    
    743 846
     
    
    744 847
             | otherwise
    
    745
    -        -> mempty
    
    848
    +        -> (extDeps, node_data)
    
    746 849
     
    
    747 850
           DepCpp {dep_path} ->
    
    748
    -        mempty {cpp = Set.singleton dep_path}
    
    749
    -
    
    750
    -    depsImportForImport mod_name = \ case
    
    751
    -      NormalLevel -> mempty { normalImport = Set.singleton mod_name }
    
    752
    -      SpliceLevel -> mempty { spliceImport = Set.singleton mod_name }
    
    753
    -      QuoteLevel ->  mempty { quoteImport  = Set.singleton mod_name }
    
    851
    +        (extDeps, addCpp dep_path node_data)
    
    754 852
     
    
    755 853
     -----------------------------------------------------------------
    
    756 854
     --              Module cycles
    

  • ghc/Main.hs
    ... ... @@ -27,7 +27,7 @@ import GHC.Driver.Phases
    27 27
     import GHC.Driver.Session
    
    28 28
     import GHC.Driver.Ppr
    
    29 29
     import GHC.Driver.Pipeline  ( oneShot )
    
    30
    -import GHC.Driver.MakeFile  ( doMkDependHS )
    
    30
    +import qualified GHC.Driver.MakeFile as MakeFile
    
    31 31
     import GHC.Driver.Backpack  ( doBackpack )
    
    32 32
     import GHC.Driver.Plugins
    
    33 33
     import GHC.Driver.Config.Logger (initLogFlags)
    
    ... ... @@ -271,7 +271,7 @@ main' postLoadMode units dflags0 args flagWarnings = do
    271 271
                                                         f
    
    272 272
            ShowByteCode f         -> liftIO $ showByteCode logger hsc_env f
    
    273 273
            DoMake                 -> doMake units srcs
    
    274
    -       DoMkDependHS           -> doMkDependHS (map fst srcs)
    
    274
    +       DoMkDependHS           -> doMkDepend units srcs
    
    275 275
            StopBefore p           -> liftIO (oneShot hsc_env p srcs)
    
    276 276
            DoInteractive          -> ghciUI units srcs Nothing
    
    277 277
            DoEval exprs           -> ghciUI units srcs $ Just $ reverse exprs
    
    ... ... @@ -332,6 +332,24 @@ doMake units targets = do
    332 332
           ok_flag <- GHC.load LoadAllTargets
    
    333 333
           when (failed ok_flag) (liftIO $ exitWith (ExitFailure 1))
    
    334 334
     
    
    335
    +-- ----------------------------------------------------------------------------
    
    336
    +-- Run -M mode
    
    337
    +
    
    338
    +doMkDepend :: [String] -> [(String, Maybe Phase)] -> Ghc ()
    
    339
    +doMkDepend units targets = do
    
    340
    +  hs_srcs <- case NE.nonEmpty units of
    
    341
    +    Just ne_units -> do
    
    342
    +      initMulti ne_units (checkOptions DoMake)
    
    343
    +    Nothing -> do
    
    344
    +      s <- initMake targets -- TODO: @fendor: This feels wrong
    
    345
    +      return $ map (uncurry (,Nothing,)) s
    
    346
    +  case hs_srcs of
    
    347
    +    [] -> return ()
    
    348
    +    _  -> do
    
    349
    +      targets' <- mapM (\(src, uid, phase) -> GHC.guessTarget src uid phase) hs_srcs
    
    350
    +      GHC.setTargets targets'
    
    351
    +      MakeFile.doMkDepend
    
    352
    +
    
    335 353
     -- ---------------------------------------------------------------------------
    
    336 354
     -- Various banners and verbosity output.
    
    337 355
     
    

  • testsuite/driver/testlib.py
    ... ... @@ -20,6 +20,7 @@ from pathlib import Path, PurePath
    20 20
     import collections
    
    21 21
     import collections.abc
    
    22 22
     import subprocess
    
    23
    +import json
    
    23 24
     
    
    24 25
     from testglobals import config, ghc_env, default_testopts, brokens, t, \
    
    25 26
                             TestRun, TestResult, TestOptions, PerfMetric
    
    ... ... @@ -3265,6 +3266,58 @@ def normalise_asm( s: str ) -> str:
    3265 3266
               out.append(ins[0])
    
    3266 3267
         return '\n'.join(out)
    
    3267 3268
     
    
    3269
    +def normalise_dep_json(s: str) -> str:
    
    3270
    +    """
    
    3271
    +    Normalise the json output of `ghc -M -dep-json output.json`
    
    3272
    +    """
    
    3273
    +
    
    3274
    +    def normalise_includes(j):
    
    3275
    +        # Only normalise proper json objects.
    
    3276
    +        # Strings might be parsed as json strings, but we that's not what we are looking for
    
    3277
    +        if not isinstance(j, dict):
    
    3278
    +            return j
    
    3279
    +        for unit in j.values():
    
    3280
    +            for module in unit.get("modules", {}).values():
    
    3281
    +                rewritten = [
    
    3282
    +                    __replace_absolute_path(p)
    
    3283
    +                    for p in module["includes"]
    
    3284
    +                ]
    
    3285
    +                # we sort to make sure this never
    
    3286
    +                module["includes"] = sorted(rewritten)
    
    3287
    +        return j
    
    3288
    +
    
    3289
    +    output = ""
    
    3290
    +    try:
    
    3291
    +        normalised_dep_json = normalise_includes(json.loads(s))
    
    3292
    +        output = json.dumps(normalised_dep_json, indent=2, sort_keys=True, ensure_ascii=False)
    
    3293
    +    except json.JSONDecodeError:
    
    3294
    +        output = s
    
    3295
    +    return output
    
    3296
    +
    
    3297
    +def normalise_dep_makefile(s: str) -> str:
    
    3298
    +    """
    
    3299
    +    Normalise the Makefile output of `ghc -M`
    
    3300
    +    """
    
    3301
    +
    
    3302
    +    output = []
    
    3303
    +    rules = []
    
    3304
    +    for line in s.split("\n"):
    
    3305
    +        target, sep, dep = line.partition(" : ")
    
    3306
    +        if sep:
    
    3307
    +            rules.append(target + sep + __replace_absolute_path(dep))
    
    3308
    +        else:
    
    3309
    +            # sort each block of rules so the order doesn't depend on the original absolute paths
    
    3310
    +            output.extend(sorted(rules))
    
    3311
    +            rules = []
    
    3312
    +            output.append(line)
    
    3313
    +    output.extend(sorted(rules))
    
    3314
    +    return "\n".join(output)
    
    3315
    +
    
    3316
    +def __replace_absolute_path(s: str) -> str:
    
    3317
    +    if s.startswith("/"):
    
    3318
    +        return "<absolute-path>/" + s.rsplit("/", 1)[-1]
    
    3319
    +    return s
    
    3320
    +
    
    3268 3321
     def safe_print(s: str) -> None:
    
    3269 3322
         s2 = s.encode(sys.stdout.encoding, errors='replace').decode(sys.stdout.encoding)
    
    3270 3323
         print(s2)
    

  • testsuite/tests/driver/T24384/Makefile
    ... ... @@ -45,4 +45,12 @@ T24384b: T24384_prep
    45 45
     		-package-db ./$(PKGCONF_LOCAL) -package-id dep-1-XXX -package-id dep-public-1-XXX \
    
    46 46
     		A.hs lib/B.hs C.hs D.hs E.hs
    
    47 47
     
    
    48
    -	cat dep.json | jq --sort-keys
    48
    +	cat dep.json
    
    49
    +
    
    50
    +T24384c: T24384_prep
    
    51
    +	'$(TEST_HC)' -M -dep-json dep.json \
    
    52
    +		-hide-all-packages -package base -package containers -package template-haskell \
    
    53
    +		-package-db ./$(PKGCONF_LOCAL) -package-id dep-1-XXX -package-id dep-public-1-XXX \
    
    54
    +		A.hs lib/B.hs C.hs D.hs E.hs
    
    55
    +
    
    56
    +	cat dep.json

  • testsuite/tests/driver/T24384/T24384a.stdout
    1 1
     # DO NOT DELETE: Beginning of Haskell dependencies
    
    2
    -E.o : E.hs
    
    3
    -E.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/Prelude.hi
    
    4
    -E.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/GHC/Essentials.hi
    
    5
    -E.o : dep-public/outdir/DepPublic.hi
    
    6
    -E.o : dep/outdir/Dep.hi
    
    7
    -E.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/template-haskell-2.25.0.0-inplace/Language/Haskell/TH/Syntax.hi
    
    8
    -C.o-boot : C.hs-boot
    
    9
    -C.o : C.hi-boot
    
    10
    -C.o-boot : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/Prelude.hi
    
    11
    -C.o-boot : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/GHC/Essentials.hi
    
    12
    -C.o-boot : E.hi
    
    2
    +A.o : <absolute-path>/Essentials.hi
    
    3
    +A.o : <absolute-path>/Prelude.hi
    
    4
    +A.o : <absolute-path>/ghcversion.h
    
    5
    +A.o : <absolute-path>/stdc-predef.h
    
    13 6
     A.o : A.hs
    
    14
    -A.o : foo.h
    
    15
    -A.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/rts-1.0.3/include/ghcversion.h
    
    16
    -A.o : /usr/include/stdc-predef.h
    
    17
    -A.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/Prelude.hi
    
    18
    -A.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/GHC/Essentials.hi
    
    19 7
     A.o : C.hi-boot
    
    20
    -C.o : C.hs
    
    21
    -C.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/Prelude.hi
    
    22
    -C.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/GHC/Essentials.hi
    
    23
    -C.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/containers-0.8-inplace/Data/Set.hi
    
    8
    +A.o : foo.h
    
    9
    +C.o : <absolute-path>/Essentials.hi
    
    10
    +C.o : <absolute-path>/Prelude.hi
    
    11
    +C.o : <absolute-path>/Set.hi
    
    24 12
     C.o : A.hi
    
    25
    -lib/B.o : lib/B.hs
    
    26
    -lib/B.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/Prelude.hi
    
    27
    -lib/B.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/GHC/Essentials.hi
    
    28
    -lib/B.o : A.hi
    
    29
    -D.o : D.hs
    
    30
    -D.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/Prelude.hi
    
    31
    -D.o : /home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/base-4.23.0.0-inplace/GHC/Essentials.hi
    
    13
    +C.o : C.hi-boot
    
    14
    +C.o : C.hs
    
    15
    +C.o-boot : <absolute-path>/Essentials.hi
    
    16
    +C.o-boot : <absolute-path>/Prelude.hi
    
    17
    +C.o-boot : C.hs-boot
    
    18
    +C.o-boot : E.hi
    
    19
    +D.o : <absolute-path>/Essentials.hi
    
    20
    +D.o : <absolute-path>/Prelude.hi
    
    32 21
     D.o : C.hi
    
    22
    +D.o : D.hs
    
    33 23
     D.o : lib/B.hi
    
    24
    +E.o : <absolute-path>/Essentials.hi
    
    25
    +E.o : <absolute-path>/Prelude.hi
    
    26
    +E.o : <absolute-path>/Syntax.hi
    
    27
    +E.o : E.hs
    
    28
    +E.o : dep-public/outdir/DepPublic.hi
    
    29
    +E.o : dep/outdir/Dep.hi
    
    30
    +lib/B.o : <absolute-path>/Essentials.hi
    
    31
    +lib/B.o : <absolute-path>/Prelude.hi
    
    32
    +lib/B.o : A.hi
    
    33
    +lib/B.o : lib/B.hi-boot
    
    34
    +lib/B.o : lib/B.hs
    
    35
    +lib/B.o-boot : <absolute-path>/Essentials.hi
    
    36
    +lib/B.o-boot : <absolute-path>/Prelude.hi
    
    37
    +lib/B.o-boot : A.hi
    
    38
    +lib/B.o-boot : lib/B.hs-boot
    
    34 39
     # DO NOT DELETE: End of Haskell dependencies

  • testsuite/tests/driver/T24384/T24384b.stdout
    1 1
     {
    
    2
    -  "A": {
    
    3
    -    "cpp": [
    
    4
    -      "/home/hugin/Documents/haskell/ghc-homes/ghc-dep-json/_build/stage1/lib/../lib/x86_64-linux-ghc-10.1.20260917-inplace/rts-1.0.3/include/ghcversion.h",
    
    5
    -      "/usr/include/stdc-predef.h",
    
    6
    -      "foo.h"
    
    7
    -    ],
    
    8
    -    "modules": {
    
    9
    -      "normal": [],
    
    10
    -      "quote": [],
    
    11
    -      "splice": []
    
    12
    -    },
    
    13
    -    "modules-boot": {
    
    14
    -      "normal": [
    
    15
    -        "C"
    
    16
    -      ],
    
    17
    -      "quote": [],
    
    18
    -      "splice": []
    
    19
    -    },
    
    20
    -    "options": [
    
    21
    -      "-XStrict",
    
    22
    -      "-XCPP",
    
    23
    -      "-fexpose-all-unfoldings"
    
    24
    -    ],
    
    25
    -    "packages": [
    
    26
    -      {
    
    27
    -        "id": "base-4.23.0.0-inplace",
    
    28
    -        "modules": {
    
    29
    -          "normal": [
    
    30
    -            "GHC.Essentials",
    
    31
    -            "Prelude"
    
    32
    -          ],
    
    33
    -          "quote": [],
    
    34
    -          "splice": []
    
    35
    -        },
    
    36
    -        "name": "base",
    
    37
    -        "package-id": "base-4.23.0.0"
    
    38
    -      }
    
    39
    -    ],
    
    40
    -    "preprocessor": null,
    
    41
    -    "sources": [
    
    42
    -      "A.hs"
    
    43
    -    ]
    
    2
    +  "base-<VERSION>-<HASH>": {
    
    3
    +    "package-id": "base-<VERSION>-<HASH>",
    
    4
    +    "package-name": "base"
    
    44 5
       },
    
    45
    -  "B": {
    
    46
    -    "cpp": [],
    
    47
    -    "modules": {
    
    48
    -      "normal": [
    
    49
    -        "A"
    
    50
    -      ],
    
    51
    -      "quote": [],
    
    52
    -      "splice": []
    
    53
    -    },
    
    54
    -    "modules-boot": {
    
    55
    -      "normal": [],
    
    56
    -      "quote": [],
    
    57
    -      "splice": []
    
    58
    -    },
    
    59
    -    "options": [
    
    60
    -      "-F",
    
    61
    -      "-pgmF",
    
    62
    -      "./preproc.sh"
    
    63
    -    ],
    
    64
    -    "packages": [
    
    65
    -      {
    
    66
    -        "id": "base-4.23.0.0-inplace",
    
    67
    -        "modules": {
    
    68
    -          "normal": [
    
    69
    -            "GHC.Essentials",
    
    70
    -            "Prelude"
    
    71
    -          ],
    
    72
    -          "quote": [],
    
    73
    -          "splice": []
    
    74
    -        },
    
    75
    -        "name": "base",
    
    76
    -        "package-id": "base-4.23.0.0"
    
    77
    -      }
    
    78
    -    ],
    
    79
    -    "preprocessor": "./preproc.sh",
    
    80
    -    "sources": [
    
    81
    -      "lib/B.hs"
    
    82
    -    ]
    
    6
    +  "containers-<VERSION>-<HASH>": {
    
    7
    +    "package-id": "containers-<VERSION>-<HASH>",
    
    8
    +    "package-name": "containers"
    
    83 9
       },
    
    84
    -  "B[boot]": {
    
    85
    -    "cpp": [],
    
    86
    -    "modules": {
    
    87
    -      "normal": [
    
    88
    -        "A"
    
    89
    -      ],
    
    90
    -      "quote": [],
    
    91
    -      "splice": []
    
    92
    -    },
    
    93
    -    "modules-boot": {
    
    94
    -      "normal": [],
    
    95
    -      "quote": [],
    
    96
    -      "splice": []
    
    97
    -    },
    
    98
    -    "options": [
    
    99
    -      "-F",
    
    100
    -      "-pgmF",
    
    101
    -      "./preproc.sh"
    
    102
    -    ],
    
    103
    -    "packages": [
    
    104
    -      {
    
    105
    -        "id": "base-4.23.0.0-inplace",
    
    106
    -        "modules": {
    
    107
    -          "normal": [
    
    108
    -            "GHC.Essentials",
    
    109
    -            "Prelude"
    
    110
    -          ],
    
    111
    -          "quote": [],
    
    112
    -          "splice": []
    
    113
    -        },
    
    114
    -        "name": "base",
    
    115
    -        "package-id": "base-4.23.0.0"
    
    116
    -      }
    
    117
    -    ],
    
    118
    -    "preprocessor": "./preproc.sh",
    
    119
    -    "sources": [
    
    120
    -      "lib/B.hs-boot"
    
    121
    -    ]
    
    10
    +  "dep-1-XXX": {
    
    11
    +    "package-id": "dep-1",
    
    12
    +    "package-name": "dep"
    
    122 13
       },
    
    123
    -  "C": {
    
    124
    -    "cpp": [],
    
    125
    -    "modules": {
    
    126
    -      "normal": [
    
    127
    -        "A"
    
    128
    -      ],
    
    129
    -      "quote": [],
    
    130
    -      "splice": []
    
    131
    -    },
    
    132
    -    "modules-boot": {
    
    133
    -      "normal": [],
    
    134
    -      "quote": [],
    
    135
    -      "splice": []
    
    136
    -    },
    
    137
    -    "options": [],
    
    138
    -    "packages": [
    
    139
    -      {
    
    140
    -        "id": "base-4.23.0.0-inplace",
    
    141
    -        "modules": {
    
    142
    -          "normal": [
    
    143
    -            "GHC.Essentials",
    
    144
    -            "Prelude"
    
    145
    -          ],
    
    146
    -          "quote": [],
    
    147
    -          "splice": []
    
    148
    -        },
    
    149
    -        "name": "base",
    
    150
    -        "package-id": "base-4.23.0.0"
    
    151
    -      },
    
    152
    -      {
    
    153
    -        "id": "containers-0.8-inplace",
    
    154
    -        "modules": {
    
    155
    -          "normal": [
    
    156
    -            "Data.Set"
    
    157
    -          ],
    
    158
    -          "quote": [],
    
    159
    -          "splice": []
    
    160
    -        },
    
    161
    -        "name": "containers",
    
    162
    -        "package-id": "containers-0.8"
    
    163
    -      }
    
    164
    -    ],
    
    165
    -    "preprocessor": null,
    
    166
    -    "sources": [
    
    167
    -      "C.hs"
    
    168
    -    ]
    
    14
    +  "dep-public-1-XXX": {
    
    15
    +    "package-id": "dep-public-1",
    
    16
    +    "package-name": "dep-public"
    
    169 17
       },
    
    170
    -  "C[boot]": {
    
    171
    -    "cpp": [],
    
    18
    +  "main": {
    
    172 19
         "modules": {
    
    173
    -      "normal": [
    
    174
    -        "E"
    
    175
    -      ],
    
    176
    -      "quote": [],
    
    177
    -      "splice": []
    
    178
    -    },
    
    179
    -    "modules-boot": {
    
    180
    -      "normal": [],
    
    181
    -      "quote": [],
    
    182
    -      "splice": []
    
    183
    -    },
    
    184
    -    "options": [],
    
    185
    -    "packages": [
    
    186
    -      {
    
    187
    -        "id": "base-4.23.0.0-inplace",
    
    188
    -        "modules": {
    
    189
    -          "normal": [
    
    190
    -            "GHC.Essentials",
    
    191
    -            "Prelude"
    
    192
    -          ],
    
    193
    -          "quote": [],
    
    194
    -          "splice": []
    
    195
    -        },
    
    196
    -        "name": "base",
    
    197
    -        "package-id": "base-4.23.0.0"
    
    198
    -      }
    
    199
    -    ],
    
    200
    -    "preprocessor": null,
    
    201
    -    "sources": [
    
    202
    -      "C.hs-boot"
    
    203
    -    ]
    
    204
    -  },
    
    205
    -  "D": {
    
    206
    -    "cpp": [],
    
    207
    -    "modules": {
    
    208
    -      "normal": [
    
    209
    -        "B",
    
    210
    -        "C"
    
    211
    -      ],
    
    212
    -      "quote": [],
    
    213
    -      "splice": []
    
    214
    -    },
    
    215
    -    "modules-boot": {
    
    216
    -      "normal": [],
    
    217
    -      "quote": [],
    
    218
    -      "splice": []
    
    219
    -    },
    
    220
    -    "options": [],
    
    221
    -    "packages": [
    
    222
    -      {
    
    223
    -        "id": "base-4.23.0.0-inplace",
    
    224
    -        "modules": {
    
    225
    -          "normal": [
    
    226
    -            "GHC.Essentials",
    
    227
    -            "Prelude"
    
    228
    -          ],
    
    229
    -          "quote": [],
    
    230
    -          "splice": []
    
    231
    -        },
    
    232
    -        "name": "base",
    
    233
    -        "package-id": "base-4.23.0.0"
    
    234
    -      }
    
    235
    -    ],
    
    236
    -    "preprocessor": null,
    
    237
    -    "sources": [
    
    238
    -      "D.hs"
    
    239
    -    ]
    
    240
    -  },
    
    241
    -  "E": {
    
    242
    -    "cpp": [],
    
    243
    -    "modules": {
    
    244
    -      "normal": [],
    
    245
    -      "quote": [],
    
    246
    -      "splice": []
    
    247
    -    },
    
    248
    -    "modules-boot": {
    
    249
    -      "normal": [],
    
    250
    -      "quote": [],
    
    251
    -      "splice": []
    
    252
    -    },
    
    253
    -    "options": [],
    
    254
    -    "packages": [
    
    255
    -      {
    
    256
    -        "id": "base-4.23.0.0-inplace",
    
    257
    -        "modules": {
    
    258
    -          "normal": [
    
    259
    -            "GHC.Essentials",
    
    260
    -            "Prelude"
    
    261
    -          ],
    
    262
    -          "quote": [],
    
    263
    -          "splice": []
    
    264
    -        },
    
    265
    -        "name": "base",
    
    266
    -        "package-id": "base-4.23.0.0"
    
    20
    +      "A": {
    
    21
    +        "imports": [
    
    22
    +          {
    
    23
    +            "base-<VERSION>-<HASH>": [
    
    24
    +              "GHC.Essentials",
    
    25
    +              "Prelude"
    
    26
    +            ]
    
    27
    +          },
    
    28
    +          {
    
    29
    +            "main": [
    
    30
    +              "C[boot]"
    
    31
    +            ]
    
    32
    +          }
    
    33
    +        ],
    
    34
    +        "includes": [
    
    35
    +          "<absolute-path>/ghcversion.h",
    
    36
    +          "<absolute-path>/stdc-predef.h",
    
    37
    +          "foo.h"
    
    38
    +        ],
    
    39
    +        "options": [
    
    40
    +          "-XStrict",
    
    41
    +          "-XCPP",
    
    42
    +          "-fexpose-all-unfoldings"
    
    43
    +        ],
    
    44
    +        "preprocessor": null,
    
    45
    +        "source": "A.hs"
    
    267 46
           },
    
    268
    -      {
    
    269
    -        "id": "dep-1-XXX",
    
    270
    -        "modules": {
    
    271
    -          "normal": [
    
    272
    -            "Dep"
    
    273
    -          ],
    
    274
    -          "quote": [],
    
    275
    -          "splice": []
    
    276
    -        },
    
    277
    -        "name": "dep",
    
    278
    -        "package-id": "dep-1"
    
    47
    +      "B": {
    
    48
    +        "imports": [
    
    49
    +          {
    
    50
    +            "base-<VERSION>-<HASH>": [
    
    51
    +              "GHC.Essentials",
    
    52
    +              "Prelude"
    
    53
    +            ]
    
    54
    +          },
    
    55
    +          {
    
    56
    +            "main": [
    
    57
    +              "A"
    
    58
    +            ]
    
    59
    +          }
    
    60
    +        ],
    
    61
    +        "includes": [],
    
    62
    +        "options": [
    
    63
    +          "-F",
    
    64
    +          "-pgmF",
    
    65
    +          "./preproc.sh"
    
    66
    +        ],
    
    67
    +        "preprocessor": "./preproc.sh",
    
    68
    +        "source": "lib/B.hs"
    
    279 69
           },
    
    280
    -      {
    
    281
    -        "id": "dep-public-1-XXX",
    
    282
    -        "modules": {
    
    283
    -          "normal": [
    
    284
    -            "DepPublic"
    
    285
    -          ],
    
    286
    -          "quote": [],
    
    287
    -          "splice": []
    
    288
    -        },
    
    289
    -        "name": "dep-public",
    
    290
    -        "package-id": "dep-public-1"
    
    70
    +      "B[boot]": {
    
    71
    +        "imports": [
    
    72
    +          {
    
    73
    +            "base-<VERSION>-<HASH>": [
    
    74
    +              "GHC.Essentials",
    
    75
    +              "Prelude"
    
    76
    +            ]
    
    77
    +          },
    
    78
    +          {
    
    79
    +            "main": [
    
    80
    +              "A"
    
    81
    +            ]
    
    82
    +          }
    
    83
    +        ],
    
    84
    +        "includes": [],
    
    85
    +        "options": [
    
    86
    +          "-F",
    
    87
    +          "-pgmF",
    
    88
    +          "./preproc.sh"
    
    89
    +        ],
    
    90
    +        "preprocessor": "./preproc.sh",
    
    91
    +        "source": "lib/B.hs-boot"
    
    291 92
           },
    
    292
    -      {
    
    293
    -        "id": "template-haskell-2.25.0.0-inplace",
    
    294
    -        "modules": {
    
    295
    -          "normal": [
    
    296
    -            "Language.Haskell.TH.Syntax"
    
    297
    -          ],
    
    298
    -          "quote": [],
    
    299
    -          "splice": []
    
    300
    -        },
    
    301
    -        "name": "template-haskell",
    
    302
    -        "package-id": "template-haskell-2.25.0.0"
    
    93
    +      "C": {
    
    94
    +        "imports": [
    
    95
    +          {
    
    96
    +            "base-<VERSION>-<HASH>": [
    
    97
    +              "GHC.Essentials",
    
    98
    +              "Prelude"
    
    99
    +            ]
    
    100
    +          },
    
    101
    +          {
    
    102
    +            "containers-<VERSION>-<HASH>": [
    
    103
    +              "Data.Set"
    
    104
    +            ]
    
    105
    +          },
    
    106
    +          {
    
    107
    +            "main": [
    
    108
    +              "A"
    
    109
    +            ]
    
    110
    +          }
    
    111
    +        ],
    
    112
    +        "includes": [],
    
    113
    +        "options": [],
    
    114
    +        "preprocessor": null,
    
    115
    +        "source": "C.hs"
    
    116
    +      },
    
    117
    +      "C[boot]": {
    
    118
    +        "imports": [
    
    119
    +          {
    
    120
    +            "base-<VERSION>-<HASH>": [
    
    121
    +              "GHC.Essentials",
    
    122
    +              "Prelude"
    
    123
    +            ]
    
    124
    +          },
    
    125
    +          {
    
    126
    +            "main": [
    
    127
    +              "E"
    
    128
    +            ]
    
    129
    +          }
    
    130
    +        ],
    
    131
    +        "includes": [],
    
    132
    +        "options": [],
    
    133
    +        "preprocessor": null,
    
    134
    +        "source": "C.hs-boot"
    
    135
    +      },
    
    136
    +      "D": {
    
    137
    +        "imports": [
    
    138
    +          {
    
    139
    +            "base-<VERSION>-<HASH>": [
    
    140
    +              "GHC.Essentials",
    
    141
    +              "Prelude"
    
    142
    +            ]
    
    143
    +          },
    
    144
    +          {
    
    145
    +            "main": [
    
    146
    +              "B",
    
    147
    +              "C"
    
    148
    +            ]
    
    149
    +          }
    
    150
    +        ],
    
    151
    +        "includes": [],
    
    152
    +        "options": [],
    
    153
    +        "preprocessor": null,
    
    154
    +        "source": "D.hs"
    
    155
    +      },
    
    156
    +      "E": {
    
    157
    +        "imports": [
    
    158
    +          {
    
    159
    +            "base-<VERSION>-<HASH>": [
    
    160
    +              "GHC.Essentials",
    
    161
    +              "Prelude"
    
    162
    +            ]
    
    163
    +          },
    
    164
    +          {
    
    165
    +            "dep-1-XXX": [
    
    166
    +              "Dep"
    
    167
    +            ]
    
    168
    +          },
    
    169
    +          {
    
    170
    +            "dep-public-1-XXX": [
    
    171
    +              "DepPublic"
    
    172
    +            ]
    
    173
    +          },
    
    174
    +          {
    
    175
    +            "template-haskell-<VERSION>-<HASH>": [
    
    176
    +              "Language.Haskell.TH.Syntax"
    
    177
    +            ]
    
    178
    +          }
    
    179
    +        ],
    
    180
    +        "includes": [],
    
    181
    +        "options": [],
    
    182
    +        "preprocessor": null,
    
    183
    +        "source": "E.hs"
    
    303 184
           }
    
    304
    -    ],
    
    305
    -    "preprocessor": null,
    
    306
    -    "sources": [
    
    307
    -      "E.hs"
    
    308
    -    ]
    
    185
    +    }
    
    186
    +  },
    
    187
    +  "template-haskell-<VERSION>-<HASH>": {
    
    188
    +    "package-id": "template-haskell-<VERSION>-<HASH>",
    
    189
    +    "package-name": "template-haskell"
    
    309 190
       }
    
    310 191
     }

  • testsuite/tests/driver/T24384/T24384b.stdout-mingw
    1
    +{
    
    2
    +  "base-<VERSION>-<HASH>": {
    
    3
    +    "package-id": "base-<VERSION>-<HASH>",
    
    4
    +    "package-name": "base"
    
    5
    +  },
    
    6
    +  "containers-<VERSION>-<HASH>": {
    
    7
    +    "package-id": "containers-<VERSION>-<HASH>",
    
    8
    +    "package-name": "containers"
    
    9
    +  },
    
    10
    +  "dep-1-XXX": {
    
    11
    +    "package-id": "dep-1",
    
    12
    +    "package-name": "dep"
    
    13
    +  },
    
    14
    +  "dep-public-1-XXX": {
    
    15
    +    "package-id": "dep-public-1",
    
    16
    +    "package-name": "dep-public"
    
    17
    +  },
    
    18
    +  "main": {
    
    19
    +    "modules": {
    
    20
    +      "A": {
    
    21
    +        "imports": [
    
    22
    +          {
    
    23
    +            "base-<VERSION>-<HASH>": [
    
    24
    +              "GHC.Essentials",
    
    25
    +              "Prelude"
    
    26
    +            ]
    
    27
    +          },
    
    28
    +          {
    
    29
    +            "main": [
    
    30
    +              "C[boot]"
    
    31
    +            ]
    
    32
    +          }
    
    33
    +        ],
    
    34
    +        "includes": [
    
    35
    +          "<absolute-path>/ghcversion.h",
    
    36
    +          "<absolute-path>/stdc-predef.h",
    
    37
    +          "foo.h"
    
    38
    +        ],
    
    39
    +        "options": [
    
    40
    +          "-XStrict",
    
    41
    +          "-XCPP",
    
    42
    +          "-fexpose-all-unfoldings"
    
    43
    +        ],
    
    44
    +        "preprocessor": null,
    
    45
    +        "source": "A.hs"
    
    46
    +      },
    
    47
    +      "B": {
    
    48
    +        "imports": [
    
    49
    +          {
    
    50
    +            "base-<VERSION>-<HASH>": [
    
    51
    +              "GHC.Essentials",
    
    52
    +              "Prelude"
    
    53
    +            ]
    
    54
    +          },
    
    55
    +          {
    
    56
    +            "main": [
    
    57
    +              "A"
    
    58
    +            ]
    
    59
    +          }
    
    60
    +        ],
    
    61
    +        "includes": [],
    
    62
    +        "options": [
    
    63
    +          "-F",
    
    64
    +          "-pgmF",
    
    65
    +          "./preproc.sh"
    
    66
    +        ],
    
    67
    +        "preprocessor": "./preproc.sh",
    
    68
    +        "source": "lib/B.hs"
    
    69
    +      },
    
    70
    +      "B[boot]": {
    
    71
    +        "imports": [
    
    72
    +          {
    
    73
    +            "base-<VERSION>-<HASH>": [
    
    74
    +              "GHC.Essentials",
    
    75
    +              "Prelude"
    
    76
    +            ]
    
    77
    +          },
    
    78
    +          {
    
    79
    +            "main": [
    
    80
    +              "A"
    
    81
    +            ]
    
    82
    +          }
    
    83
    +        ],
    
    84
    +        "includes": [],
    
    85
    +        "options": [
    
    86
    +          "-F",
    
    87
    +          "-pgmF",
    
    88
    +          "./preproc.sh"
    
    89
    +        ],
    
    90
    +        "preprocessor": "./preproc.sh",
    
    91
    +        "source": "lib/B.hs-boot"
    
    92
    +      },
    
    93
    +      "C": {
    
    94
    +        "imports": [
    
    95
    +          {
    
    96
    +            "base-<VERSION>-<HASH>": [
    
    97
    +              "GHC.Essentials",
    
    98
    +              "Prelude"
    
    99
    +            ]
    
    100
    +          },
    
    101
    +          {
    
    102
    +            "containers-<VERSION>-<HASH>": [
    
    103
    +              "Data.Set"
    
    104
    +            ]
    
    105
    +          },
    
    106
    +          {
    
    107
    +            "main": [
    
    108
    +              "A"
    
    109
    +            ]
    
    110
    +          }
    
    111
    +        ],
    
    112
    +        "includes": [],
    
    113
    +        "options": [],
    
    114
    +        "preprocessor": null,
    
    115
    +        "source": "C.hs"
    
    116
    +      },
    
    117
    +      "C[boot]": {
    
    118
    +        "imports": [
    
    119
    +          {
    
    120
    +            "base-<VERSION>-<HASH>": [
    
    121
    +              "GHC.Essentials",
    
    122
    +              "Prelude"
    
    123
    +            ]
    
    124
    +          },
    
    125
    +          {
    
    126
    +            "main": [
    
    127
    +              "E"
    
    128
    +            ]
    
    129
    +          }
    
    130
    +        ],
    
    131
    +        "includes": [],
    
    132
    +        "options": [],
    
    133
    +        "preprocessor": null,
    
    134
    +        "source": "C.hs-boot"
    
    135
    +      },
    
    136
    +      "D": {
    
    137
    +        "imports": [
    
    138
    +          {
    
    139
    +            "base-<VERSION>-<HASH>": [
    
    140
    +              "GHC.Essentials",
    
    141
    +              "Prelude"
    
    142
    +            ]
    
    143
    +          },
    
    144
    +          {
    
    145
    +            "main": [
    
    146
    +              "B",
    
    147
    +              "C"
    
    148
    +            ]
    
    149
    +          }
    
    150
    +        ],
    
    151
    +        "includes": [],
    
    152
    +        "options": [],
    
    153
    +        "preprocessor": null,
    
    154
    +        "source": "D.hs"
    
    155
    +      },
    
    156
    +      "E": {
    
    157
    +        "imports": [
    
    158
    +          {
    
    159
    +            "base-<VERSION>-<HASH>": [
    
    160
    +              "GHC.Essentials",
    
    161
    +              "Prelude"
    
    162
    +            ]
    
    163
    +          },
    
    164
    +          {
    
    165
    +            "dep-1-XXX": [
    
    166
    +              "Dep"
    
    167
    +            ]
    
    168
    +          },
    
    169
    +          {
    
    170
    +            "dep-public-1-XXX": [
    
    171
    +              "DepPublic"
    
    172
    +            ]
    
    173
    +          },
    
    174
    +          {
    
    175
    +            "template-haskell-<VERSION>-<HASH>": [
    
    176
    +              "Language.Haskell.TH.Syntax"
    
    177
    +            ]
    
    178
    +          }
    
    179
    +        ],
    
    180
    +        "includes": [],
    
    181
    +        "options": [],
    
    182
    +        "preprocessor": null,
    
    183
    +        "source": "E.hs"
    
    184
    +      }
    
    185
    +    }
    
    186
    +  },
    
    187
    +  "template-haskell-<VERSION>-<HASH>": {
    
    188
    +    "package-id": "template-haskell-<VERSION>-<HASH>",
    
    189
    +    "package-name": "template-haskell"
    
    190
    +  }
    
    191
    +}

  • testsuite/tests/driver/T24384/T24384c.stdout
    1
    +{
    
    2
    +  "main": {
    
    3
    +    "modules": {
    
    4
    +      "A": {
    
    5
    +        "imports": [
    
    6
    +          {
    
    7
    +            "main": [
    
    8
    +              "C[boot]"
    
    9
    +            ]
    
    10
    +          }
    
    11
    +        ],
    
    12
    +        "includes": [],
    
    13
    +        "options": [
    
    14
    +          "-XStrict",
    
    15
    +          "-XCPP",
    
    16
    +          "-fexpose-all-unfoldings"
    
    17
    +        ],
    
    18
    +        "preprocessor": null,
    
    19
    +        "source": "A.hs"
    
    20
    +      },
    
    21
    +      "B": {
    
    22
    +        "imports": [
    
    23
    +          {
    
    24
    +            "main": [
    
    25
    +              "A"
    
    26
    +            ]
    
    27
    +          }
    
    28
    +        ],
    
    29
    +        "includes": [],
    
    30
    +        "options": [
    
    31
    +          "-F",
    
    32
    +          "-pgmF",
    
    33
    +          "./preproc.sh"
    
    34
    +        ],
    
    35
    +        "preprocessor": "./preproc.sh",
    
    36
    +        "source": "lib/B.hs"
    
    37
    +      },
    
    38
    +      "B[boot]": {
    
    39
    +        "imports": [
    
    40
    +          {
    
    41
    +            "main": [
    
    42
    +              "A"
    
    43
    +            ]
    
    44
    +          }
    
    45
    +        ],
    
    46
    +        "includes": [],
    
    47
    +        "options": [
    
    48
    +          "-F",
    
    49
    +          "-pgmF",
    
    50
    +          "./preproc.sh"
    
    51
    +        ],
    
    52
    +        "preprocessor": "./preproc.sh",
    
    53
    +        "source": "lib/B.hs-boot"
    
    54
    +      },
    
    55
    +      "C": {
    
    56
    +        "imports": [
    
    57
    +          {
    
    58
    +            "main": [
    
    59
    +              "A"
    
    60
    +            ]
    
    61
    +          }
    
    62
    +        ],
    
    63
    +        "includes": [],
    
    64
    +        "options": [],
    
    65
    +        "preprocessor": null,
    
    66
    +        "source": "C.hs"
    
    67
    +      },
    
    68
    +      "C[boot]": {
    
    69
    +        "imports": [
    
    70
    +          {
    
    71
    +            "main": [
    
    72
    +              "E"
    
    73
    +            ]
    
    74
    +          }
    
    75
    +        ],
    
    76
    +        "includes": [],
    
    77
    +        "options": [],
    
    78
    +        "preprocessor": null,
    
    79
    +        "source": "C.hs-boot"
    
    80
    +      },
    
    81
    +      "D": {
    
    82
    +        "imports": [
    
    83
    +          {
    
    84
    +            "main": [
    
    85
    +              "B",
    
    86
    +              "C"
    
    87
    +            ]
    
    88
    +          }
    
    89
    +        ],
    
    90
    +        "includes": [],
    
    91
    +        "options": [],
    
    92
    +        "preprocessor": null,
    
    93
    +        "source": "D.hs"
    
    94
    +      },
    
    95
    +      "E": {
    
    96
    +        "imports": [],
    
    97
    +        "includes": [],
    
    98
    +        "options": [],
    
    99
    +        "preprocessor": null,
    
    100
    +        "source": "E.hs"
    
    101
    +      }
    
    102
    +    }
    
    103
    +  }
    
    104
    +}

  • testsuite/tests/driver/T24384/all.T
    1
    +
    
    2
    +json_normalisers =  [ normalise_version('base', 'containers', 'template-haskell')
    
    3
    +                    , normalise_slashes
    
    4
    +                    , normalise_fun(normalise_dep_json)
    
    5
    +                    ]
    
    6
    +
    
    7
    +makefile_normalisers = [ normalise_slashes, normalise_fun(normalise_dep_makefile) ]
    
    8
    +
    
    1 9
     test_extras = extra_files(
    
    2 10
       ['A.hs', 'lib/', 'C.hs', 'C.hs-boot', 'D.hs', 'E.hs',
    
    3 11
       'foo.h',
    
    ... ... @@ -5,7 +13,8 @@ test_extras = extra_files(
    5 13
       'preproc.sh'
    
    6 14
       ])
    
    7 15
     
    
    8
    -normalisers = normalise_version('base', 'containers', 'template-haskell')
    
    16
    +skip_on_mingw = when(opsys('mingw32'), skip)
    
    9 17
     
    
    10
    -test('T24384a', [ test_extras, normalisers, pre_cmd('$MAKE -s --no-print-directory T24384_prep') ], makefile_test, [])
    
    11
    -test('T24384b', [ test_extras, normalisers, pre_cmd('$MAKE -s --no-print-directory T24384_prep') ], makefile_test, [])
    18
    +test('T24384a', [ test_extras, pre_cmd('$MAKE -s --no-print-directory T24384_prep'), *makefile_normalisers ], makefile_test, [])
    
    19
    +test('T24384b', [ test_extras, pre_cmd('$MAKE -s --no-print-directory T24384_prep'), skip_on_mingw, *json_normalisers ], makefile_test, [])
    
    20
    +test('T24384c', [ test_extras, pre_cmd('$MAKE -s --no-print-directory T24384_prep'), skip_on_mingw, *json_normalisers ], makefile_test, [])

  • testsuite/tests/driver/T24384/format_json.sh
    1
    +#! /usr/bin/env bash
    
    2
    +set -euo pipefail
    
    3
    +
    
    4
    +# Packages whose ids are rewritten to <pkg>-<VERSION>-<HASH>
    
    5
    +pkgs='base|containers|template-haskell'
    
    6
    +
    
    7
    +usage() {
    
    8
    +  cat <<EOF
    
    9
    +Usage: $(basename "$0") FILE
    
    10
    +
    
    11
    +Format one of the test -dep-json output file with jq and normalise it:
    
    12
    +  - absolute paths in "includes" become <absolute-path>/<filename>,
    
    13
    +    and the "includes" lists are sorted
    
    14
    +  - ids of the packages ${packages[*]}
    
    15
    +    (e.g. base-4.23.0.0-inplace) become <pkg>-<VERSION>-<HASH>
    
    16
    +
    
    17
    +Writes the output to FILE
    
    18
    +EOF
    
    19
    +}
    
    20
    +
    
    21
    +case "${1:-}" in -h|--help) usage; exit 0 ;; esac
    
    22
    +[ $# -eq 1 ] || { usage >&2; exit 1; }
    
    23
    +
    
    24
    +# Escape regex metacharacters (and the / delimiter) for sed
    
    25
    +esc() { sed 's/[][\.*^$+?(){}|/]/\\&/g'; }
    
    26
    +
    
    27
    +json=$(jq --sort-keys '
    
    28
    +  (.. | objects | select(has("includes")) | .includes) |=
    
    29
    +    (map(if startswith("/") then "<absolute-path>/" + (split("/") | last) else . end) | sort)
    
    30
    +' "$1")
    
    31
    +
    
    32
    +tmp=$(mktemp "$1.XXXXXX")
    
    33
    +trap 'rm -f "$tmp"' EXIT
    
    34
    +sed -E "s/($pkgs)-[0-9.]+(-[0-9a-zA-Z+]+)?(-[0-9a-zA-Z]+)?/\\1-<VERSION>-<HASH>/g" <<<"$json" > "$tmp"
    
    35
    +mv "$tmp" "$1"

  • testsuite/tests/driver/T24384/format_makefile.sh
    1
    +#! /usr/bin/env bash
    
    2
    +set -euo pipefail
    
    3
    +
    
    4
    +usage() {
    
    5
    +  cat <<EOF
    
    6
    +Usage: $(basename "$0") FILE
    
    7
    +
    
    8
    +Normalise a Makefile written by 'ghc -M':
    
    9
    +  - absolute dependency paths become <absolute-path>/<filename>
    
    10
    +  - each block of "target : dependency" rules is sorted
    
    11
    +
    
    12
    +Writes the output to FILE
    
    13
    +EOF
    
    14
    +}
    
    15
    +
    
    16
    +case "${1:-}" in -h|--help) usage; exit 0 ;; esac
    
    17
    +[ $# -eq 1 ] || { usage >&2; exit 1; }
    
    18
    +
    
    19
    +tmp=$(mktemp "$1.XXXXXX")
    
    20
    +trap 'rm -f "$tmp"' EXIT
    
    21
    +
    
    22
    +sed -E 's#^(.* : )/.*/#\1<absolute-path>/#' "$1" |
    
    23
    +  awk '
    
    24
    +    / : / { print | "LC_ALL=C sort"; next }
    
    25
    +    { close("LC_ALL=C sort"); print; fflush() }
    
    26
    +    END { close("LC_ALL=C sort") }
    
    27
    +  ' > "$tmp"
    
    28
    +mv "$tmp" "$1"