diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index 49db03ee3c1..4c2932f0394 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -621,6 +621,8 @@ buildInfoFieldGrammar = <*> monoidalFieldAla "cc-options" (alaList' NoCommaFSep Token') L.ccOptions <*> monoidalFieldAla "cxx-options" (alaList' NoCommaFSep Token') L.cxxOptions ^^^ availableSince CabalSpecV2_2 [] + <*> monoidalFieldAla "js-options" (alaList' NoCommaFSep Token') L.jsOptions + ^^^ availableSince CabalSpecV3_14 [] <*> monoidalFieldAla "ld-options" (alaList' NoCommaFSep Token') L.ldOptions <*> monoidalFieldAla "hsc2hs-options" (alaList' NoCommaFSep Token') L.hsc2hsOptions ^^^ availableSince CabalSpecV3_6 [] diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs index 2d7a5edeae1..8ea6423e65c 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs @@ -61,6 +61,8 @@ data BuildInfo = BuildInfo -- ^ options for C compiler , cxxOptions :: [String] -- ^ options for C++ compiler + , jsOptions :: [String] + -- ^ options for pre-processing JavaScript code , ldOptions :: [String] -- ^ options for linker , hsc2hsOptions :: [String] @@ -161,6 +163,7 @@ instance Monoid BuildInfo where , cmmOptions = [] , ccOptions = [] , cxxOptions = [] + , jsOptions = [] , ldOptions = [] , hsc2hsOptions = [] , pkgconfigDepends = [] @@ -214,6 +217,7 @@ instance Semigroup BuildInfo where , cmmOptions = combine cmmOptions , ccOptions = combine ccOptions , cxxOptions = combine cxxOptions + , jsOptions = combine jsOptions , ldOptions = combine ldOptions , hsc2hsOptions = combine hsc2hsOptions , pkgconfigDepends = combine pkgconfigDepends diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs index ac99f3c65a5..c80698681f3 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs @@ -59,6 +59,10 @@ class HasBuildInfo a where cxxOptions = buildInfo . cxxOptions {-# INLINE cxxOptions #-} + jsOptions :: Lens' a [String] + jsOptions = buildInfo . jsOptions + {-# INLINE jsOptions #-} + ldOptions :: Lens' a [String] ldOptions = buildInfo . ldOptions {-# INLINE ldOptions #-} diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index 6e27b41bc83..f5353a3d2ab 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -489,6 +489,7 @@ componentJsGhcOptions verbosity lbi bi clbi odir filename = , ghcOptPackageDBs = withPackageDB lbi , ghcOptPackages = toNubListR $ mkGhcOptPackages (promisedPkgs lbi) clbi , ghcOptObjDir = toFlag odir + , ghcOptExtra = jsOptions bi } componentGhcOptions diff --git a/cabal-testsuite/PackageTests/JS/JsOptions/cabal.project b/cabal-testsuite/PackageTests/JS/JsOptions/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/JS/JsOptions/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/JS/JsOptions/demo/Main.hs b/cabal-testsuite/PackageTests/JS/JsOptions/demo/Main.hs new file mode 100644 index 00000000000..19e67f001f8 --- /dev/null +++ b/cabal-testsuite/PackageTests/JS/JsOptions/demo/Main.hs @@ -0,0 +1,6 @@ +module Main where + +import Lib + +main :: IO () +main = foo diff --git a/cabal-testsuite/PackageTests/JS/JsOptions/js.test.hs b/cabal-testsuite/PackageTests/JS/JsOptions/js.test.hs new file mode 100644 index 00000000000..c7df6e8e986 --- /dev/null +++ b/cabal-testsuite/PackageTests/JS/JsOptions/js.test.hs @@ -0,0 +1,9 @@ +import Test.Cabal.Prelude + +main = do + skipUnlessJavaScript + skipIfWindows "" + setupAndCabalTest $ do + skipUnlessGhcVersion ">= 9.12" + res <- cabal' "v2-run" ["demo"] + assertOutputContains "Hello definition!" res diff --git a/cabal-testsuite/PackageTests/JS/JsOptions/jsbits/lib.js b/cabal-testsuite/PackageTests/JS/JsOptions/jsbits/lib.js new file mode 100644 index 00000000000..b3b8beb78fb --- /dev/null +++ b/cabal-testsuite/PackageTests/JS/JsOptions/jsbits/lib.js @@ -0,0 +1,9 @@ +//#OPTIONS: CPP + +function foo() { +#ifdef PRINT_DEF + console.log("Hello definition!"); +#else + console.log("Hello!"); +#endif +} diff --git a/cabal-testsuite/PackageTests/JS/JsOptions/jsoptions.cabal b/cabal-testsuite/PackageTests/JS/JsOptions/jsoptions.cabal new file mode 100644 index 00000000000..00d6b3e9089 --- /dev/null +++ b/cabal-testsuite/PackageTests/JS/JsOptions/jsoptions.cabal @@ -0,0 +1,19 @@ +cabal-version: 3.14 +name: jsoptions +version: 0 +build-type: Simple + +library + default-language: Haskell2010 + exposed-modules: Lib + build-depends: base + + if impl(javascript) + js-sources: jsbits/lib.js + js-options: -optJSP-DPRINT_DEF + +executable demo + default-language: Haskell2010 + main-is: Main.hs + hs-source-dirs: demo + build-depends: base, jsoptions diff --git a/cabal-testsuite/PackageTests/JS/JsOptions/other-arch.out b/cabal-testsuite/PackageTests/JS/JsOptions/other-arch.out new file mode 100644 index 00000000000..eeec21715d5 --- /dev/null +++ b/cabal-testsuite/PackageTests/JS/JsOptions/other-arch.out @@ -0,0 +1,14 @@ +# cabal v2-run +Configuration is affected by the following files: +- cabal.project +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - jsoptions-exe-0 (lib) (first run) + - jsoptions-exe-0 (exe:demo) (first run) +Configuring library for jsoptions-exe-0... +Preprocessing library for jsoptions-exe-0... +Building library for jsoptions-exe-0... +Configuring executable 'demo' for jsoptions-exe-0... +Preprocessing executable 'demo' for jsoptions-exe-0... +Building executable 'demo' for jsoptions-exe-0... diff --git a/cabal-testsuite/PackageTests/JS/JsOptions/other-arch.test.hs b/cabal-testsuite/PackageTests/JS/JsOptions/other-arch.test.hs new file mode 100644 index 00000000000..0659304d12b --- /dev/null +++ b/cabal-testsuite/PackageTests/JS/JsOptions/other-arch.test.hs @@ -0,0 +1,8 @@ +import Test.Cabal.Prelude + +main = do + skipIfJavaScript + cabalTest $ do + -- Ensure the field `js-options` does not raise issues + res <- cabal' "v2-run" ["demo"] + assertOutputContains "foo_fallback" res diff --git a/cabal-testsuite/PackageTests/JS/JsOptions/src/Lib.hs b/cabal-testsuite/PackageTests/JS/JsOptions/src/Lib.hs new file mode 100644 index 00000000000..a61f3098927 --- /dev/null +++ b/cabal-testsuite/PackageTests/JS/JsOptions/src/Lib.hs @@ -0,0 +1,9 @@ +{-# LANGUAGE CPP #-} +module Lib where + +#if defined(javascript_HOST_ARCH) +foreign import javascript foo :: IO () +#else +foo :: IO () +foo = putStrLn "foo_fallback" +#endif \ No newline at end of file diff --git a/doc/buildinfo-fields-reference.rst b/doc/buildinfo-fields-reference.rst index a289292945a..27fefbb8030 100644 --- a/doc/buildinfo-fields-reference.rst +++ b/doc/buildinfo-fields-reference.rst @@ -268,6 +268,14 @@ cxx-options .. math:: {\left\{ \mathop{\mathit{hs\text{-}string}}\mid{{[\mathop{\mathord{``}\mathtt{\ }\mathord{"}}]^c}}^+_{} \right\}}^\ast_{\bullet} +js-options + * Monoidal field + * Available since ``cabal-version: 3.14``. + * Documentation of :pkg-field:`library:js-options` + + .. math:: + {\left\{ \mathop{\mathit{hs\text{-}string}}\mid{{[\mathop{\mathord{``}\mathtt{\ }\mathord{"}}]^c}}^+_{} \right\}}^\ast_{\bullet} + cxx-sources * Monoidal field * Available since ``cabal-version: 2.2``. diff --git a/editors/vim/syntax/cabal.vim b/editors/vim/syntax/cabal.vim index 2e578307a7e..349f244178e 100644 --- a/editors/vim/syntax/cabal.vim +++ b/editors/vim/syntax/cabal.vim @@ -67,6 +67,7 @@ syn keyword cabalFieldName contained \ copyright \ cpp-options \ cxx-options + \ js-options \ cxx-sources \ data-dir \ data-files