diff --git a/.hlint.yaml b/.hlint.yaml index ce17428cf63..a12f8fafe10 100644 --- a/.hlint.yaml +++ b/.hlint.yaml @@ -57,10 +57,11 @@ # TODO: Remove --ignore-glob for ghc-supported-languages.hs when this module compiles - --ignore-glob=Cabal-tests/tests/misc/ghc-supported-languages.hs - --ignore-glob=cabal-testsuite/PackageTests/BuildWays/q/app/Main.hs + - --ignore-glob=cabal-testsuite/PackageTests/CppOptions/CppOpts/Main.hs - --ignore-glob=cabal-testsuite/PackageTests/CMain/10168/src/Lib.hs - - --ignore-glob=cabal-testsuite/PackageTests/CmmSources/src/Demo.hs - - --ignore-glob=cabal-testsuite/PackageTests/CmmSourcesDyn/src/Demo.hs - - --ignore-glob=cabal-testsuite/PackageTests/CmmSourcesExe/src/Demo.hs + - --ignore-glob=cabal-testsuite/PackageTests/Cmm/CmmSources/src/Demo.hs + - --ignore-glob=cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/src/Demo.hs + - --ignore-glob=cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/src/Demo.hs - --ignore-glob=cabal-testsuite/PackageTests/NewBuild/CmdRun/Script/script.hs - --ignore-glob=cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptLiterate/script.lhs - --ignore-glob=cabal-testsuite/PackageTests/Regression/T5309/lib/Bio/Character/Exportable/Class.hs diff --git a/cabal-testsuite/PackageTests/CmmSources/cabal.out b/cabal-testsuite/PackageTests/Cmm/CmmSources/cabal.out similarity index 100% rename from cabal-testsuite/PackageTests/CmmSources/cabal.out rename to cabal-testsuite/PackageTests/Cmm/CmmSources/cabal.out diff --git a/cabal-testsuite/PackageTests/CmmSources/cabal.project b/cabal-testsuite/PackageTests/Cmm/CmmSources/cabal.project similarity index 100% rename from cabal-testsuite/PackageTests/CmmSources/cabal.project rename to cabal-testsuite/PackageTests/Cmm/CmmSources/cabal.project diff --git a/cabal-testsuite/PackageTests/CmmSources/cabal.test.hs b/cabal-testsuite/PackageTests/Cmm/CmmSources/cabal.test.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSources/cabal.test.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSources/cabal.test.hs diff --git a/cabal-testsuite/PackageTests/CmmSources/cbits/HeapPrim.cmm b/cabal-testsuite/PackageTests/Cmm/CmmSources/cbits/HeapPrim.cmm similarity index 100% rename from cabal-testsuite/PackageTests/CmmSources/cbits/HeapPrim.cmm rename to cabal-testsuite/PackageTests/Cmm/CmmSources/cbits/HeapPrim.cmm diff --git a/cabal-testsuite/PackageTests/CmmSources/cmmexperiment.cabal b/cabal-testsuite/PackageTests/Cmm/CmmSources/cmmexperiment.cabal similarity index 100% rename from cabal-testsuite/PackageTests/CmmSources/cmmexperiment.cabal rename to cabal-testsuite/PackageTests/Cmm/CmmSources/cmmexperiment.cabal diff --git a/cabal-testsuite/PackageTests/CmmSources/demo/Main.hs b/cabal-testsuite/PackageTests/Cmm/CmmSources/demo/Main.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSources/demo/Main.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSources/demo/Main.hs diff --git a/cabal-testsuite/PackageTests/CmmSources/setup.out b/cabal-testsuite/PackageTests/Cmm/CmmSources/setup.out similarity index 100% rename from cabal-testsuite/PackageTests/CmmSources/setup.out rename to cabal-testsuite/PackageTests/Cmm/CmmSources/setup.out diff --git a/cabal-testsuite/PackageTests/CmmSources/setup.test.hs b/cabal-testsuite/PackageTests/Cmm/CmmSources/setup.test.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSources/setup.test.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSources/setup.test.hs diff --git a/cabal-testsuite/PackageTests/CmmSources/src/Demo.hs b/cabal-testsuite/PackageTests/Cmm/CmmSources/src/Demo.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSources/src/Demo.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSources/src/Demo.hs diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/cabal.out b/cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/cabal.out similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesDyn/cabal.out rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/cabal.out diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/cabal.project b/cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/cabal.project similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesDyn/cabal.project rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/cabal.project diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/cabal.test.hs b/cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/cabal.test.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesDyn/cabal.test.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/cabal.test.hs diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/cbits/HeapPrim.cmm b/cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/cbits/HeapPrim.cmm similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesDyn/cbits/HeapPrim.cmm rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/cbits/HeapPrim.cmm diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/cmmexperiment.cabal b/cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/cmmexperiment.cabal similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesDyn/cmmexperiment.cabal rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/cmmexperiment.cabal diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/demo/Main.hs b/cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/demo/Main.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesDyn/demo/Main.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/demo/Main.hs diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/setup.out b/cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/setup.out similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesDyn/setup.out rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/setup.out diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/setup.test.hs b/cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/setup.test.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesDyn/setup.test.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/setup.test.hs diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/src/Demo.hs b/cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/src/Demo.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesDyn/src/Demo.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesDyn/src/Demo.hs diff --git a/cabal-testsuite/PackageTests/CmmSourcesExe/cabal.out b/cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/cabal.out similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesExe/cabal.out rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/cabal.out diff --git a/cabal-testsuite/PackageTests/CmmSourcesExe/cabal.project b/cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/cabal.project similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesExe/cabal.project rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/cabal.project diff --git a/cabal-testsuite/PackageTests/CmmSourcesExe/cabal.test.hs b/cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/cabal.test.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesExe/cabal.test.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/cabal.test.hs diff --git a/cabal-testsuite/PackageTests/CmmSourcesExe/cbits/HeapPrim.cmm b/cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/cbits/HeapPrim.cmm similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesExe/cbits/HeapPrim.cmm rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/cbits/HeapPrim.cmm diff --git a/cabal-testsuite/PackageTests/CmmSourcesExe/cmmexperiment.cabal b/cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/cmmexperiment.cabal similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesExe/cmmexperiment.cabal rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/cmmexperiment.cabal diff --git a/cabal-testsuite/PackageTests/CmmSourcesExe/demo/Main.hs b/cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/demo/Main.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesExe/demo/Main.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/demo/Main.hs diff --git a/cabal-testsuite/PackageTests/CmmSourcesExe/setup.out b/cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/setup.out similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesExe/setup.out rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/setup.out diff --git a/cabal-testsuite/PackageTests/CmmSourcesExe/setup.test.hs b/cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/setup.test.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesExe/setup.test.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/setup.test.hs diff --git a/cabal-testsuite/PackageTests/CmmSourcesExe/src/Demo.hs b/cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/src/Demo.hs similarity index 100% rename from cabal-testsuite/PackageTests/CmmSourcesExe/src/Demo.hs rename to cabal-testsuite/PackageTests/Cmm/CmmSourcesExe/src/Demo.hs diff --git a/cabal-testsuite/PackageTests/CppOptions/CppOpts/Main.hs b/cabal-testsuite/PackageTests/CppOptions/CppOpts/Main.hs new file mode 100644 index 00000000000..56ad7bfd144 --- /dev/null +++ b/cabal-testsuite/PackageTests/CppOptions/CppOpts/Main.hs @@ -0,0 +1,15 @@ +{-# LANGUAGE CPP #-} + +module Main where + +#ifndef __TESTOPT_CPP__ +#error "Did not get required __TESTOPT_CPP__ from cpp-options" +#endif + +main :: IO () +main = do + -- The value 44 comes from __TESTOPT_CPP__ - see the cabal file. + let secret = __TESTOPT_CPP__ :: Int + if (secret == 44) + then putStrLn ("The secret is " ++ show secret) + else error ("Expected value 44, got " ++ show secret) diff --git a/cabal-testsuite/PackageTests/CppOptions/CppOpts/README.md b/cabal-testsuite/PackageTests/CppOptions/CppOpts/README.md new file mode 100644 index 00000000000..adb776886a0 --- /dev/null +++ b/cabal-testsuite/PackageTests/CppOptions/CppOpts/README.md @@ -0,0 +1,3 @@ +# CppOpts + +This test case asserts that cabal passes `cpp-options` to the C preprocessor when compiling Haskell source files that use the `CPP` language extension. diff --git a/cabal-testsuite/PackageTests/CppOptions/CppOpts/cabal.out b/cabal-testsuite/PackageTests/CppOptions/CppOpts/cabal.out new file mode 100644 index 00000000000..4bc7087362d --- /dev/null +++ b/cabal-testsuite/PackageTests/CppOptions/CppOpts/cabal.out @@ -0,0 +1,10 @@ +# cabal v2-build +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - cpp-opts-0.1 (exe:cpp-opts-exe) (first run) +Configuring executable 'cpp-opts-exe' for cpp-opts-0.1... +Preprocessing executable 'cpp-opts-exe' for cpp-opts-0.1... +Building executable 'cpp-opts-exe' for cpp-opts-0.1... +# cpp-opts cpp-opts-exe +The secret is 44 diff --git a/cabal-testsuite/PackageTests/CppOptions/CppOpts/cabal.project b/cabal-testsuite/PackageTests/CppOptions/CppOpts/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/CppOptions/CppOpts/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/CppOptions/CppOpts/cabal.test.hs b/cabal-testsuite/PackageTests/CppOptions/CppOpts/cabal.test.hs new file mode 100644 index 00000000000..08b1aea22e9 --- /dev/null +++ b/cabal-testsuite/PackageTests/CppOptions/CppOpts/cabal.test.hs @@ -0,0 +1,4 @@ +import Test.Cabal.Prelude +main = cabalTest $ do + cabal "v2-build" ["cpp-opts-exe"] + withPlan $ runPlanExe "cpp-opts" "cpp-opts-exe" [] diff --git a/cabal-testsuite/PackageTests/CppOptions/CppOpts/cpp-opts.cabal b/cabal-testsuite/PackageTests/CppOptions/CppOpts/cpp-opts.cabal new file mode 100644 index 00000000000..9913b86d720 --- /dev/null +++ b/cabal-testsuite/PackageTests/CppOptions/CppOpts/cpp-opts.cabal @@ -0,0 +1,10 @@ +cabal-version: 2.2 +name: cpp-opts +version: 0.1 +build-type: Simple + +executable cpp-opts-exe + main-is: Main.hs + build-depends: base + default-language: Haskell2010 + cpp-options: -D__TESTOPT_CPP__=44 diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/Main.hs b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/Main.hs new file mode 100644 index 00000000000..ec92f1779fa --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/Main.hs @@ -0,0 +1,16 @@ +{-# LANGUAGE ForeignFunctionInterface #-} + +module Main where + +import Foreign.C (CInt (..)) + +foreign import ccall "asmlib.h meaning_of_life_asm" + meaning_of_life_asm :: IO CInt + +main :: IO () +main = do + secret <- meaning_of_life_asm + -- The value 33 comes from meaning_of_life_val - see asm-options in the cabal file. + if (secret == 33) + then putStrLn ("The secret is " ++ show secret) + else error ("Expected value 33, got " ++ show secret) diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/README.md b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/README.md new file mode 100644 index 00000000000..0e7be80fc60 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/README.md @@ -0,0 +1,7 @@ +# ForeignOptsAsm + +This test case asserts that cabal passes `asm-options` to the assembler when compiling assembly source files. + +The test uses `asm-options: -Wa,--defsym,meaning_of_life_val=33` which routes through GHC's `-opta` flag to `gcc`, which then passes `--defsym meaning_of_life_val=33` to the actual GNU assembler. The assembly source file references `meaning_of_life_val` as an immediate operand; if the define is not passed, the assembler will fail with an undefined symbol error. + +This test is skipped on macOS (which uses Apple's assembler, not GNU as) and on non-x86_64/aarch64 architectures. diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/abits/asmlib.h b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/abits/asmlib.h new file mode 100644 index 00000000000..0b373105531 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/abits/asmlib.h @@ -0,0 +1,6 @@ +#ifndef ASMLIB_H +#define ASMLIB_H + +int meaning_of_life_asm(); + +#endif diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/abits/asmlib_aarch64.s b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/abits/asmlib_aarch64.s new file mode 100644 index 00000000000..4d29b50cf54 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/abits/asmlib_aarch64.s @@ -0,0 +1,9 @@ + .text + .globl meaning_of_life_asm + .type meaning_of_life_asm, @function + // meaning_of_life_val must be defined via --defsym from asm-options. + // If asm-options are not passed, the assembler will fail here. +meaning_of_life_asm: + mov w0, #meaning_of_life_val + ret + .size meaning_of_life_asm, .-meaning_of_life_asm diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/abits/asmlib_x86_64.s b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/abits/asmlib_x86_64.s new file mode 100644 index 00000000000..a301c2b41e4 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/abits/asmlib_x86_64.s @@ -0,0 +1,9 @@ + .text + .globl meaning_of_life_asm + .type meaning_of_life_asm, @function + # meaning_of_life_val must be defined via --defsym from asm-options. + # If asm-options are not passed, the assembler will fail here. +meaning_of_life_asm: + movl $meaning_of_life_val, %eax + ret + .size meaning_of_life_asm, .-meaning_of_life_asm diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/cabal.out b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/cabal.out new file mode 100644 index 00000000000..d764348cc9f --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/cabal.out @@ -0,0 +1,10 @@ +# cabal v2-build +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - foreign-opts-asm-0.1 (exe:foreign-opts-asm-exe) (first run) +Configuring executable 'foreign-opts-asm-exe' for foreign-opts-asm-0.1... +Preprocessing executable 'foreign-opts-asm-exe' for foreign-opts-asm-0.1... +Building executable 'foreign-opts-asm-exe' for foreign-opts-asm-0.1... +# foreign-opts-asm foreign-opts-asm-exe +The secret is 33 diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/cabal.project b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/cabal.test.hs b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/cabal.test.hs new file mode 100644 index 00000000000..21f08b035d4 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/cabal.test.hs @@ -0,0 +1,10 @@ +import Test.Cabal.Prelude +import Distribution.System (Arch (X86_64, AArch64), buildArch) + +main = do + skipIfOSX "Apple assembler does not support --defsym" + skipIfWindows "TODO: investigate Windows assembly support" + skipUnlessIO "needs x86_64 or aarch64" (buildArch `elem` [X86_64, AArch64]) + cabalTest $ do + cabal "v2-build" ["foreign-opts-asm-exe"] + withPlan $ runPlanExe "foreign-opts-asm" "foreign-opts-asm-exe" [] diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/foreign-opts-asm.cabal b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/foreign-opts-asm.cabal new file mode 100644 index 00000000000..f5a18a6f895 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsAsm/foreign-opts-asm.cabal @@ -0,0 +1,18 @@ +cabal-version: 3.0 +name: foreign-opts-asm +version: 0.1 +build-type: Simple + +executable foreign-opts-asm-exe + main-is: Main.hs + build-depends: base + default-language: Haskell2010 + include-dirs: abits + if arch(x86_64) + asm-sources: abits/asmlib_x86_64.s + elif arch(aarch64) + asm-sources: abits/asmlib_aarch64.s + -- The value 33 is passed to the assembler via -Wa,--defsym (which routes + -- through gcc into the actual assembler) and used as an immediate operand + -- in the assembly source. + asm-options: -Wa,--defsym,meaning_of_life_val=33 diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/Main.hs b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/Main.hs new file mode 100644 index 00000000000..d462a135061 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/Main.hs @@ -0,0 +1,18 @@ +{-# LANGUAGE ForeignFunctionInterface #-} + +module Main where + +import Foreign.C (CInt (..)) + +-- With ld-options: -Wl,--wrap=meaning_of_life_ld_real, the linker redirects +-- this call to __wrap_meaning_of_life_ld_real, which returns 55. +foreign import ccall "ldlib.h meaning_of_life_ld_real" + meaning_of_life_ld_real :: IO CInt + +main :: IO () +main = do + secret <- meaning_of_life_ld_real + -- The value 55 comes from __wrap_meaning_of_life_ld_real - see ld-options in the cabal file. + if (secret == 55) + then putStrLn ("The secret is " ++ show secret) + else error ("Expected value 55, got " ++ show secret) diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/README.md b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/README.md new file mode 100644 index 00000000000..13cc9b25f43 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/README.md @@ -0,0 +1,7 @@ +# ForeignOptsLd + +This test case asserts that cabal passes `ld-options` to the linker. + +The test uses `ld-options: -Wl,--wrap=meaning_of_life_ld_real` which instructs the GNU linker to redirect all calls to `meaning_of_life_ld_real` to `__wrap_meaning_of_life_ld_real` instead. The real function returns 0; the wrapper function returns 55. If `ld-options` were not passed, the real function would be called and the test would fail with an unexpected value. + +This test is skipped on macOS (which uses Apple's linker, not GNU ld) and on Windows. diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cabal.out b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cabal.out new file mode 100644 index 00000000000..02d1975c005 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cabal.out @@ -0,0 +1,10 @@ +# cabal v2-build +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - foreign-opts-ld-0.1 (exe:foreign-opts-ld-exe) (first run) +Configuring executable 'foreign-opts-ld-exe' for foreign-opts-ld-0.1... +Preprocessing executable 'foreign-opts-ld-exe' for foreign-opts-ld-0.1... +Building executable 'foreign-opts-ld-exe' for foreign-opts-ld-0.1... +# foreign-opts-ld foreign-opts-ld-exe +The secret is 55 diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cabal.project b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cabal.test.hs b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cabal.test.hs new file mode 100644 index 00000000000..e75028d55dd --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cabal.test.hs @@ -0,0 +1,8 @@ +import Test.Cabal.Prelude + +main = do + skipIfOSX "Apple linker does not support --wrap" + skipIfWindows "Windows linker does not support --wrap" + cabalTest $ do + cabal "v2-build" ["foreign-opts-ld-exe"] + withPlan $ runPlanExe "foreign-opts-ld" "foreign-opts-ld-exe" [] diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cbits/ldlib.c b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cbits/ldlib.c new file mode 100644 index 00000000000..67e7972c6b2 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cbits/ldlib.c @@ -0,0 +1,14 @@ +#include "ldlib.h" + +/* The "real" implementation - returns 0, the wrong value. + * With ld-options: -Wl,--wrap=meaning_of_life_ld_real, the linker redirects + * all calls to this function to __wrap_meaning_of_life_ld_real below. */ +int meaning_of_life_ld_real() { + return 0; +} + +/* The wrapper that the linker substitutes in place of the real function. + * Returns 55 - see ld-options in the cabal file. */ +int __wrap_meaning_of_life_ld_real() { + return 55; +} diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cbits/ldlib.h b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cbits/ldlib.h new file mode 100644 index 00000000000..773c3dc6853 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/cbits/ldlib.h @@ -0,0 +1,10 @@ +#ifndef LDLIB_H +#define LDLIB_H + +/* The "real" function; with --wrap, calls to this are redirected by the linker. */ +int meaning_of_life_ld_real(); + +/* The wrapper that the linker calls instead of the real function. */ +int __wrap_meaning_of_life_ld_real(); + +#endif diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/foreign-opts-ld.cabal b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/foreign-opts-ld.cabal new file mode 100644 index 00000000000..741874d0a56 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsLd/foreign-opts-ld.cabal @@ -0,0 +1,15 @@ +cabal-version: 2.2 +name: foreign-opts-ld +version: 0.1 +build-type: Simple + +executable foreign-opts-ld-exe + main-is: Main.hs + build-depends: base + default-language: Haskell2010 + include-dirs: cbits + c-sources: cbits/ldlib.c + -- Redirect calls to meaning_of_life_ld_real to __wrap_meaning_of_life_ld_real. + -- If ld-options are not passed the real function (returning 0) is called instead + -- of the wrapper (returning 55), and the test fails at runtime. + ld-options: -Wl,--wrap=meaning_of_life_ld_real diff --git a/cabal-testsuite/PackageTests/JS/JSPPOptions/README.md b/cabal-testsuite/PackageTests/JS/JSPPOptions/README.md new file mode 100644 index 00000000000..7acb5233aed --- /dev/null +++ b/cabal-testsuite/PackageTests/JS/JSPPOptions/README.md @@ -0,0 +1,3 @@ +# JSPPOptions + +This asserts that cabal passes `jspp-options` to the JavaScript-preprocessor.