diff --git a/compiler/GHC/Driver/Pipeline/Execute.hs b/compiler/GHC/Driver/Pipeline/Execute.hs index 338d5f26038cc59812455c248eb83b27fb70048b..8fc8e0d18ed380f52c4752b94604536d45aae64f 100644 --- a/compiler/GHC/Driver/Pipeline/Execute.hs +++ b/compiler/GHC/Driver/Pipeline/Execute.hs @@ -121,7 +121,7 @@ runPhase (T_CmmCpp pipe_env hsc_env input_fn) = do (hsc_dflags hsc_env) (hsc_unit_env hsc_env) (CppOpts - { sourceCodePreprocessor = SCPCpp + { sourceCodePreprocessor = SCPCmmCpp , cppLinePragmas = True }) input_fn output_fn diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs index 5c9a975598f31c12d5648d348e4e8dad9af9efae..b7bec8cff860f68c1ecca8a27a330fba42c2bb76 100644 --- a/compiler/GHC/Driver/Session.hs +++ b/compiler/GHC/Driver/Session.hs @@ -114,6 +114,8 @@ module GHC.Driver.Session ( sOpt_P_fingerprint, sOpt_JSP, sOpt_JSP_fingerprint, + sOpt_CmmP, + sOpt_CmmP_fingerprint, sOpt_F, sOpt_c, sOpt_cxx, @@ -136,11 +138,11 @@ module GHC.Driver.Session ( ghcUsagePath, ghciUsagePath, topDir, versionedAppDir, versionedFilePath, extraGccViaCFlags, globalPackageDatabasePath, - pgm_L, pgm_P, pgm_JSP, pgm_F, pgm_c, pgm_cxx, pgm_cpp, pgm_a, pgm_l, + pgm_L, pgm_P, pgm_JSP, pgm_CmmP, pgm_F, pgm_c, pgm_cxx, pgm_cpp, pgm_a, pgm_l, pgm_lm, pgm_windres, pgm_ar, pgm_ranlib, pgm_lo, pgm_lc, pgm_las, pgm_i, - opt_L, opt_P, opt_JSP, opt_F, opt_c, opt_cxx, opt_a, opt_l, opt_lm, opt_i, - opt_P_signature, opt_JSP_signature, + opt_L, opt_P, opt_JSP, opt_CmmP, opt_F, opt_c, opt_cxx, opt_a, opt_l, opt_lm, opt_i, + opt_P_signature, opt_JSP_signature, opt_CmmP_signature, opt_windres, opt_lo, opt_lc, opt_las, updatePlatformConstants, @@ -401,6 +403,8 @@ pgm_P :: DynFlags -> (String,[Option]) pgm_P dflags = toolSettings_pgm_P $ toolSettings dflags pgm_JSP :: DynFlags -> (String,[Option]) pgm_JSP dflags = toolSettings_pgm_JSP $ toolSettings dflags +pgm_CmmP :: DynFlags -> (String,[Option]) +pgm_CmmP dflags = toolSettings_pgm_CmmP $ toolSettings dflags pgm_F :: DynFlags -> String pgm_F dflags = toolSettings_pgm_F $ toolSettings dflags pgm_c :: DynFlags -> String @@ -437,6 +441,8 @@ opt_P dflags = concatMap (wayOptP (targetPlatform dflags)) (ways dflags) opt_JSP :: DynFlags -> [String] opt_JSP dflags = concatMap (wayOptP (targetPlatform dflags)) (ways dflags) ++ toolSettings_opt_JSP (toolSettings dflags) +opt_CmmP :: DynFlags -> [String] +opt_CmmP dflags = toolSettings_opt_CmmP $ toolSettings dflags -- This function packages everything that's needed to fingerprint opt_P -- flags. See Note [Repeated -optP hashing]. @@ -452,6 +458,10 @@ opt_JSP_signature dflags = ( concatMap (wayOptP (targetPlatform dflags)) (ways dflags) , toolSettings_opt_JSP_fingerprint $ toolSettings dflags ) +-- This function packages everything that's needed to fingerprint opt_CmmP +-- flags. See Note [Repeated -optP hashing]. +opt_CmmP_signature :: DynFlags -> Fingerprint +opt_CmmP_signature = toolSettings_opt_CmmP_fingerprint . toolSettings opt_F :: DynFlags -> [String] opt_F dflags= toolSettings_opt_F $ toolSettings dflags @@ -600,7 +610,8 @@ setObjectDir, setHiDir, setHieDir, setStubDir, setDumpDir, setOutputDir, setDynObjectSuf, setDynHiSuf, setDylibInstallName, setObjectSuf, setHiSuf, setHieSuf, setHcSuf, parseDynLibLoaderMode, - setPgmP, setPgmJSP, addOptl, addOptc, addOptcxx, addOptP, addOptJSP, + setPgmP, setPgmJSP, setPgmCmmP, addOptl, addOptc, addOptcxx, addOptP, + addOptJSP, addOptCmmP, addCmdlineFramework, addHaddockOpts, addGhciScript, setInteractivePrint :: String -> DynFlags -> DynFlags @@ -694,6 +705,10 @@ setPgmP f = alterToolSettings (\s -> s { toolSettings_pgm_P = (pgm, map Opti -- Config.hs should really use Option. setPgmJSP f = alterToolSettings (\s -> s { toolSettings_pgm_JSP = (pgm, map Option args)}) where (pgm:args) = words f +-- XXX HACK: Prelude> words "'does not' work" ===> ["'does","not'","work"] +-- Config.hs should really use Option. +setPgmCmmP f = alterToolSettings (\s -> s { toolSettings_pgm_CmmP = (pgm, map Option args)}) + where (pgm:args) = words f addOptl f = alterToolSettings (\s -> s { toolSettings_opt_l = f : toolSettings_opt_l s}) addOptc f = alterToolSettings (\s -> s { toolSettings_opt_c = f : toolSettings_opt_c s}) addOptcxx f = alterToolSettings (\s -> s { toolSettings_opt_cxx = f : toolSettings_opt_cxx s}) @@ -707,6 +722,10 @@ addOptJSP f = alterToolSettings $ \s -> s , toolSettings_opt_JSP_fingerprint = fingerprintStrings (f : toolSettings_opt_JSP s) } -- See Note [Repeated -optP hashing] +addOptCmmP f = alterToolSettings $ \s -> s + { toolSettings_opt_CmmP = f : toolSettings_opt_CmmP s + , toolSettings_opt_CmmP_fingerprint = fingerprintStrings (f : toolSettings_opt_CmmP s) + } setDepMakefile :: FilePath -> DynFlags -> DynFlags setDepMakefile f d = d { depMakefile = f } @@ -1099,6 +1118,8 @@ dynamic_flags_deps = [ (hasArg setPgmP) , make_ord_flag defFlag "pgmJSP" (hasArg setPgmJSP) + , make_ord_flag defFlag "pgmCmmP" + (hasArg setPgmCmmP) , make_ord_flag defFlag "pgmF" $ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_F = f } , make_ord_flag defFlag "pgmc" @@ -1155,6 +1176,8 @@ dynamic_flags_deps = [ (hasArg addOptP) , make_ord_flag defFlag "optJSP" (hasArg addOptJSP) + , make_ord_flag defFlag "optCmmP" + (hasArg addOptCmmP) , make_ord_flag defFlag "optF" $ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_opt_F = f : toolSettings_opt_F s } , make_ord_flag defFlag "optc" diff --git a/compiler/GHC/Iface/Recomp/Flags.hs b/compiler/GHC/Iface/Recomp/Flags.hs index a8493e069a20b7452552823f3389742d6c083b7c..fef5e617521c77dc4e44af1ef985f62ee69de3a1 100644 --- a/compiler/GHC/Iface/Recomp/Flags.hs +++ b/compiler/GHC/Iface/Recomp/Flags.hs @@ -64,6 +64,12 @@ fingerprintDynFlags hsc_env this_mod nameio = , opt_JSP_signature dflags) -- See Note [Repeated -optP hashing] + -- -I, -D and -U flags affect C-- CPP Preprocessor + cmm = ( map normalise $ flattenIncludes includePathsMinusImplicit + -- normalise: eliminate spurious differences due to "./foo" vs "foo" + , picPOpts dflags + , opt_CmmP_signature dflags) + -- Note [path flags and recompilation] paths = [ hcSuf ] @@ -77,7 +83,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- Other flags which affect code generation codegen = map (`gopt` dflags) (EnumSet.toList codeGenFlags) - flags = ((mainis, safeHs, lang, cpp, js), (paths, prof, ticky, codegen, debugLevel, callerCcFilters)) + flags = ((mainis, safeHs, lang, cpp, js, cmm), (paths, prof, ticky, codegen, debugLevel, callerCcFilters)) in -- pprTrace "flags" (ppr flags) $ computeFingerprint nameio flags diff --git a/compiler/GHC/Settings.hs b/compiler/GHC/Settings.hs index 49d653c1bc3bce15873c12133cdfd813477f75a3..61d8b797acfad9fb0b0fa83f434d7f8b46cf6d88 100644 --- a/compiler/GHC/Settings.hs +++ b/compiler/GHC/Settings.hs @@ -27,6 +27,7 @@ module GHC.Settings , sPgm_L , sPgm_P , sPgm_JSP + , sPgm_CmmP , sPgm_F , sPgm_c , sPgm_cxx @@ -48,6 +49,8 @@ module GHC.Settings , sOpt_P_fingerprint , sOpt_JSP , sOpt_JSP_fingerprint + , sOpt_CmmP + , sOpt_CmmP_fingerprint , sOpt_F , sOpt_c , sOpt_cxx @@ -95,6 +98,7 @@ data ToolSettings = ToolSettings , toolSettings_ccSupportsNoPie :: Bool , toolSettings_useInplaceMinGW :: Bool , toolSettings_arSupportsDashL :: Bool + , toolSettings_cmmCppSupportsG0 :: Bool -- commands for particular phases , toolSettings_pgm_L :: String @@ -102,6 +106,8 @@ data ToolSettings = ToolSettings toolSettings_pgm_P :: (String, [Option]) , -- | The JavaScript C preprocessor and default options (not added by -optP) toolSettings_pgm_JSP :: (String, [Option]) + , -- | The C-- C Preprocessor and default options (not added by -optP) + toolSettings_pgm_CmmP :: (String, [Option]) , toolSettings_pgm_F :: String , toolSettings_pgm_c :: String , toolSettings_pgm_cxx :: String @@ -130,12 +136,16 @@ data ToolSettings = ToolSettings , toolSettings_opt_L :: [String] , toolSettings_opt_P :: [String] , toolSettings_opt_JSP :: [String] + , toolSettings_opt_CmmP :: [String] , -- | cached Fingerprint of sOpt_P -- See Note [Repeated -optP hashing] toolSettings_opt_P_fingerprint :: Fingerprint , -- | cached Fingerprint of sOpt_JSP -- See Note [Repeated -optP hashing] toolSettings_opt_JSP_fingerprint :: Fingerprint + , -- | cached Fingerprint of sOpt_CmmP + -- See Note [Repeated -optP hashing] + toolSettings_opt_CmmP_fingerprint :: Fingerprint , toolSettings_opt_F :: [String] , toolSettings_opt_c :: [String] , toolSettings_opt_cxx :: [String] @@ -216,6 +226,8 @@ sPgm_P :: Settings -> (String, [Option]) sPgm_P = toolSettings_pgm_P . sToolSettings sPgm_JSP :: Settings -> (String, [Option]) sPgm_JSP = toolSettings_pgm_JSP . sToolSettings +sPgm_CmmP :: Settings -> (String, [Option]) +sPgm_CmmP = toolSettings_pgm_CmmP . sToolSettings sPgm_F :: Settings -> String sPgm_F = toolSettings_pgm_F . sToolSettings sPgm_c :: Settings -> String @@ -258,6 +270,10 @@ sOpt_JSP :: Settings -> [String] sOpt_JSP = toolSettings_opt_JSP . sToolSettings sOpt_JSP_fingerprint :: Settings -> Fingerprint sOpt_JSP_fingerprint = toolSettings_opt_JSP_fingerprint . sToolSettings +sOpt_CmmP :: Settings -> [String] +sOpt_CmmP = toolSettings_opt_CmmP . sToolSettings +sOpt_CmmP_fingerprint :: Settings -> Fingerprint +sOpt_CmmP_fingerprint = toolSettings_opt_CmmP_fingerprint . sToolSettings sOpt_F :: Settings -> [String] sOpt_F = toolSettings_opt_F . sToolSettings sOpt_c :: Settings -> [String] diff --git a/compiler/GHC/Settings/IO.hs b/compiler/GHC/Settings/IO.hs index 06d553245ad100f878da6a9b3ac822fe1709b6b9..a1c883db362f27e25c1ca1516a6e905189fc5f2b 100644 --- a/compiler/GHC/Settings/IO.hs +++ b/compiler/GHC/Settings/IO.hs @@ -87,12 +87,15 @@ initSettings top_dir = do cc_args_str <- getToolSetting "C compiler flags" cxx_args_str <- getToolSetting "C++ compiler flags" gccSupportsNoPie <- getBooleanSetting "C compiler supports -no-pie" + cmmCppSupportsG0 <- getBooleanSetting "C-- CPP supports -g0" cpp_prog <- getToolSetting "CPP command" cpp_args_str <- getToolSetting "CPP flags" hs_cpp_prog <- getToolSetting "Haskell CPP command" hs_cpp_args_str <- getToolSetting "Haskell CPP flags" js_cpp_prog <- getToolSetting "JavaScript CPP command" js_cpp_args_str <- getToolSetting "JavaScript CPP flags" + cmmCpp_prog <- getToolSetting "C-- CPP command" + cmmCpp_args_str <- getToolSetting "C-- CPP flags" platform <- either pgmError pure $ getTargetPlatform settingsFile mySettings @@ -102,6 +105,7 @@ initSettings top_dir = do cpp_args = map Option (unescapeArgs cpp_args_str) hs_cpp_args = map Option (unescapeArgs hs_cpp_args_str) js_cpp_args = map Option (unescapeArgs js_cpp_args_str) + cmmCpp_args = map Option (unescapeArgs cmmCpp_args_str) cc_args = unescapeArgs cc_args_str ++ unreg_cc_args cxx_args = unescapeArgs cxx_args_str @@ -192,10 +196,12 @@ initSettings top_dir = do , toolSettings_ccSupportsNoPie = gccSupportsNoPie , toolSettings_useInplaceMinGW = useInplaceMinGW , toolSettings_arSupportsDashL = arSupportsDashL + , toolSettings_cmmCppSupportsG0 = cmmCppSupportsG0 , toolSettings_pgm_L = unlit_path , toolSettings_pgm_P = (hs_cpp_prog, hs_cpp_args) , toolSettings_pgm_JSP = (js_cpp_prog, js_cpp_args) + , toolSettings_pgm_CmmP = (cmmCpp_prog, cmmCpp_args) , toolSettings_pgm_F = "" , toolSettings_pgm_c = cc_prog , toolSettings_pgm_cxx = cxx_prog @@ -215,8 +221,10 @@ initSettings top_dir = do , toolSettings_opt_L = [] , toolSettings_opt_P = [] , toolSettings_opt_JSP = [] + , toolSettings_opt_CmmP = [] , toolSettings_opt_P_fingerprint = fingerprint0 , toolSettings_opt_JSP_fingerprint = fingerprint0 + , toolSettings_opt_CmmP_fingerprint = fingerprint0 , toolSettings_opt_F = [] , toolSettings_opt_c = cc_args , toolSettings_opt_cxx = cxx_args diff --git a/compiler/GHC/SysTools/Cpp.hs b/compiler/GHC/SysTools/Cpp.hs index 2a7d74f46e22b9ccdddbc570cc783ee91f65242e..6129ce961370a29982b9a59e893a8d4b1ace2b21 100644 --- a/compiler/GHC/SysTools/Cpp.hs +++ b/compiler/GHC/SysTools/Cpp.hs @@ -48,16 +48,18 @@ data CppOpts = CppOpts {- Note [Preprocessing invocations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We must consider three distinct preprocessors when preprocessing Haskell. +We must consider four distinct preprocessors when preprocessing Haskell. These are: (1) The Haskell C preprocessor (HsCpp), which preprocesses Haskell files that make use of the CPP language extension -(2) The C preprocessor (Cpp), which is used to preprocess C and Cmm files +(2) The C preprocessor (Cpp), which is used to preprocess C files (3) The JavaScript preprocessor (JsCpp), which preprocesses JavaScript files +(4) The C-- preprocessor (CmmCpp), which preprocesses C-- files + These preprocessors are indeed different. Despite often sharing the same underlying program (the C compiler), the set of flags passed determines the behaviour of the preprocessor, and Cpp and HsCpp behave differently. @@ -86,6 +88,17 @@ minifying software (for example, Google Closure Compiler) uses JSDoc information to apply more strict rules to code reduction which results in better but more dangerous minification. JSDoc comments are usually used to instruct minifiers where dangerous optimizations could be applied. + +The fourth, the C-- preprocessor, is needed as modern compilers emit defines +for debug info generation when preprocessing. The C-- preprocessor avoids this +by suppressing debug info generation. The C-- preprocessor also inherits flags +passed to the C compiler. This is done for compatibility. Following those, +the C-- compiler receives -g0, if it was detected as supported, and flags +passed via -optCmmP specifically for the C-- preprocessor. The combined +command line looks like: + + $pgmCmmP $optCs_without_g3s $g0_if_supported $optCmmP + -} -- | Run either the Haskell preprocessor, JavaScript preprocessor diff --git a/compiler/GHC/SysTools/Tasks.hs b/compiler/GHC/SysTools/Tasks.hs index c80d4ac44308812c0d527c75fb4f07e139c37c32..2663c44c2de1f9055f1ed56a01f1bb25361ad6f6 100644 --- a/compiler/GHC/SysTools/Tasks.hs +++ b/compiler/GHC/SysTools/Tasks.hs @@ -115,6 +115,8 @@ data SourceCodePreprocessor -- ^ Use the Haskell C preprocessor (don't remove C comments, don't break on names including single quotes) | SCPJsCpp -- ^ Use the JavaScript preprocessor (don't remove jsdoc and multiline comments) + | SCPCmmCpp + -- ^ Use the C-- preprocessor (don't emit debug information) deriving (Eq) -- | Run source code preprocessor. @@ -140,11 +142,27 @@ runSourceCodePreprocessor logger tmpfs dflags preprocessor args = runSomething readable_name p all_args mb_env where + toolSettings' = toolSettings dflags + cmmG0 = ["-g0" | toolSettings_cmmCppSupportsG0 toolSettings'] + -- GCC <=10 (pre commit r11-5596-g934a54180541d2) implied -dD for debug + -- flags by the spec snippet %{g3|ggdb3|gstabs3|gxcoff3|gvms3:-dD}. This + -- means that a g0 will not override a previously-specified -g3 causing + -- debug info emission (see https://gcc.gnu.org/PR97989). We're filtering + -- -optc here, rather than the combined command line, in order to avoid an + -- issue where a user has to, for some reason, override our decision. If + -- they see the need to do that, they can pass -optCmmP. + g3Flags = ["-g3", "-ggdb3", "-gstabs3", "-gxcoff3", "-gvms3"] + optCFiltered = filter (`notElem` g3Flags) . opt_c + -- In the wild (and GHC), there is lots of code assuming that -optc gets + -- passed to the C-- preprocessor too. Note that the arguments are + -- reversed by getOpts. + cAndCmmOpt dflags = opt_CmmP dflags ++ cmmG0 ++ optCFiltered dflags (logger_name, pgm_getter, opt_getter, readable_name) = case preprocessor of SCPCpp -> ("cpp", pgm_cpp, opt_c, "C pre-processor") SCPHsCpp -> ("hs-cpp", pgm_P, opt_P, "Haskell C pre-processor") SCPJsCpp -> ("js-cpp", pgm_JSP, opt_JSP, "JavaScript C pre-processor") + SCPCmmCpp -> ("cmm-cpp", pgm_CmmP, cAndCmmOpt, "C-- C pre-processor") runSomethingResponseFileCpp = runSomethingResponseFile logger tmpfs (tmpDir dflags) cc_filter @@ -156,6 +174,7 @@ runSourceCodePreprocessor logger tmpfs dflags preprocessor args = SCPCpp -> runSomethingResponseFileCpp SCPHsCpp -> runSomethingFilteredOther SCPJsCpp -> runSomethingFilteredOther + SCPCmmCpp -> runSomethingResponseFileCpp runPp :: Logger -> DynFlags -> [Option] -> IO () runPp logger dflags args = traceSystoolCommand logger "pp" $ do diff --git a/configure.ac b/configure.ac index 5f1f827a3ab27ea4e23b487bbdd439e9c793f9ac..5429d5c898ec31fbafbe82578b0ed862f5887a61 100644 --- a/configure.ac +++ b/configure.ac @@ -416,6 +416,16 @@ FP_JSCPP_CMD_WITH_ARGS(JavaScriptCPPCmd, JavaScriptCPPArgs) AC_SUBST([JavaScriptCPPCmd]) AC_SUBST([JavaScriptCPPArgs]) +# --with-cmm-cpp/--with-cmm-cpp-flags +FP_CMM_CPP_CMD_WITH_ARGS([$CC_STAGE0], [CmmCPPCmd_STAGE0], [CmmCPPArgs_STAGE0], [CmmCPPSupportsG0_STAGE0]) +AC_SUBST([CmmCPPCmd_STAGE0]) +AC_SUBST([CmmCPPArgs_STAGE0]) +AC_SUBST([CmmCPPSupportsG0_STAGE0]) +FP_CMM_CPP_CMD_WITH_ARGS([$CC], [CmmCPPCmd], [CmmCPPArgs], [CmmCPPSupportsG0]) +AC_SUBST([CmmCPPCmd]) +AC_SUBST([CmmCPPArgs]) +AC_SUBST([CmmCPPSupportsG0]) + FP_SET_CFLAGS_C99([CC],[CFLAGS],[CPPFLAGS]) FP_SET_CFLAGS_C99([CC_STAGE0],[CONF_CC_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0]) FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1]) @@ -999,6 +1009,9 @@ echo "\ hs-cpp-flags : $HaskellCPPArgs js-cpp : $JavaScriptCPPCmd js-cpp-flags : $JavaScriptCPPArgs + cmmcpp : $CmmCPPCmd + cmmcpp-flags : $CmmCPPArgs + cmmcpp-g0 : $CmmCPPSupportsG0 ar : $ArCmd nm : $NmCmd objdump : $ObjdumpCmd diff --git a/distrib/configure.ac.in b/distrib/configure.ac.in index 39609940ab3f1027447bb8eb1dd074c2b410763b..574ea3391dec49383d1ab3b98823cf58a95a956b 100644 --- a/distrib/configure.ac.in +++ b/distrib/configure.ac.in @@ -135,6 +135,12 @@ FP_HSCPP_CMD_WITH_ARGS(HaskellCPPCmd, HaskellCPPArgs) AC_SUBST([HaskellCPPCmd]) AC_SUBST([HaskellCPPArgs]) +# --with-cmm-cpp/--with-cmm-cpp-flags +FP_CMM_CPP_CMD_WITH_ARGS([$CC], [CmmCPPCmd], [CmmCPPArgs], [CmmCPPSupportsG0]) +AC_SUBST([CmmCPPCmd]) +AC_SUBST([CmmCPPArgs]) +AC_SUBST([CmmCPPSupportsG0]) + FP_SET_CFLAGS_C99([CC],[CFLAGS],[CPPFLAGS]) dnl FP_SET_CFLAGS_C99([CC_STAGE0],[CONF_CC_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0]) FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1]) diff --git a/docs/users_guide/phases.rst b/docs/users_guide/phases.rst index a4a443537f954a97ac476751503c999f43b16e34..623f957dfe2348d5d68f143c108341621059656c 100644 --- a/docs/users_guide/phases.rst +++ b/docs/users_guide/phases.rst @@ -38,6 +38,13 @@ given compilation phase: Use ⟨cmd⟩ as the JavaScript C pre-processor (only for javascript-backend). +.. ghc-flag:: -pgmCmmP ⟨cmd⟩ + :shortdesc: Use ⟨cmd⟩ as the C-- C pre-processor + :type: dynamic + :category: phase-programs + + Use ⟨cmd⟩ as the C-- C pre-processor. + .. ghc-flag:: -pgmc ⟨cmd⟩ :shortdesc: Use ⟨cmd⟩ as the C compiler :type: dynamic @@ -179,6 +186,17 @@ the following flags: Pass ⟨option⟩ to JavaScript C pre-processor (only for javascript-backend). +.. ghc-flag:: -optCmmP ⟨option⟩ + :shortdesc: pass ⟨option⟩ to the C-- C pre-processor. + :type: dynamic + :category: phase-options + + Pass ⟨option⟩ to the C-- C pre-processor. + + The C-- C pre-processor also receives C compiler flags. Those flags will + come _before_ the flags added by this option. As a result, the net effect + of the following pair of flags is zero: :code:`-optCmmP-UFOO -optc-DFOO`. + .. ghc-flag:: -optF ⟨option⟩ :shortdesc: pass ⟨option⟩ to the custom pre-processor :type: dynamic @@ -192,7 +210,7 @@ the following flags: :type: dynamic :category: phase-options - Pass ⟨option⟩ to the C compiler. + Pass ⟨option⟩ to the C compiler and, for compatibility, C-- pre-processor. .. ghc-flag:: -pgmc-supports-no-pie :shortdesc: *(deprecated)* diff --git a/hadrian/bindist/Makefile b/hadrian/bindist/Makefile index 9701b438d471725d84863a407ffbb354680fbcf3..5983855a16dc89c3f996a0577395b7e8fb9cfea6 100644 --- a/hadrian/bindist/Makefile +++ b/hadrian/bindist/Makefile @@ -96,6 +96,9 @@ lib/settings : config.mk @echo ',("Haskell CPP flags", "$(SettingsHaskellCPPFlags)")' >> $@ @echo ',("JavaScript CPP command", "$(SettingsJavaScriptCPPCommand)")' >> $@ @echo ',("JavaScript CPP flags", "$(SettingsJavaScriptCPPFlags)")' >> $@ + @echo ',("C-- CPP command", "$(SettingsCmmCPPCommand)")' >> $@ + @echo ',("C-- CPP flags", "$(SettingsCmmCPPFlags)")' >> $@ + @echo ',("C-- CPP supports -g0", "$(SettingsCmmCPPSupportsG0)")' >> $@ @echo ',("ld supports compact unwind", "$(LdHasNoCompactUnwind)")' >> $@ @echo ',("ld supports filelist", "$(LdHasFilelist)")' >> $@ @echo ',("ld supports single module", "$(LdHasSingleModule)")' >> $@ diff --git a/hadrian/bindist/config.mk.in b/hadrian/bindist/config.mk.in index 30489959fc5d54a631b3b9cb97c8b8684d7d8f90..f7779791f2c4f3f1b47f412559d2d50e785caf96 100644 --- a/hadrian/bindist/config.mk.in +++ b/hadrian/bindist/config.mk.in @@ -206,6 +206,9 @@ SettingsHaskellCPPCommand = @SettingsHaskellCPPCommand@ SettingsHaskellCPPFlags = @SettingsHaskellCPPFlags@ SettingsJavaScriptCPPCommand = @SettingsJavaScriptCPPCommand@ SettingsJavaScriptCPPFlags = @SettingsJavaScriptCPPFlags@ +SettingsCmmCPPCommand = @SettingsCmmCPPCommand@ +SettingsCmmCPPFlags = @SettingsCmmCPPFlags@ +SettingsCmmCPPSupportsG0 = @SettingsCmmCPPSupportsG0@ SettingsCCompilerFlags = @SettingsCCompilerFlags@ SettingsCxxCompilerFlags = @SettingsCxxCompilerFlags@ SettingsCCompilerLinkFlags = @SettingsCCompilerLinkFlags@ diff --git a/hadrian/cfg/default.host.target.in b/hadrian/cfg/default.host.target.in index fb97d246fe9f9bb445800f9420595217f2f67a5c..272521f1ac9e8da757f40b2a01f6c305c3d3ab6b 100644 --- a/hadrian/cfg/default.host.target.in +++ b/hadrian/cfg/default.host.target.in @@ -17,6 +17,7 @@ Target , tgtCPreprocessor = Cpp {cppProgram = Program {prgPath = "@CPPCmd_STAGE0@", prgFlags = @CONF_CPP_OPTS_STAGE0List@}} , tgtHsCPreprocessor = HsCpp {hsCppProgram = Program {prgPath = "@CC_STAGE0@", prgFlags = @HaskellCPPArgsList@}} , tgtJsCPreprocessor = Nothing +, tgtCmmCPreprocessor = CmmCpp {cmmCppProgram = Program {prgPath = "@CmmCPPCmd_STAGE0@", prgFlags = @CmmCPPArgs_STAGE0List@}, cmmCppSupportsG0 = @CmmCPPSupportsG0_STAGE0@} , tgtCCompilerLink = CcLink { ccLinkProgram = Program {prgPath = "@CC_STAGE0@", prgFlags = @CONF_GCC_LINKER_OPTS_STAGE0List@} , ccLinkSupportsNoPie = False diff --git a/hadrian/cfg/default.target.in b/hadrian/cfg/default.target.in index 5d48e509a8470a2a2257bcf85c92090bebd2336a..a3f28dba52a2cbf7e642e7bae5373f9942c6772c 100644 --- a/hadrian/cfg/default.target.in +++ b/hadrian/cfg/default.target.in @@ -17,6 +17,7 @@ Target , tgtCPreprocessor = Cpp {cppProgram = Program {prgPath = "@CPPCmd@", prgFlags = @CONF_CPP_OPTS_STAGE2List@}} , tgtHsCPreprocessor = HsCpp {hsCppProgram = Program {prgPath = "@HaskellCPPCmd@", prgFlags = @HaskellCPPArgsList@}} , tgtJsCPreprocessor = Just (JsCpp {jsCppProgram = Program {prgPath = "@JavaScriptCPPCmd@", prgFlags = @JavaScriptCPPArgsList@}}) +, tgtCmmCPreprocessor = CmmCpp {cmmCppProgram = Program {prgPath = "@CmmCPPCmd@", prgFlags = @CmmCPPArgsList@}, cmmCppSupportsG0 = @CmmCPPSupportsG0@} , tgtCCompilerLink = CcLink { ccLinkProgram = Program {prgPath = "@CC@", prgFlags = @CONF_GCC_LINKER_OPTS_STAGE2List@} , ccLinkSupportsNoPie = @CONF_GCC_SUPPORTS_NO_PIEBool@ diff --git a/hadrian/src/Rules/Generate.hs b/hadrian/src/Rules/Generate.hs index c99a9066f1c418bbf067afaaec5a4d05d8729c34..6e1312e12f58bc4f1249cd86922a9f8de19776f6 100644 --- a/hadrian/src/Rules/Generate.hs +++ b/hadrian/src/Rules/Generate.hs @@ -464,6 +464,9 @@ generateSettings settingsFile = do , ("Haskell CPP flags", queryTarget hsCppFlags) , ("JavaScript CPP command", queryTarget jsCppPath) , ("JavaScript CPP flags", queryTarget jsCppFlags) + , ("C-- CPP command", queryTarget cmmCppPath) + , ("C-- CPP flags", queryTarget cmmCppFlags) + , ("C-- CPP supports -g0", queryTarget cmmCppSupportsG0') , ("ld supports compact unwind", queryTarget linkSupportsCompactUnwind) , ("ld supports filelist", queryTarget linkSupportsFilelist) , ("ld supports single module", queryTarget linkSupportsSingleModule) @@ -526,6 +529,9 @@ generateSettings settingsFile = do hsCppFlags = escapeArgs . prgFlags . hsCppProgram . tgtHsCPreprocessor jsCppPath = maybe "" (prgPath . jsCppProgram) . tgtJsCPreprocessor jsCppFlags = maybe "" (escapeArgs . prgFlags . jsCppProgram) . tgtJsCPreprocessor + cmmCppPath = prgPath . cmmCppProgram . tgtCmmCPreprocessor + cmmCppFlags = escapeArgs . prgFlags . cmmCppProgram . tgtCmmCPreprocessor + cmmCppSupportsG0' = yesNo . cmmCppSupportsG0 . tgtCmmCPreprocessor mergeObjsPath = maybe "" (prgPath . mergeObjsProgram) . tgtMergeObjs mergeObjsFlags = maybe "" (escapeArgs . prgFlags . mergeObjsProgram) . tgtMergeObjs linkSupportsSingleModule = yesNo . ccLinkSupportsSingleModule . tgtCCompilerLink diff --git a/m4/fp_cmm_cpp_cmd_with_args.m4 b/m4/fp_cmm_cpp_cmd_with_args.m4 new file mode 100644 index 0000000000000000000000000000000000000000..0a5a6b572e7725a1b4941a852f8d026fa0ae637b --- /dev/null +++ b/m4/fp_cmm_cpp_cmd_with_args.m4 @@ -0,0 +1,67 @@ +# FP_CMM_CPP_CMD_WITH_ARGS() +# -------------------------- +# sets CMM_CPP command and its arguments +# +# $1 = the variable to set to Cmm CPP command +# $2 = the variable to set to Cmm CPP command arguments + +AC_DEFUN([FP_CMM_CPP_CMD_WITH_ARGS],[ + +AC_ARG_WITH(cmm-cpp, +[AS_HELP_STRING([--with-cmm-cpp=ARG], + [Path to the Cmm (C) preprocessor [default=autodetect]. + If you set --with-cmm-cpp=CC, ensure -E is included in --with-cmm-cpp-flags])], +[ + if test "$HostOS" = "mingw32" + then + AC_MSG_WARN([Request to use $withval will be ignored]) + else + CMM_CPP_CMD="$withval" + fi +], +[ + # We can't use the CPP var here, since CPP_CMD is expected to be a single + # command (no flags), and autoconf defines CPP as "/usr/bin/gcc -E". + # So we use CC with -E by default + CMM_CPP_CMD="$1" +] +) + +AC_ARG_WITH(cmm-cpp-flags, +[AS_HELP_STRING([--with-cmm-cpp-flags=ARG], + [Flags to the Cmm (C) preprocessor [default=autodetect]])], +[ + if test "$HostOS" = "mingw32" + then + AC_MSG_WARN([Request to use $withval will be ignored]) + else + # Use whatever flags were manually set, ignoring previously configured + # flags; and add CPP_ARGS (which will be -E if CPP_CMD was not specified) + CMM_CPP_ARGS="$withval" + fi +], +[ + CMM_CPP_ARGS="-E" +]) + +AC_MSG_CHECKING([whether the C-- preprocessor "$CMM_CPP_CMD" $CMM_CPP_ARGS supports -g0]) +: > conftest.c +if "$CMM_CPP_CMD" $CMM_CPP_ARGS conftest.c -g0 >/dev/null 2>&1; then + $4=True + AC_MSG_RESULT([yes]) +else + $4=False + AC_MSG_RESULT([no]) +fi +rm -f conftest.c + + +$2="$CMM_CPP_CMD" +$3="$$3 $CMM_CPP_ARGS" + +# Clear CMM_CPP_CMD and CMM_CPP_ARGS +unset CMM_CPP_CMD +unset CMM_CPP_ARGS + +]) + diff --git a/m4/fp_settings.m4 b/m4/fp_settings.m4 index 75cae2603d5cdccdae437c7815900620818fc006..05c30c18bb24319df6341b1fbe5cd69c6ed0c82e 100644 --- a/m4/fp_settings.m4 +++ b/m4/fp_settings.m4 @@ -64,12 +64,21 @@ AC_DEFUN([FP_SETTINGS], SettingsHaskellCPPFlags="$HaskellCPPArgs" SettingsJavaScriptCPPCommand="$JavaScriptCPPCmd" SettingsJavaScriptCPPFlags="$JavaScriptCPPArgs" + SettingsCmmCPPCommand="$CmmCPPCmd" + SettingsCmmCPPFlags="$CmmCPPArgs" SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2" SettingsArCommand="$ArCmd" SettingsRanlibCommand="$RanlibCmd" SettingsMergeObjectsCommand="$MergeObjsCmd" SettingsMergeObjectsFlags="$MergeObjsArgs" + AS_CASE( + ["$CmmCPPSupportsG0"], + [True], [SettingsCmmCPPSupportsG0=YES], + [False], [SettingsCmmCPPSupportsG0=NO], + [AC_MSG_ERROR(Unknown CPPSupportsG0 value $CmmCPPSupportsG0)] + ) + if test -z "$WindresCmd"; then SettingsWindresCommand="/bin/false" else @@ -81,6 +90,7 @@ AC_DEFUN([FP_SETTINGS], # executable names, not paths. SettingsCCompilerCommand="$(basename $SettingsCCompilerCommand)" SettingsHaskellCPPCommand="$(basename $SettingsHaskellCPPCommand)" + SettingsCmmCPPCommand="$(basename $SettingsCmmCPPCommand)" SettingsJavaScriptCPPCommand="$(basename $SettingsJavaScriptCPPCommand)" SettingsLdCommand="$(basename $SettingsLdCommand)" SettingsMergeObjectsCommand="$(basename $SettingsMergeObjectsCommand)" @@ -101,6 +111,8 @@ AC_DEFUN([FP_SETTINGS], SUBST_TOOLDIR([SettingsCPPFlags]) SUBST_TOOLDIR([SettingsHaskellCPPCommand]) SUBST_TOOLDIR([SettingsHaskellCPPFlags]) + SUBST_TOOLDIR([SettingsCmmCPPCommand]) + SUBST_TOOLDIR([SettingsCmmCPPFlags]) SUBST_TOOLDIR([SettingsJavaScriptCPPCommand]) SUBST_TOOLDIR([SettingsJavaScriptCPPFlags]) SUBST_TOOLDIR([SettingsMergeObjectsCommand]) @@ -145,6 +157,9 @@ AC_DEFUN([FP_SETTINGS], AC_SUBST(SettingsCPPFlags) AC_SUBST(SettingsHaskellCPPCommand) AC_SUBST(SettingsHaskellCPPFlags) + AC_SUBST(SettingsCmmCPPCommand) + AC_SUBST(SettingsCmmCPPFlags) + AC_SUBST(SettingsCmmCPPSupportsG0) AC_SUBST(SettingsJavaScriptCPPCommand) AC_SUBST(SettingsJavaScriptCPPFlags) AC_SUBST(SettingsCCompilerFlags) diff --git a/m4/fp_setup_windows_toolchain.m4 b/m4/fp_setup_windows_toolchain.m4 index 91acc1b94360b06672270d7d4601b07def94674c..a9a795fc31d9b6df1a343b2cf7e02be7942db0c5 100644 --- a/m4/fp_setup_windows_toolchain.m4 +++ b/m4/fp_setup_windows_toolchain.m4 @@ -117,6 +117,7 @@ AC_DEFUN([FP_SETUP_WINDOWS_TOOLCHAIN],[ HaskellCPPArgs="$HaskellCPPArgs -I$mingwinclude" JavaScriptCPPCmd="$JavaScriptCPPCmd -I$mingwinclude" + CmmCPPArgs="$CmmCPPArgs -I$mingwinclude" CONF_GCC_LINKER_OPTS_STAGE1="-fuse-ld=lld $cflags -L$mingwlib -L$mingw_mingw32_lib" CONF_GCC_LINKER_OPTS_STAGE2="-fuse-ld=lld $cflags -L$mingwlib -L$mingw_mingw32_lib" @@ -150,4 +151,5 @@ AC_DEFUN([FP_SETUP_WINDOWS_TOOLCHAIN],[ USER_HS_CPP_ARGS="$HaskellCPPArgs" USER_LDFLAGS="$CONF_GCC_LINKER_OPTS_STAGE2" USER_JS_CPP_ARGS="$JavaScriptCPPArgs" + USER_CMM_CPP_ARGS="$CmmCPPArgs" ]) diff --git a/m4/ghc_toolchain.m4 b/m4/ghc_toolchain.m4 index 00d84f7293c12fab1fa182b688c02a1a409088c6..43c3b3ed7d87c2b046fe02ccf3ad5355216e09f1 100644 --- a/m4/ghc_toolchain.m4 +++ b/m4/ghc_toolchain.m4 @@ -99,6 +99,7 @@ AC_DEFUN([FIND_GHC_TOOLCHAIN], echo "--cpp=$CPPCmd" >> acargs echo "--hs-cpp=$HaskellCPPCmd" >> acargs echo "--js-cpp=$JavaScriptCPPCmd" >> acargs + echo "--cmm-cpp=$CmmCPPCommand" >> acargs echo "--cc-link=$CC" >> acargs echo "--ar=$AR" >> acargs echo "--ranlib=$RANLIB" >> acargs @@ -125,6 +126,7 @@ AC_DEFUN([FIND_GHC_TOOLCHAIN], ADD_GHC_TOOLCHAIN_ARG([cpp-opt], [$USER_CPP_ARGS]) ADD_GHC_TOOLCHAIN_ARG([hs-cpp-opt], [$USER_HS_CPP_ARGS]) ADD_GHC_TOOLCHAIN_ARG([js-cpp-opt], [$USER_JS_CPP_ARGS]) + ADD_GHC_TOOLCHAIN_ARG([cmm-cpp-opt], [$USER_CMM_CPP_ARGS]) INVOKE_GHC_TOOLCHAIN() diff --git a/m4/prep_target_file.m4 b/m4/prep_target_file.m4 index 3f2e844c5270f2324c6d73a4fd16d1a1b4370ab8..bcce8883be12b5e7303522745795777c717ab1db 100644 --- a/m4/prep_target_file.m4 +++ b/m4/prep_target_file.m4 @@ -146,6 +146,8 @@ AC_DEFUN([PREP_TARGET_FILE],[ PREP_LIST([CONF_GCC_LINKER_OPTS_STAGE2]) PREP_LIST([HaskellCPPArgs]) PREP_LIST([JavaScriptCPPArgs]) + PREP_LIST([CmmCPPArgs]) + PREP_LIST([CmmCPPArgs_STAGE0]) PREP_MAYBE_SIMPLE_PROGRAM([WindresCmd]) PREP_MAYBE_STRING([TargetVendor_CPP]) PREP_MAYBE_STRING([HostVendor_CPP]) diff --git a/testsuite/tests/cmm/should_compile/T24474-cmm-gets-c-opts.cmm b/testsuite/tests/cmm/should_compile/T24474-cmm-gets-c-opts.cmm new file mode 100644 index 0000000000000000000000000000000000000000..8d163a2ce349be1e1f12029bd942aad2804af684 --- /dev/null +++ b/testsuite/tests/cmm/should_compile/T24474-cmm-gets-c-opts.cmm @@ -0,0 +1,5 @@ +/* Test that that C-- C pre-processor receives -optc args. */ + +#ifndef FOO +# error "C pre-processor arguments not passed" +#endif diff --git a/testsuite/tests/cmm/should_compile/T24474-cmm-opt-order.cmm b/testsuite/tests/cmm/should_compile/T24474-cmm-opt-order.cmm new file mode 100644 index 0000000000000000000000000000000000000000..b9cb8dfabdb3672845770c1a39d46e3b8ded43a6 --- /dev/null +++ b/testsuite/tests/cmm/should_compile/T24474-cmm-opt-order.cmm @@ -0,0 +1,6 @@ +/* Test that that C-- C pre-processor arguments are passed after the C + arguments, always. */ + +#if defined(FOO) || defined(BAR) +# error "Arguments were applied in the wrong order" +#endif diff --git a/testsuite/tests/cmm/should_compile/T24474.cmm b/testsuite/tests/cmm/should_compile/T24474.cmm new file mode 100644 index 0000000000000000000000000000000000000000..da36f9e8518e443224ee70e581a3e152e1659d7b --- /dev/null +++ b/testsuite/tests/cmm/should_compile/T24474.cmm @@ -0,0 +1,2 @@ +/* Test that -optc-g3 does not fail compilation of C-- files. */ +#define foo 123 diff --git a/testsuite/tests/cmm/should_compile/all.T b/testsuite/tests/cmm/should_compile/all.T index 3271a91faa68c2b9be77c9a4f0dc8b720ac5e92f..6195d5819bb1c882c1ccfe634094d35add18d649 100644 --- a/testsuite/tests/cmm/should_compile/all.T +++ b/testsuite/tests/cmm/should_compile/all.T @@ -12,3 +12,9 @@ test('T17442', normal, compile, ['']) test('T20725', normal, compile, ['-package ghc']) test('T23610', normal, makefile_test, ['T23610']) test('T24224', [cmm_src, grep_errmsg(r'(F64.*);', [1])], compile, ['-no-hs-main -ddump-cmm -dsuppress-all -dsuppress-uniques']) +test('T24474', cmm_src, compile, ['-optc-g3']) +test('T24474-cmm-gets-c-opts', cmm_src, compile, ['-optc-DFOO']) +test('T24474-cmm-opt-order', cmm_src, compile, ['-optc-DFOO ' + '-optCmmP-UFOO ' + '-optCmmP-UBAR ' + '-optc-DBAR']) diff --git a/testsuite/tests/cmm/should_fail/T24474-cmm-override-g0.cmm b/testsuite/tests/cmm/should_fail/T24474-cmm-override-g0.cmm new file mode 100644 index 0000000000000000000000000000000000000000..8002680578f56fc2b39c08d7ecf7e41d9f48c7bc --- /dev/null +++ b/testsuite/tests/cmm/should_fail/T24474-cmm-override-g0.cmm @@ -0,0 +1 @@ +/* Test that -optCmmP-g3 /does/ fail compilation of C-- files. */ diff --git a/testsuite/tests/cmm/should_fail/T24474-cmm-override-g0.stderr b/testsuite/tests/cmm/should_fail/T24474-cmm-override-g0.stderr new file mode 100644 index 0000000000000000000000000000000000000000..16c315861bd71f576aa475346aa35cff628ed566 --- /dev/null +++ b/testsuite/tests/cmm/should_fail/T24474-cmm-override-g0.stderr @@ -0,0 +1,2 @@ +<built-in>:0:2: error: [GHC-75725] + Cmm lexical error diff --git a/testsuite/tests/cmm/should_fail/all.T b/testsuite/tests/cmm/should_fail/all.T new file mode 100644 index 0000000000000000000000000000000000000000..fd01f2bf9b6b75704a77db8b4473a8b9c1f0cd46 --- /dev/null +++ b/testsuite/tests/cmm/should_fail/all.T @@ -0,0 +1,7 @@ +test('T24474-cmm-override-g0', + [cmm_src, + check_errmsg('GHC-75725'), + # Relies on GCC, as this is a GCC-related workaround. + unless(gcc_as_cmmp(), fragile(0))], + compile_fail, + ['-optCmmP-g3']) diff --git a/testsuite/tests/diagnostic-codes/codes.stdout b/testsuite/tests/diagnostic-codes/codes.stdout index a189eaafd09edc7f5799894920e40b52ec019214..ad93f29bac1b035571d91ac7737a66592ddc3020 100644 --- a/testsuite/tests/diagnostic-codes/codes.stdout +++ b/testsuite/tests/diagnostic-codes/codes.stdout @@ -13,7 +13,6 @@ [GHC-58181] is untested (constructor = DsOrphanRule) [GHC-69441] is untested (constructor = DsRuleLhsTooComplicated) [GHC-19551] is untested (constructor = DsAggregatedViewExpressions) -[GHC-75725] is untested (constructor = PsErrCmmLexer) [GHC-09848] is untested (constructor = PsErrCmmParser) [GHC-95644] is untested (constructor = PsErrBangPatWithoutSpace) [GHC-45106] is untested (constructor = PsErrInvalidInfixHole) diff --git a/testsuite/tests/ghc-api/settings-escape/T11938.hs b/testsuite/tests/ghc-api/settings-escape/T11938.hs index e06b43c9ab36e2724018ebca7dcfefe45112d726..ac7bff1dc114412bc57b88e0274de50839195621 100644 --- a/testsuite/tests/ghc-api/settings-escape/T11938.hs +++ b/testsuite/tests/ghc-api/settings-escape/T11938.hs @@ -45,6 +45,7 @@ main = do multipleArguments = Set.fromList [ "Haskell CPP flags" , "JavaScript CPP flags" + , "C-- CPP flags" , "C compiler flags" , "C++ compiler flags" , "CPP flags" @@ -117,6 +118,9 @@ main = do -- Setting 'JavaScript CPP flags' contains '$topdir' reference. -- Resolving those while containing spaces, should not introduce more options. recordSetting "JavaScript CPP flags" (map showOpt . snd . toolSettings_pgm_JSP . sToolSettings) + -- Setting 'C-- CPP flags' contains '$topdir' reference. + -- Resolving those while containing spaces, should not introduce more options. + recordSetting "C-- CPP flags" (map showOpt . snd . toolSettings_pgm_CmmP . sToolSettings) -- Setting 'C compiler flags' contains strings with spaces. -- GHC should not split these by word. recordSetting "C compiler flags" (toolSettings_opt_c . sToolSettings) diff --git a/testsuite/tests/ghc-api/settings-escape/T11938.stderr b/testsuite/tests/ghc-api/settings-escape/T11938.stderr index 9ffaee06cccbb8c6672868b271c6ea0a69dd4f26..0b454df2c02f7342b978999f1f32050984ab9f06 100644 --- a/testsuite/tests/ghc-api/settings-escape/T11938.stderr +++ b/testsuite/tests/ghc-api/settings-escape/T11938.stderr @@ -2,6 +2,8 @@ Contains spaces: True === 'JavaScript CPP flags' contains 2 new entries: True Contains spaces: True +=== 'C-- CPP flags' contains 2 new entries: True + Contains spaces: True === 'C compiler flags' contains 2 new entries: True Contains spaces: True === 'C compiler link flags' contains 2 new entries: True diff --git a/utils/check-exact/Preprocess.hs b/utils/check-exact/Preprocess.hs index bdf095f0f384c8ea937d4b00791035b35ed243d3..4681f351154fe4fad6b3c336f711fd7a5060a187 100644 --- a/utils/check-exact/Preprocess.hs +++ b/utils/check-exact/Preprocess.hs @@ -231,14 +231,14 @@ showErrorMessages msgs = $ msgs injectCppOptions :: CppOptions -> GHC.DynFlags -> GHC.DynFlags -injectCppOptions CppOptions{..} dflags = folded_opt_jsp_with_p +injectCppOptions CppOptions{..} dflags = folded_opt where mkDefine = ("-D" ++) mkIncludeDir = ("-I" ++) mkInclude = ("-include" ++) file_flags = map mkDefine cppDefine ++ map mkIncludeDir cppInclude ++ map mkInclude cppFile - folded_opt_p = foldr addOptP dflags file_flags - folded_opt_jsp_with_p = foldr addOptJSP folded_opt_p file_flags + addFs = [addOptP, addOptJSP, addOptCmmP] + folded_opt = foldr ($) dflags (addFs <*> file_flags) addOptP :: String -> GHC.DynFlags -> GHC.DynFlags addOptP f = alterToolSettings $ \s -> s @@ -250,6 +250,11 @@ addOptJSP f = alterToolSettings $ \s -> s { GHC.toolSettings_opt_JSP = f : GHC.toolSettings_opt_JSP s , GHC.toolSettings_opt_JSP_fingerprint = GHC.fingerprintStrings (f : GHC.toolSettings_opt_JSP s) } +addOptCmmP :: String -> GHC.DynFlags -> GHC.DynFlags +addOptCmmP f = alterToolSettings $ \s -> s + { GHC.toolSettings_opt_CmmP = f : GHC.toolSettings_opt_CmmP s + , GHC.toolSettings_opt_CmmP_fingerprint = GHC.fingerprintStrings (f : GHC.toolSettings_opt_CmmP s) + } alterToolSettings :: (GHC.ToolSettings -> GHC.ToolSettings) -> GHC.DynFlags -> GHC.DynFlags alterToolSettings f dynFlags = dynFlags { GHC.toolSettings = f (GHC.toolSettings dynFlags) } diff --git a/utils/ghc-toolchain/exe/Main.hs b/utils/ghc-toolchain/exe/Main.hs index 0c2bb7a304a556f05ccecc025b91f43606a917f0..b37a7603f3b2b5f10650afb744276a1ef410be00 100644 --- a/utils/ghc-toolchain/exe/Main.hs +++ b/utils/ghc-toolchain/exe/Main.hs @@ -44,6 +44,7 @@ data Opts = Opts , optCpp :: ProgOpt , optHsCpp :: ProgOpt , optJsCpp :: ProgOpt + , optCmmCpp :: ProgOpt , optCcLink :: ProgOpt , optAr :: ProgOpt , optRanlib :: ProgOpt @@ -90,6 +91,7 @@ emptyOpts = Opts , optCpp = po0 , optHsCpp = po0 , optJsCpp = po0 + , optCmmCpp = po0 , optCcLink = po0 , optAr = po0 , optRanlib = po0 @@ -108,14 +110,15 @@ emptyOpts = Opts where po0 = emptyProgOpt -_optCc, _optCxx, _optCpp, _optHsCpp, _optJsCpp, _optCcLink, _optAr, _optRanlib, - _optNm, _optReadelf, _optMergeObjs, _optWindres, _optLd +_optCc, _optCxx, _optCpp, _optHsCpp, _optJsCpp, _optCmmCpp, _optCcLink, _optAr, + _optRanlib, _optNm, _optReadelf, _optMergeObjs, _optWindres, _optLd :: Lens Opts ProgOpt _optCc = Lens optCc (\x o -> o {optCc=x}) _optCxx = Lens optCxx (\x o -> o {optCxx=x}) _optCpp = Lens optCpp (\x o -> o {optCpp=x}) _optHsCpp = Lens optHsCpp (\x o -> o {optHsCpp=x}) _optJsCpp = Lens optJsCpp (\x o -> o {optJsCpp=x}) +_optCmmCpp = Lens optCmmCpp (\x o -> o {optCmmCpp=x}) _optCcLink = Lens optCcLink (\x o -> o {optCcLink=x}) _optAr = Lens optAr (\x o -> o {optAr=x}) _optRanlib = Lens optRanlib (\x o -> o {optRanlib=x}) @@ -171,6 +174,7 @@ options = , progOpts "cpp" "C preprocessor" _optCpp , progOpts "hs-cpp" "Haskell C preprocessor" _optHsCpp , progOpts "js-cpp" "JavaScript C preprocessor" _optJsCpp + , progOpts "cmm-cpp" "C-- C preprocessor" _optCmmCpp , progOpts "cxx" "C++ compiler" _optCxx , progOpts "cc-link" "C compiler for linking" _optCcLink , progOpts "ar" "ar archiver" _optAr @@ -396,6 +400,7 @@ mkTarget opts = do -- TODO: same case as ranlib below -- TODO: we need it really only for javascript target (maybe wasm target as well) jsCpp <- Just <$> findJsCpp (optJsCpp opts) cc0 + cmmCpp <- findCmmCpp (optCmmCpp opts) cc0 cc <- addPlatformDepCcFlags archOs cc0 readelf <- optional $ findReadelf (optReadelf opts) ccLink <- findCcLink tgtLlvmTarget (optLd opts) (optCcLink opts) (ldOverrideWhitelist archOs && fromMaybe True (optLdOverride opts)) archOs cc readelf @@ -452,6 +457,7 @@ mkTarget opts = do , tgtCPreprocessor = cpp , tgtHsCPreprocessor = hsCpp , tgtJsCPreprocessor = jsCpp + , tgtCmmCPreprocessor = cmmCpp , tgtAr = ar , tgtCCompilerLink = ccLink , tgtRanlib = ranlib diff --git a/utils/ghc-toolchain/src/GHC/Toolchain/Target.hs b/utils/ghc-toolchain/src/GHC/Toolchain/Target.hs index 5fa1209b7da68c40c01074454d041e21ab742223..ec95db46f9da35636ee7e04a4e5ed55e1870b13f 100644 --- a/utils/ghc-toolchain/src/GHC/Toolchain/Target.hs +++ b/utils/ghc-toolchain/src/GHC/Toolchain/Target.hs @@ -62,6 +62,7 @@ data Target = Target , tgtCPreprocessor :: Cpp , tgtHsCPreprocessor :: HsCpp , tgtJsCPreprocessor :: Maybe JsCpp + , tgtCmmCPreprocessor :: CmmCpp -- ^ We set it only in javascript target , tgtCCompilerLink :: CcLink , tgtAr :: Ar @@ -114,6 +115,7 @@ instance Show Target where , ", tgtCPreprocessor = " ++ show tgtCPreprocessor , ", tgtHsCPreprocessor = " ++ show tgtHsCPreprocessor , ", tgtJsCPreprocessor = " ++ show tgtJsCPreprocessor + , ", tgtCmmCPreprocessor = " ++ show tgtCmmCPreprocessor , ", tgtCCompilerLink = " ++ show tgtCCompilerLink , ", tgtAr = " ++ show tgtAr , ", tgtRanlib = " ++ show tgtRanlib diff --git a/utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs b/utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs index 94b2051d7e40899b1d7adbd63d4ebe13873a731d..909e8646f9f72ab50631f7ca46dd8df31206da7e 100644 --- a/utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs +++ b/utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs @@ -1,6 +1,11 @@ {-# LANGUAGE NamedFieldPuns #-} -module GHC.Toolchain.Tools.Cpp (HsCpp(..), findHsCpp, Cpp(..), findCpp, JsCpp(..), findJsCpp) where +module GHC.Toolchain.Tools.Cpp + (HsCpp(..), findHsCpp + , Cpp(..), findCpp + , JsCpp(..), findJsCpp + , CmmCpp(..), findCmmCpp + ) where import Control.Monad import System.FilePath @@ -25,6 +30,24 @@ newtype JsCpp = JsCpp { jsCppProgram :: Program } deriving (Show, Read, Eq, Ord) +data CmmCpp = CmmCpp { cmmCppProgram :: Program + , cmmCppSupportsG0 :: Bool + -- ^ Whether the C-- preprocessor supports -g0. Extracted + -- out as -g0 needs to be appended to the complete + -- invocation, rather than prefix flags, in order to + -- override other flags. + } + deriving (Show, Read, Eq, Ord) + +checkFlag :: String -> Program -> String -> M () +checkFlag conftest cpp flag = checking ("for "++flag++" support") $ + -- Werror to ensure that unrecognized warnings result in an error + callProgram cpp ["-Werror", flag, conftest] +-- tryFlag :: String -> Program -> String -> M [String] +-- tryFlag conftest cpp flag = +-- ([flag] <$ checkFlag conftest cpp flag) <|> return [] + + ----- Haskell Preprocessor ----- findHsCpp :: ProgOpt -> Cc -> M HsCpp @@ -65,20 +88,13 @@ findHsCppArgs cpp = withTempDir $ \dir -> do withTmpDir $ \dir -> do let tmp_h = dir </> "tmp.h" - -- Werror to ensure that unrecognized warnings result in an error - let checkFlag flag = - checking ("for "++flag++" support") $ callProgram cpp ["-Werror", flag, tmp_h] - - tryFlag flag = - ([flag] <$ checkFlag flag) <|> return [] - writeFile tmp_h "" concat <$> sequence [ tryFlag "-undef" - , ["-traditional"] <$ checkFlag "-traditional" - , tryFlag "-Wno-invalid-pp-token" - , tryFlag "-Wno-unicode" - , tryFlag "-Wno-trigraphs" + , ["-traditional"] <$ checkFlag tmp_h cpp "-traditional" + , tryFlag tmp_h cpp "-Wno-invalid-pp-token" + , tryFlag tmp_h cpp "-Wno-unicode" + , tryFlag tmp_h cpp "-Wno-trigraphs" ] -} @@ -136,6 +152,27 @@ findJsCpp progOpt cc = checking "for JavaScript C preprocessor" $ do unless (trim file_output_in_dir_content == "// 1") $ throwE "JavaScript C Preprocessor didn't provide correct output" +----- C-- preprocessor ----- + +findCmmCpp :: ProgOpt -> Cc -> M CmmCpp +findCmmCpp progOpt cc = checking "for a Cmm preprocessor" $ do + -- Use the specified CPP or try to use the c compiler + foundCppProg <- findProgram "Cmm preprocessor" progOpt [] <|> pure (programFromOpt progOpt (prgPath $ ccProgram cc) []) + -- Check whether the C preprocessor needs -std=gnu99 (only very old toolchains need this) + Cc cpp <- oneOf "cc doesn't support C99" $ map checkC99Support + [ Cc foundCppProg + , Cc (foundCppProg & _prgFlags %++ "-std=gnu99") + ] + + cmmCppSupportsG0 <- withTempDir $ \dir -> do + let conftest = dir </> "conftest.c" + writeFile conftest "int main(void) {}" + True <$ checkFlag conftest cpp "-g0" <|> return False + + -- Always add the -E flag to the CPP, regardless of the user options + let cmmCppProgram = foldr addFlagIfNew cpp ["-E"] + return CmmCpp{cmmCppProgram, cmmCppSupportsG0} + ----- C preprocessor ----- findCpp :: ProgOpt -> Cc -> M Cpp