<commit_before>module Settings.GhcCabal (
    cabalArgs, bootPackageDbArgs, customPackageArgs
    ) where

import Way
import Util
import Stage
import Builder
import Package
import Switches
import Expression
import Oracles.Base
import Oracles.Flag
import Oracles.Setting
import Settings.User
import Settings.Ways
import Settings.Util
import Settings.Packages
import Data.List
import Control.Applicative

cabalArgs :: Args
cabalArgs = builder GhcCabal ? do
    path <- getPackagePath
    dir  <- getTargetDirectory
    mconcat [ arg "configure"
            , arg path
            , arg dir
            , dllArgs
            , withStaged Ghc
            , withStaged GhcPkg
            , stage0 ? bootPackageDbArgs
            , libraryArgs
            , with HsColour
            , configureArgs
            , stage0 ? packageConstraints
            , withStaged Gcc
            , notStage0 ? with Ld
            , with Ar
            , with Alex
            , with Happy ]

-- TODO: Isn't vanilla always built? If yes, some conditions are redundant.
libraryArgs :: Args
libraryArgs = do
    ways   <- getWays
    ghcInt <- lift $ ghcWithInterpreter
    append [ if vanilla `elem` ways
             then  "--enable-library-vanilla"
             else "--disable-library-vanilla"
           , if vanilla `elem` ways && ghcInt && not dynamicGhcPrograms
             then  "--enable-library-for-ghci"
             else "--disable-library-for-ghci"
           , if profiling `elem` ways
             then  "--enable-library-profiling"
             else "--disable-library-profiling"
           , if dynamic `elem` ways
             then  "--enable-shared"
             else "--disable-shared" ]

configureArgs :: Args
configureArgs = do
    stage <- getStage
    let conf key = appendSubD $ "--configure-option=" ++ key
        cFlags   = mconcat [ ccArgs
                           , remove ["-Werror"]
                           , argSettingList $ ConfCcArgs stage ]
        ldFlags  = ldArgs <> (argSettingList $ ConfGccLinkerArgs stage)
        cppFlags = cppArgs <> (argSettingList $ ConfCppArgs stage)
    mconcat
        [ conf "CFLAGS"   cFlags
        , conf "LDFLAGS"  ldFlags
        , conf "CPPFLAGS" cppFlags
        , appendSubD "--gcc-options" $ cFlags <> ldFlags
        , conf "--with-iconv-includes"  $ argSettingList IconvIncludeDirs
        , conf "--with-iconv-libraries" $ argSettingList IconvLibDirs
        , conf "--with-gmp-includes"    $ argSettingList GmpIncludeDirs
        , conf "--with-gmp-libraries"   $ argSettingList GmpLibDirs
        -- TODO: why TargetPlatformFull and not host?
        , crossCompiling ? (conf "--host" $ argSetting TargetPlatformFull)
        , conf "--with-cc" . argM . builderPath $ Gcc stage ]

bootPackageDbArgs :: Args
bootPackageDbArgs = do
    path <- getSetting GhcSourcePath
    arg $ "--package-db=" ++ path -/- "libraries/bootstrapping.conf"

-- This is a positional argument, hence:
-- * if it is empty, we need to emit one empty string argument;
-- * otherwise, we must collapse it into one space-separated string.
-- TODO: should be non-empty for compiler
dllArgs :: Args
dllArgs = arg ""

packageConstraints :: Args
packageConstraints = do
    pkgs <- getPackages
    constraints <- lift $ forM pkgs $ \pkg -> do
        let cabal  = pkgPath pkg -/- pkgCabal pkg
            prefix = dropExtension (pkgCabal pkg) ++ " == "
        need [cabal]
        content <- lines <$> liftIO (readFile cabal)
        let vs = filter (("ersion:" `isPrefixOf`) . drop 1) content
        case vs of
            [v] -> return $ prefix ++ dropWhile (not . isDigit) v
            _   -> redError $ "Cannot determine package version in '"
                            ++ cabal ++ "'."
    append $ concatMap (\c -> ["--constraint", c]) $ constraints

-- TODO: should be in a different file
-- TODO: put all validating options together in one file
ccArgs :: Args
ccArgs = validating ? do
    let gccGe46 = notP gccLt46
    mconcat [ arg "-Werror"
            , arg "-Wall"
            , gccIsClang ??
              ( arg "-Wno-unknown-pragmas" <>
                gccGe46 ? windowsHost ? arg "-Werror=unused-but-set-variable"
              , gccGe46 ? arg "-Wno-error=inline" )]

ldArgs :: Args
ldArgs = mempty

ghcIncludeDirs :: [FilePath]
ghcIncludeDirs = [ "includes", "includes/dist"
                 , "includes/dist-derivedconstants/header"
                 , "includes/dist-ghcconstants/header" ]

cppArgs :: Args
cppArgs = append . map ("-I" ++ ) $ ghcIncludeDirs

customPackageArgs :: Args
customPackageArgs = do
    stage   <- getStage
    rtsWays <- getRtsWays
    mconcat
        [ package integerGmp2 ?
          mconcat [ windowsHost ? builder GhcCabal ?
                    arg "--configure-option=--with-intree-gmp"
                  , appendCcArgs ["-Ilibraries/integer-gmp2/gmp"] ]

        , package base ?
          builder GhcCabal ? arg ("--flags=" ++ pkgName integerLibrary)

        , package ghcPrim ?
          builder GhcCabal ? arg "--flag=include-ghc-prim"

        , package compiler ?
          builder GhcCabal ?
          mconcat [ arg $ "--ghc-option=-DSTAGE=" ++ show (succ stage)
                  , arg "--disable-library-for-ghci"
                  , targetOs "openbsd" ? arg "--ld-options=-E"
                  , flag GhcUnregisterised ? arg "--ghc-option=-DNO_REGS"
                  , notP ghcWithSMP ? arg "--ghc-option=-DNOSMP"
                  , notP ghcWithSMP ? arg "--ghc-option=-optc-DNOSMP"
                  , (threaded `elem` rtsWays) ?
                    notStage0 ? arg "--ghc-option=-optc-DTHREADED_RTS"
                  , ghcWithNativeCodeGen ? arg "--flags=ncg"
                  , ghcWithInterpreter ? arg "--flags=ghci"<commit_msg>Fix custom settings of the compiler package.<commit_after>module Settings.GhcCabal (
    cabalArgs, bootPackageDbArgs, customPackageArgs
    ) where

import Way
import Util
import Stage
import Builder
import Package
import Switches
import Expression
import Oracles.Base
import Oracles.Flag
import Oracles.Setting
import Settings.User
import Settings.Ways
import Settings.Util
import Settings.Packages
import Data.List
import Control.Applicative

cabalArgs :: Args
cabalArgs = builder GhcCabal ? do
    path <- getPackagePath
    dir  <- getTargetDirectory
    mconcat [ arg "configure"
            , arg path
            , arg dir
            , dllArgs
            , withStaged Ghc
            , withStaged GhcPkg
            , stage0 ? bootPackageDbArgs
            , libraryArgs
            , with HsColour
            , configureArgs
            , stage0 ? packageConstraints
            , withStaged Gcc
            , notStage0 ? with Ld
            , with Ar
            , with Alex
            , with Happy ]

-- TODO: Isn't vanilla always built? If yes, some conditions are redundant.
libraryArgs :: Args
libraryArgs = do
    ways   <- getWays
    ghcInt <- lift $ ghcWithInterpreter
    append [ if vanilla `elem` ways
             then  "--enable-library-vanilla"
             else "--disable-library-vanilla"
           , if vanilla `elem` ways && ghcInt && not dynamicGhcPrograms
             then  "--enable-library-for-ghci"
             else "--disable-library-for-ghci"
           , if profiling `elem` ways
             then  "--enable-library-profiling"
             else "--disable-library-profiling"
           , if dynamic `elem` ways
             then  "--enable-shared"
             else "--disable-shared" ]

configureArgs :: Args
configureArgs = do
    stage <- getStage
    let conf key = appendSubD $ "--configure-option=" ++ key
        cFlags   = mconcat [ ccArgs
                           , remove ["-Werror"]
                           , argSettingList $ ConfCcArgs stage ]
        ldFlags  = ldArgs <> (argSettingList $ ConfGccLinkerArgs stage)
        cppFlags = cppArgs <> (argSettingList $ ConfCppArgs stage)
    mconcat
        [ conf "CFLAGS"   cFlags
        , conf "LDFLAGS"  ldFlags
        , conf "CPPFLAGS" cppFlags
        , appendSubD "--gcc-options" $ cFlags <> ldFlags
        , conf "--with-iconv-includes"  $ argSettingList IconvIncludeDirs
        , conf "--with-iconv-libraries" $ argSettingList IconvLibDirs
        , conf "--with-gmp-includes"    $ argSettingList GmpIncludeDirs
        , conf "--with-gmp-libraries"   $ argSettingList GmpLibDirs
        -- TODO: why TargetPlatformFull and not host?
        , crossCompiling ? (conf "--host" $ argSetting TargetPlatformFull)
        , conf "--with-cc" . argM . builderPath $ Gcc stage ]

bootPackageDbArgs :: Args
bootPackageDbArgs = do
    path <- getSetting GhcSourcePath
    arg $ "--package-db=" ++ path -/- "libraries/bootstrapping.conf"

-- This is a positional argument, hence:
-- * if it is empty, we need to emit one empty string argument;
-- * otherwise, we must collapse it into one space-separated string.
-- TODO: should be non-empty for compiler
dllArgs :: Args
dllArgs = arg ""

packageConstraints :: Args
packageConstraints = do
    pkgs <- getPackages
    constraints <- lift $ forM pkgs $ \pkg -> do
        let cabal  = pkgPath pkg -/- pkgCabal pkg
            prefix = dropExtension (pkgCabal pkg) ++ " == "
        need [cabal]
        content <- lines <$> liftIO (readFile cabal)
        let vs = filter (("ersion:" `isPrefixOf`) . drop 1) content
        case vs of
            [v] -> return $ prefix ++ dropWhile (not . isDigit) v
            _   -> redError $ "Cannot determine package version in '"
                            ++ cabal ++ "'."
    append $ concatMap (\c -> ["--constraint", c]) $ constraints

-- TODO: should be in a different file
-- TODO: put all validating options together in one file
ccArgs :: Args
ccArgs = validating ? do
    let gccGe46 = notP gccLt46
    mconcat [ arg "-Werror"
            , arg "-Wall"
            , gccIsClang ??
              ( arg "-Wno-unknown-pragmas" <>
                gccGe46 ? windowsHost ? arg "-Werror=unused-but-set-variable"
              , gccGe46 ? arg "-Wno-error=inline" )]

ldArgs :: Args
ldArgs = mempty

ghcIncludeDirs :: [FilePath]
ghcIncludeDirs = [ "includes", "includes/dist"
                 , "includes/dist-derivedconstants/header"
                 , "includes/dist-ghcconstants/header" ]

cppArgs :: Args
cppArgs = append . map ("-I" ++ ) $ ghcIncludeDirs

customPackageArgs :: Args
customPackageArgs = do
    stage   <- getStage
    rtsWays <- getRtsWays
    mconcat
        [ package integerGmp2 ?
          mconcat [ windowsHost ? builder GhcCabal ?
                    arg "--configure-option=--with-intree-gmp"
                  , appendCcArgs ["-Ilibraries/integer-gmp2/gmp"] ]

        , package base ?
          builder GhcCabal ? arg ("--flags=" ++ pkgName integerLibrary)

        , package ghcPrim ?
          builder GhcCabal ? arg "--flag=include-ghc-prim"

        , package compiler ?
          builder GhcCabal ?
          mconcat [ arg $ "--ghc-option=-DSTAGE=" ++ show (succ stage)
                  , arg $ "--flags=stage" ++ show (succ stage)
                  , arg "--disable-library-for-ghci"
                  , targetOs "openbsd" ? arg "--ld-options=-E"
                  , flag GhcUnregisterised ? arg "--ghc-option=-DNO_REGS"
                  , notP ghcWithSMP ? arg "--ghc-option=-DNOSMP"
                  , notP ghcWithSMP ? arg "--ghc-option=-optc-DNOSMP"
                  , (threaded `elem` rtsWays) ?
                    notStage0 ? arg "--ghc-option=-optc-DTHREADED_RTS"
                  , ghcWithNativeCodeGen ? arg "--flags=ncg"
                  , ghcWithInterpreter ?
                    notStage0 ? arg "--flags=ghci"
{'fraction_non_alphanumeric': 0.10477750948602967, 'fraction_numerical': 0.0026733356329768886, 'mean_word_length': 1.9419076610857433, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6167368', 'n_tokens_mistral': 3446, 'n_tokens_neox': 3334, 'n_words': 915}