Sven Tennie pushed to branch wip/supersven/hadrian-cross-stage3 at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • hadrian/src/BindistConfig.hs
    ... ... @@ -3,6 +3,7 @@ module BindistConfig where
    3 3
     import Stage
    
    4 4
     import Oracles.Flag
    
    5 5
     import Expression
    
    6
    +import UserSettings (finalStage)
    
    6 7
     
    
    7 8
     data BindistConfig = BindistConfig { library_stage :: Stage -- ^ The stage compiler which builds the libraries
    
    8 9
                                        , executable_stage :: Stage -- ^ The stage compiler which builds the executables
    
    ... ... @@ -32,7 +33,9 @@ implicitBindistConfig = do
    32 33
       -- libraries built for the host, but the distributed compiler would produce files for
    
    33 34
       -- the target.
    
    34 35
       cross <- flag CrossCompiling
    
    35
    -  return $ if cross then crossBindist else normalBindist
    
    36
    +  if not cross
    
    37
    +    then return normalBindist
    
    38
    +    else return $ if finalStage == Stage3 then targetBindist else crossBindist
    
    36 39
     
    
    37 40
     -- | Are we building things in this stage for the final target?
    
    38 41
     buildingForTarget ::  Stage -> Action Bool
    

  • hadrian/src/Rules/BinaryDist.hs
    ... ... @@ -110,12 +110,12 @@ other, the install script:
    110 110
     
    
    111 111
     data Relocatable = Relocatable | NotRelocatable
    
    112 112
     
    
    113
    -installTo :: Relocatable -> String -> Action ()
    
    114
    -installTo relocatable prefix = do
    
    113
    +installTo :: Relocatable -> FilePath -> String -> Action ()
    
    114
    +installTo relocatable dirSuffix prefix = do
    
    115 115
         root <- buildRoot
    
    116 116
         version        <- setting ProjectVersion
    
    117 117
         targetPlatform <- setting TargetPlatformFull
    
    118
    -    let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
    
    118
    +    let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform <> dirSuffix
    
    119 119
             bindistFilesDir  = root -/- "bindist" -/- ghcVersionPretty
    
    120 120
         runBuilder (Configure bindistFilesDir) ["--prefix="++prefix] [] []
    
    121 121
         let env = case relocatable of
    
    ... ... @@ -124,8 +124,8 @@ installTo relocatable prefix = do
    124 124
         runBuilderWithCmdOptions env (Make bindistFilesDir) ["install"] [] []
    
    125 125
     
    
    126 126
     
    
    127
    -buildBinDistDir :: FilePath -> BindistConfig -> Action ()
    
    128
    -buildBinDistDir root conf@BindistConfig{..} = do
    
    127
    +buildBinDistDir :: FilePath -> FilePath -> BindistConfig -> Action ()
    
    128
    +buildBinDistDir dirSuffix root conf@BindistConfig{..} = do
    
    129 129
     
    
    130 130
         verbosity <- getVerbosity
    
    131 131
         -- We 'need' all binaries and libraries
    
    ... ... @@ -155,7 +155,7 @@ buildBinDistDir root conf@BindistConfig{..} = do
    155 155
         distDir        <- Context.distDir (vanillaContext library_stage rts)
    
    156 156
     
    
    157 157
         let ghcBuildDir      = root -/- stageString library_stage
    
    158
    -        bindistFilesDir  = root -/- "bindist" -/- ghcVersionPretty
    
    158
    +        bindistFilesDir  = root -/- "bindist" -/- ghcVersionPretty <> dirSuffix
    
    159 159
             ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
    
    160 160
             rtsIncludeDir    = distDir -/- "include"
    
    161 161
     
    
    ... ... @@ -228,7 +228,7 @@ buildBinDistDir root conf@BindistConfig{..} = do
    228 228
         let bindistSettings = bindistFilesDir -/- "lib" -/- "settings"
    
    229 229
             bindistContext = vanillaContext library_stage compiler
    
    230 230
         bindistSettingsContent <- interpretInContext bindistContext $
    
    231
    -        generateSettings bindistSettings False "package.conf.d"
    
    231
    +        generateSettings bindistSettings False "package.conf.d" executable_stage
    
    232 232
         writeFile' bindistSettings bindistSettingsContent
    
    233 233
     
    
    234 234
         copyDirectory rtsIncludeDir         bindistFilesDir
    
    ... ... @@ -240,10 +240,16 @@ buildBinDistDir root conf@BindistConfig{..} = do
    240 240
         --
    
    241 241
         -- N.B. the ghc-pkg executable may be prefixed with a target triple
    
    242 242
         -- (c.f. #20267).
    
    243
    -
    
    244
    -    -- Not going to work for cross
    
    245
    -    ghcPkgName <- programName (vanillaContext Stage1 ghcPkg)
    
    246
    -    cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ]
    
    243
    +    --
    
    244
    +    -- For target bindists the executable_stage binaries run on the target, not
    
    245
    +    -- the build host, so we fall back to the prior stage's ghc-pkg.
    
    246
    +    canRunGhcPkg <- not <$> crossStage (predStage executable_stage)
    
    247
    +    if canRunGhcPkg then do
    
    248
    +      ghcPkgName <- programName (vanillaContext executable_stage ghcPkg)
    
    249
    +      cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ]
    
    250
    +    else do
    
    251
    +      ghcPkgPath <- builderPath $ GhcPkg Recache library_stage
    
    252
    +      cmd_ ghcPkgPath ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ]
    
    247 253
     
    
    248 254
     
    
    249 255
         need ["docs"]
    
    ... ... @@ -318,45 +324,45 @@ buildBinDistDir root conf@BindistConfig{..} = do
    318 324
     bindistRules :: Rules ()
    
    319 325
     bindistRules = do
    
    320 326
         root <- buildRootRules
    
    321
    -    phony "reloc-binary-dist-dir" $ do
    
    322
    -        need ["binary-dist-dir"]
    
    327
    +    forM_ ["", "-stage3"] $ \suffix -> do
    
    328
    +      phony ("reloc-binary-dist-dir" ++ suffix) $ do
    
    329
    +        need ["binary-dist-dir" ++ suffix]
    
    323 330
             cwd <- liftIO IO.getCurrentDirectory
    
    324 331
             version        <- setting ProjectVersion
    
    325 332
             targetPlatform <- setting TargetPlatformFull
    
    326
    -        let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
    
    327
    -        let prefix = cwd -/- root -/- "reloc-bindist" -/- ghcVersionPretty
    
    328
    -        installTo Relocatable prefix
    
    333
    +        let prefix = cwd -/- root -/- "reloc-bindist" -/- ("ghc-" ++ version ++ "-" ++ targetPlatform ++ suffix)
    
    334
    +        installTo Relocatable suffix prefix
    
    329 335
     
    
    330
    -    phony "install" $ do
    
    331
    -        need ["binary-dist-dir"]
    
    336
    +      phony ("install" ++ suffix) $ do
    
    337
    +        need ["binary-dist-dir" ++ suffix]
    
    332 338
             let prefixErr = "You must specify a path with --prefix when using the"
    
    333
    -                     ++ " 'install' rule"
    
    339
    +                     ++ " 'install" ++ suffix ++ "' rule"
    
    334 340
             installPrefix <- fromMaybe (error prefixErr) <$> cmdPrefix
    
    335
    -        installTo NotRelocatable installPrefix
    
    341
    +        installTo NotRelocatable suffix installPrefix
    
    336 342
     
    
    337 343
         phony "binary-dist-dir" $ do
    
    338 344
           cfg <- implicitBindistConfig
    
    339
    -      buildBinDistDir root cfg
    
    345
    +      buildBinDistDir "" root cfg
    
    340 346
     
    
    341
    -    phony "binary-dist-dir-cross" $ buildBinDistDir root crossBindist
    
    342
    -    -- MP: Not working yet
    
    343
    -    -- phony "binary-dist-dir-stage3" $ buildBinDistDir root targetBindist
    
    347
    +    phony "binary-dist-dir-cross" $ buildBinDistDir "" root crossBindist
    
    348
    +
    
    349
    +    phony "binary-dist-dir-stage3" $ buildBinDistDir "-stage3" root targetBindist
    
    344 350
     
    
    345 351
         let buildBinDist compressor = do
    
    346 352
               win_host <- isWinHost
    
    347 353
               win_target <- isWinTarget Stage2
    
    348 354
               when (win_target && win_host) (error "normal binary-dist does not work for windows targets, use `reloc-binary-dist-*` target instead.")
    
    349
    -          buildBinDistX "binary-dist-dir" "bindist" compressor
    
    350
    -        buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist"
    
    355
    +          buildBinDistX "binary-dist-dir" "bindist" "" compressor
    
    356
    +        buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist" ""
    
    351 357
     
    
    352
    -        buildBinDistX :: String -> FilePath -> Compressor -> Action ()
    
    353
    -        buildBinDistX target bindist_folder compressor = do
    
    358
    +        buildBinDistX :: String -> FilePath -> FilePath -> Compressor -> Action ()
    
    359
    +        buildBinDistX target bindist_folder dirSuffix compressor = do
    
    354 360
                 need [target]
    
    355 361
     
    
    356 362
                 version        <- setting ProjectVersion
    
    357 363
                 targetPlatform <- setting TargetPlatformFull
    
    358 364
     
    
    359
    -            let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
    
    365
    +            let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform <> dirSuffix
    
    360 366
     
    
    361 367
                 -- Finally, we create the archive <root>/bindist/ghc-X.Y.Z-platform.tar.xz
    
    362 368
                 tarPath <- builderPath (Tar Create)
    
    ... ... @@ -371,14 +377,35 @@ bindistRules = do
    371 377
           phony (name <> "-dist-bzip2") $ mk_bindist Bzip2
    
    372 378
           phony (name <> "-dist-xz") $ mk_bindist Xz
    
    373 379
     
    
    374
    -    phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" Xz
    
    375
    -    phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" Xz
    
    380
    +    phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" "" Xz
    
    381
    +    phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" "-stage3" Xz
    
    376 382
     
    
    377 383
         -- Prepare binary distribution configure script
    
    378 384
         -- (generated under <ghc root>/distrib/configure by 'autoreconf')
    
    379
    -    root -/- "bindist" -/- "ghc-*" -/- "configure" %> \configurePath -> do
    
    380
    -        need ["distrib" -/- "configure.ac"]
    
    385
    +    priority 2 $ root -/- "bindist" -/- "*ghc-*-stage3" -/- "configure" %> generateConfigure Stage2
    
    386
    +    root -/- "bindist" -/- "*ghc-*" -/- "configure" %> generateConfigure Stage1
    
    387
    +
    
    388
    +    -- Generate the Makefile that enables the "make install" part
    
    389
    +    root -/- "bindist" -/- "*ghc-*" -/- "Makefile" %> \makefilePath -> do
    
    390
    +        top <- topDirectory
    
    391
    +        copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath
    
    392
    +
    
    393
    +    -- Copy various configure-related files needed for a working
    
    394
    +    -- './configure [...] && make install' workflow
    
    395
    +    -- (see the list of files needed in the 'binary-dist' rule above, before
    
    396
    +    -- creating the archive).
    
    397
    +    forM_ bindistInstallFiles $ \file ->
    
    398
    +        root -/- "bindist" -/- "*ghc-*" -/- file %> \dest -> do
    
    399
    +            copyFile (fixup file) dest
    
    400
    +
    
    401
    +  where
    
    402
    +    fixup f | f `elem` ["INSTALL", "README"] = "distrib" -/- f
    
    403
    +            | otherwise                      = f
    
    404
    +    generateConfigure stage configurePath = do
    
    405
    +        let acFile = stageString stage -/- "distrib" -/- "configure.ac"
    
    406
    +        need [acFile]
    
    381 407
             ghcRoot <- topDirectory
    
    408
    +        copyFile (ghcRoot -/- acFile) (ghcRoot -/- "distrib" -/- "configure.ac")
    
    382 409
             copyFile (ghcRoot -/- "aclocal.m4") (ghcRoot -/- "distrib" -/- "aclocal.m4")
    
    383 410
             copyDirectory (ghcRoot -/- "m4") (ghcRoot -/- "distrib")
    
    384 411
     
    
    ... ... @@ -401,30 +428,12 @@ bindistRules = do
    401 428
     
    
    402 429
             buildWithCmdOptions env $
    
    403 430
                 target (vanillaContext Stage1 ghc) (Autoreconf $ ghcRoot -/- "distrib") [] []
    
    404
    -        -- We clean after ourselves, moving the configure script we generated in
    
    405
    -        -- our bindist dir
    
    431
    +        removeFile (ghcRoot -/- acFile)
    
    432
    +        removeFile (ghcRoot -/- "distrib" -/- "configure.ac")
    
    406 433
             removeFile (ghcRoot -/- "distrib" -/- "aclocal.m4")
    
    407 434
             removeDirectory (ghcRoot -/- "distrib" -/- "m4")
    
    408
    -
    
    409 435
             moveFile (ghcRoot -/- "distrib" -/- "configure") configurePath
    
    410 436
     
    
    411
    -    -- Generate the Makefile that enables the "make install" part
    
    412
    -    root -/- "bindist" -/- "ghc-*" -/- "Makefile" %> \makefilePath -> do
    
    413
    -        top <- topDirectory
    
    414
    -        copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath
    
    415
    -
    
    416
    -    -- Copy various configure-related files needed for a working
    
    417
    -    -- './configure [...] && make install' workflow
    
    418
    -    -- (see the list of files needed in the 'binary-dist' rule above, before
    
    419
    -    -- creating the archive).
    
    420
    -    forM_ bindistInstallFiles $ \file ->
    
    421
    -        root -/- "bindist" -/- "ghc-*" -/- file %> \dest -> do
    
    422
    -            copyFile (fixup file) dest
    
    423
    -
    
    424
    -  where
    
    425
    -    fixup f | f `elem` ["INSTALL", "README"] = "distrib" -/- f
    
    426
    -            | otherwise                      = f
    
    427
    -
    
    428 437
     data Compressor = Gzip | Bzip2 | Xz
    
    429 438
                     deriving (Eq, Ord, Show)
    
    430 439
     
    
    ... ... @@ -499,7 +508,7 @@ pkgToWrappers stage pkg = do
    499 508
             -- These are the packages which we want to expose to the user and hence
    
    500 509
             -- there are wrappers installed in the bindist.
    
    501 510
           | pkg `elem` [hpcBin, haddock, hp2ps, hsc2hs, ghc, ghcPkg]
    
    502
    -                      -> (:[]) <$> (programName =<< programContext Stage1 pkg)
    
    511
    +                      -> (:[]) <$> (programName =<< programContext stage pkg)
    
    503 512
           | otherwise     -> pure []
    
    504 513
     
    
    505 514
     wrapper :: Stage -> FilePath -> Action String
    

  • hadrian/src/Rules/CabalReinstall.hs
    ... ... @@ -67,13 +67,15 @@ cabalBuildRules = do
    67 67
     
    
    68 68
             let cabal_package_db = cwd -/- root -/- "stage-cabal" -/- "dist-newstyle" -/- "packagedb" -/- "ghc-" ++ version
    
    69 69
     
    
    70
    +        cfg <- implicitBindistConfig
    
    71
    +        let compilerStage = executable_stage cfg
    
    70 72
             forM_ bin_targets $ \(bin_pkg,_bin_path) -> do
    
    71 73
                 let pgmName pkg
    
    72 74
                       | pkg == ghc    = "ghc"
    
    73 75
                       | pkg == hpcBin = "hpc"
    
    74 76
                       | otherwise     = pkgName pkg
    
    75 77
                 let cabal_bin_out = work_dir -/- "cabal-bin" -/- (pgmName bin_pkg)
    
    76
    -            needed_wrappers <- pkgToWrappers Stage2 bin_pkg
    
    78
    +            needed_wrappers <- pkgToWrappers compilerStage bin_pkg
    
    77 79
                 forM_ needed_wrappers $ \wrapper_name -> do
    
    78 80
                   let wrapper_prefix = unlines
    
    79 81
                         ["#!/usr/bin/env sh"
    
    ... ... @@ -85,7 +87,7 @@ cabalBuildRules = do
    85 87
                         ,"export GHC_PACKAGE_PATH="++show cabal_package_db++":"
    
    86 88
                         ]
    
    87 89
                       output_file = outputDir -/- wrapper_name
    
    88
    -              wrapper_content <- wrapper Stage2 wrapper_name
    
    90
    +              wrapper_content <- wrapper compilerStage wrapper_name
    
    89 91
                   writeFile' output_file (wrapper_prefix ++ wrapper_content)
    
    90 92
                   makeExecutable output_file
    
    91 93
                   pure ()
    

  • hadrian/src/Rules/Generate.hs
    ... ... @@ -275,7 +275,7 @@ generateRules = do
    275 275
                           then root -/- stageString stage' -/- "lib"
    
    276 276
                           else prefix
    
    277 277
                     relPkgDb = makeRelativeNoSysLink libTopDir pkgDb
    
    278
    -            go (generateSettings out True relPkgDb) out
    
    278
    +            go (generateSettings out True relPkgDb (predStage stage')) out
    
    279 279
             (prefix -/- "targets" -/- "default.target") %> \out -> go (show <$> expr (targetStage (succStage stage))) out
    
    280 280
     
    
    281 281
       where
    
    ... ... @@ -360,6 +360,11 @@ templateRule :: FilePath -> Interpolations -> Rules ()
    360 360
     templateRule outPath =
    
    361 361
       templateRuleFrom (outPath <.> "in") outPath
    
    362 362
     
    
    363
    +templateRuleForStages :: FilePath -> (Stage -> Interpolations) -> Rules ()
    
    364
    +templateRuleForStages outPath mkInterps =
    
    365
    +  forM_ [Stage1, Stage2] $ \stage ->
    
    366
    +    templateRuleFrom (outPath <.> "in") (stageString stage -/- outPath) (mkInterps stage)
    
    367
    +
    
    363 368
     templateRules :: Rules ()
    
    364 369
     templateRules = do
    
    365 370
       templateRule "compiler/ghc.cabal" $ projectVersion
    
    ... ... @@ -427,12 +432,13 @@ bindistRules = do
    427 432
         , interpolateVar "TargetOS_CPP" $ cppify <$> getTarget queryOS
    
    428 433
         , interpolateVar "LLVMTarget" $ getTarget tgtLlvmTarget
    
    429 434
         ]
    
    430
    -  templateRule ("distrib" -/- "configure.ac") $ mconcat
    
    435
    +  templateRuleForStages ("distrib" -/- "configure.ac") $ \stage -> mconcat
    
    431 436
         [ interpolateSetting "ConfiguredEmsdkVersion" EmsdkVersion
    
    432 437
         , interpolateVar "CrossCompilePrefix" $ do
    
    433
    -        crossCompiling <- interp $ getFlag CrossCompiling
    
    434
    -        tpf <- setting TargetPlatformFull
    
    435
    -        pure $ if crossCompiling then tpf <> "-" else ""
    
    438
    +        cross  <- interp $ getFlag CrossCompiling
    
    439
    +        isCross <- crossStage stage
    
    440
    +        target <- setting TargetPlatformFull
    
    441
    +        pure $ if cross && isCross then target <> "-" else ""
    
    436 442
         , interpolateVar "LeadingUnderscore" $ yesNo <$> getTarget tgtSymbolsHaveLeadingUnderscore
    
    437 443
         , interpolateSetting "LlvmMaxVersion" LlvmMaxVersion
    
    438 444
         , interpolateSetting "LlvmMinVersion" LlvmMinVersion
    
    ... ... @@ -442,8 +448,8 @@ bindistRules = do
    442 448
         , interpolateVar "TablesNextToCode" $ yesNo <$> getTarget tgtTablesNextToCode
    
    443 449
         , interpolateVar "TargetHasLibm" $ yesNo <$> interp (staged (buildFlag TargetHasLibm))
    
    444 450
         , interpolateVar "TargetPlatform" $ getTarget targetPlatformTriple
    
    445
    -    , interpolateVar "BuildPlatform"  $ interp $ queryBuild targetPlatformTriple
    
    446
    -    , interpolateVar "HostPlatform"   $ interp $ queryHost targetPlatformTriple
    
    451
    +    , interpolateVar "BuildPlatform"  $ ifM (not <$> crossStage stage) (getTarget targetPlatformTriple) (interp $ queryBuild targetPlatformTriple)
    
    452
    +    , interpolateVar "HostPlatform"   $ ifM (not <$> crossStage stage) (getTarget targetPlatformTriple) (interp $ queryHost targetPlatformTriple)
    
    447 453
         , interpolateVar "TargetWordBigEndian" $ getTarget isBigEndian
    
    448 454
         , interpolateVar "TargetWordSize" $ getTarget wordSize
    
    449 455
         , interpolateVar "Unregisterised" $ yesNo <$> getTarget tgtUnregisterised
    
    ... ... @@ -452,8 +458,8 @@ bindistRules = do
    452 458
         , interpolateVar "BaseUnitId" $ pkgUnitId Stage1 base
    
    453 459
         , interpolateVar "GhcWithSMP" $ yesNo <$> targetSupportsSMP Stage2
    
    454 460
         , interpolateVar "TargetPlatformFull" (setting TargetPlatformFull)
    
    455
    -    , interpolateVar "BuildPlatformFull" (setting BuildPlatformFull)
    
    456
    -    , interpolateVar "HostPlatformFull"  (setting HostPlatformFull)
    
    461
    +    , interpolateVar "BuildPlatformFull" $ ifM (not <$> crossStage stage) (setting TargetPlatformFull) (setting BuildPlatformFull)
    
    462
    +    , interpolateVar "HostPlatformFull" $ ifM (not <$> crossStage stage) (setting TargetPlatformFull) (setting HostPlatformFull)
    
    457 463
         ]
    
    458 464
       where
    
    459 465
         interp = interpretInContext (semiEmptyTarget Stage2)
    
    ... ... @@ -483,8 +489,8 @@ ghcWrapper stage = do
    483 489
     -- "package.conf.d"). Callers supply the correct relative path. For bindists
    
    484 490
     -- the layout is known statically; for in-tree builds callers compute it. For
    
    485 491
     -- bindists, we omit @LibDir@ so it defaults to @topDir@ at runtime.
    
    486
    -generateSettings :: FilePath -> Bool -> FilePath -> Expr String
    
    487
    -generateSettings settingsFile includeLibDir rel_pkg_db = do
    
    492
    +generateSettings :: FilePath -> Bool -> FilePath -> Stage -> Expr String
    
    493
    +generateSettings settingsFile includeLibDir rel_pkg_db compilerStage = do
    
    488 494
         ctx <- getContext
    
    489 495
         stage <- getStage
    
    490 496
     
    
    ... ... @@ -499,7 +505,6 @@ generateSettings settingsFile includeLibDir rel_pkg_db = do
    499 505
         -- For cross compilers, LibDir points to the succeeding stage's lib dir
    
    500 506
         -- (which contains the target architecture's libraries). For non-cross,
    
    501 507
         -- it points to the preceding stage's lib dir as usual.
    
    502
    -    let compilerStage = predStage stage  -- the GHC that builds packages in this stage
    
    503 508
         isCrossLibDir <- expr $ crossStage compilerStage
    
    504 509
         let stage_dir_stage = if isCrossLibDir then stage else compilerStage
    
    505 510