summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZejun Wu <watashi@fb.com>2019-06-04 15:25:10 -0700
committerBen Gamari <ben@smart-cactus.org>2019-06-23 13:27:12 -0400
commit1c18d3b41f897f34a93669edaebe6069f319f9e2 (patch)
tree8e81dd7f20d6a25c2d48caaf33710fdc7e0a2758
parentc1c0ce7ad45a24042175f2b0d2eb466a769ba29d (diff)
downloadhaskell-1c18d3b41f897f34a93669edaebe6069f319f9e2.tar.gz
Pass preprocessor options to C compiler when building foreign C files (#16737)
(cherry picked from commit cfd3e0f1cfd16c8f35cae139d2a871a32eb4d2e1)
-rw-r--r--compiler/main/DriverPipeline.hs16
-rw-r--r--testsuite/tests/driver/T16737.hs32
-rw-r--r--testsuite/tests/driver/T16737.stdout2
-rw-r--r--testsuite/tests/driver/T16737include/T16737.h7
-rw-r--r--testsuite/tests/driver/all.T1
5 files changed, 54 insertions, 4 deletions
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 <T16737.h>"
+ , "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'])