From 1c18d3b41f897f34a93669edaebe6069f319f9e2 Mon Sep 17 00:00:00 2001 From: Zejun Wu Date: Tue, 4 Jun 2019 15:25:10 -0700 Subject: Pass preprocessor options to C compiler when building foreign C files (#16737) (cherry picked from commit cfd3e0f1cfd16c8f35cae139d2a871a32eb4d2e1) --- compiler/main/DriverPipeline.hs | 16 ++++++++++---- testsuite/tests/driver/T16737.hs | 32 +++++++++++++++++++++++++++ testsuite/tests/driver/T16737.stdout | 2 ++ testsuite/tests/driver/T16737include/T16737.h | 7 ++++++ testsuite/tests/driver/all.T | 1 + 5 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 testsuite/tests/driver/T16737.hs create mode 100644 testsuite/tests/driver/T16737.stdout create mode 100644 testsuite/tests/driver/T16737include/T16737.h diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs index 5d3dbafdbb..39d818889b 100644 --- a/compiler/main/DriverPipeline.hs +++ b/compiler/main/DriverPipeline.hs @@ -1193,9 +1193,6 @@ runPhase (RealPhase Cmm) input_fn dflags ----------------------------------------------------------------------------- -- Cc phase --- we don't support preprocessing .c files (with -E) now. Doing so introduces --- way too many hacks, and I can't say I've ever used it anyway. - runPhase (RealPhase cc_phase) input_fn dflags | any (cc_phase `eqPhase`) [Cc, Ccxx, HCc, Cobjc, Cobjcxx] = do @@ -1217,6 +1214,16 @@ runPhase (RealPhase cc_phase) input_fn dflags (includePathsQuote cmdline_include_paths) let include_paths = include_paths_quote ++ include_paths_global + -- pass -D or -optP to preprocessor when compiling foreign C files + -- (#16737). Doing it in this way is simpler and also enable the C + -- compiler to performs preprocessing and parsing in a single pass, + -- but it may introduce inconsistency if a different pgm_P is specified. + let more_preprocessor_opts = concat + [ ["-Xpreprocessor", i] + | not hcc + , i <- getOpts dflags opt_P + ] + let gcc_extra_viac_flags = extraGccViaCFlags dflags let pic_c_flags = picCCOpts dflags @@ -1226,7 +1233,7 @@ runPhase (RealPhase cc_phase) input_fn dflags -- hc code doesn't not #include any header files anyway, so these -- options aren't necessary. pkg_extra_cc_opts <- liftIO $ - if cc_phase `eqPhase` HCc + if hcc then return [] else getPackageExtraCcOpts dflags pkgs @@ -1317,6 +1324,7 @@ runPhase (RealPhase cc_phase) input_fn dflags ++ [ "-include", ghcVersionH ] ++ framework_paths ++ include_paths + ++ more_preprocessor_opts ++ pkg_extra_cc_opts )) diff --git a/testsuite/tests/driver/T16737.hs b/testsuite/tests/driver/T16737.hs new file mode 100644 index 0000000000..daf830693b --- /dev/null +++ b/testsuite/tests/driver/T16737.hs @@ -0,0 +1,32 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -DFOO=2 -optP=-DBAR=3 -optc=-DBAZ=5 -optcxx=-DBAZ=7 #-} + +import Language.Haskell.TH.Syntax + +do + let code = unlines + [ "#if defined(__cplusplus)" + , "extern \"C\" {" + , "#endif" + , "#include " + , "int FUN(void) {" + , " return FOO * BAR * BAZ;" + , "}" + , "#if defined(__cplusplus)" + , "}" + , "#endif" + ] + addForeignSource LangC code + addForeignSource LangCxx code + pure [] + +foreign import ccall unsafe "c_value" + c_value :: IO Int + +foreign import ccall unsafe "cxx_value" + cxx_value :: IO Int + +main :: IO () +main = do + print =<< c_value + print =<< cxx_value diff --git a/testsuite/tests/driver/T16737.stdout b/testsuite/tests/driver/T16737.stdout new file mode 100644 index 0000000000..8a3609b7ca --- /dev/null +++ b/testsuite/tests/driver/T16737.stdout @@ -0,0 +1,2 @@ +30 +42 diff --git a/testsuite/tests/driver/T16737include/T16737.h b/testsuite/tests/driver/T16737include/T16737.h new file mode 100644 index 0000000000..08c7ca8729 --- /dev/null +++ b/testsuite/tests/driver/T16737include/T16737.h @@ -0,0 +1,7 @@ +#pragma once + +#if defined(__cplusplus) +#define FUN cxx_value +#else +#define FUN c_value +#endif diff --git a/testsuite/tests/driver/all.T b/testsuite/tests/driver/all.T index 02eeeb321b..397fdc5622 100644 --- a/testsuite/tests/driver/all.T +++ b/testsuite/tests/driver/all.T @@ -287,3 +287,4 @@ test('inline-check', omit_ways(['hpc', 'profasm']) test('T14452', [], run_command, ['$MAKE -s --no-print-directory T14452']) test('T15396', normal, compile_and_run, ['-package ghc']) +test('T16737', [extra_files(['T16737include/'])], compile_and_run, ['-optP=-isystem -optP=T16737include']) -- cgit v1.2.1