diff --git a/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/Basic.hs b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/Basic.hs new file mode 100644 index 00000000000..d8690293fff --- /dev/null +++ b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/Basic.hs @@ -0,0 +1,10 @@ +module Basic where + +funcs :: (a -> b -> c) -> ((a -> b -> c) -> a -> b -> c) -> b -> a -> c +funcs f g = \a b -> (g f) b a + +name :: String +name = "Basic" + +number :: Integer +number = 8 diff --git a/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/basic.cabal b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/basic.cabal new file mode 100644 index 00000000000..90f2414bc6a --- /dev/null +++ b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/basic.cabal @@ -0,0 +1,10 @@ +cabal-version: >= 1.10 +name: basic +version: 0.1 +build-type: Simple + +library + default-language: Haskell2010 + build-depends: base + exposed-modules: + Basic diff --git a/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/cabal.project b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/cabal.project new file mode 100644 index 00000000000..6b9fac75bce --- /dev/null +++ b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/cabal.project @@ -0,0 +1 @@ +packages: basic diff --git a/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.out b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.out new file mode 100644 index 00000000000..fa5cb34ec0e --- /dev/null +++ b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.out @@ -0,0 +1,26 @@ +# cabal v2-install +Wrote tarball sdist to /cabal.dist/work/./basic/../dist/sdist/basic-0.1.tar.gz +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - basic-0.1 (lib) (requires build) +Configuring library for basic-0.1.. +Preprocessing library for basic-0.1.. +Building library for basic-0.1.. +Installing library in +# cabal v2-install +Wrote tarball sdist to /cabal.dist/work/./basic/../dist/sdist/basic-0.1.tar.gz +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - basic-0.1 (lib) (requires build) +Configuring library for basic-0.1.. +Preprocessing library for basic-0.1.. +Building library for basic-0.1.. +Installing library in +# cabal v2-install +Wrote tarball sdist to /cabal.dist/work/./basic/../dist/sdist/basic-0.1.tar.gz +Resolving dependencies... +# cabal v2-install +Wrote tarball sdist to /cabal.dist/work/./basic/../dist/sdist/basic-0.1.tar.gz +Resolving dependencies... diff --git a/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.test.hs b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.test.hs new file mode 100644 index 00000000000..04eccaffaa4 --- /dev/null +++ b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.test.hs @@ -0,0 +1,97 @@ +import Test.Cabal.Prelude + +-- This test ensures the following fix holds: +-- > Fix project-local build flags being ignored. +-- > +-- > I noticed that running ‘cabal install’ with two separate sets of dynamic / +-- > static build flags (e.g. one with none, and one with ‘--enable-shared +-- > --enable-executable-dynamic --disable-library-vanilla’) produced packages with +-- > the same hash, instead of different hashes. +-- > +-- > After debugging this issue I found that this command (with no explicit cabal +-- > project file) was resulting in these build configuration flags being ignored, +-- > because in ProjectPlanning.hs, the sdist was not considered a local package, so +-- > the (non-shared) local-package-only configuration was being dropped. +-- > +-- > This fix ensures that these command-line arguments properly make it through to +-- > where they belong in cases like this. +-- +-- Basically, take a simple package, build it under two sets of build flags: +-- > (nothing) +-- > --enable-shared --enable-executable-dynamic --disable-library-vanilla +-- +-- And ensure that whereas before they produced the same hash, now the package +-- hashes produced are different. (And also supplementarily ensure that +-- re-running the same build with the same flags a second time produces a +-- deterministic hash too; the hash should differ only when we change these +-- flags.) +-- +-- Based on the UniqueIPID test. + +import Control.Monad (forM, foldM_) +import Data.List (isPrefixOf, tails) + +data Linking = Static | Dynamic deriving (Eq, Ord, Show) + +links :: [Linking] +links = [Static, Dynamic] + +linkConfigFlags :: Linking -> [String] +linkConfigFlags Static = + [ + ] +linkConfigFlags Dynamic = + [ + "--enable-shared", + "--enable-executable-dynamic", + "--disable-library-vanilla" + ] + +lrun :: [Linking] +lrun = [Static, Dynamic, Static, Dynamic] + +main = cabalTest $ do + withPackageDb $ do + -- Phase 1: get 4 hashes according to config flags. + results <- forM (zip [0..] lrun) $ \(idx, linking) -> do + withDirectory "basic" $ do + withSourceCopyDir ("basic" ++ show idx) $ do + cwd <- fmap testSourceCopyDir getTestEnv + -- (Now do ‘cd ..’, since withSourceCopyDir made our previous + -- previous such withDirectories now accumulate to be + -- relative to setup.dist/basic0, not testSourceDir + -- (see 'testCurrentDir').) + withDirectory ".." $ do + packageEnv <- ( ("basic" ++ show idx ++ ".env")) . testWorkDir <$> getTestEnv + cabal "v2-install" $ ["--disable-deterministic", "--lib", "--package-env=" ++ packageEnv] ++ linkConfigFlags linking ++ ["basic"] + let exIPID s = takeWhile (/= '\n') . head . filter ("basic-0.1-" `isPrefixOf`) $ tails s + hashedIpid <- exIPID <$> liftIO (readFile packageEnv) + return $ ((idx, linking), hashedIpid) + -- Phase 2: make sure we have different hashes iff we have different config flags. + -- In particular make sure the dynamic config flags weren't silently + -- dropped and ignored, since this is the bug that prompted this test. + (\step -> foldM_ step (const $ return ()) results) $ \acc x -> do + acc x + return $ \future -> acc future >> do + let + ((thisIdx, thisLinking), thisHashedIpid) = x + ((futureIdx, futureLinking), futureHashedIpid) = future + when ((thisHashedIpid == futureHashedIpid) /= (thisLinking == futureLinking)) $ do + assertFailure . unlines $ + if thisLinking /= futureLinking + then + -- What we are primarily concerned with testing + -- here. + [ + "Error: static and dynamic config flags produced an IPID with the same hash; were the dynamic flags silently dropped?", + "\thashed IPID: " ++ thisHashedIpid + ] + else + -- Help test our test can also make equal + -- hashes. + [ + "Error: config flags were equal, yet a different IPID hash was produced.", + "\thashed IPID 1 : " ++ thisHashedIpid, + "\thashed IPID 2 : " ++ futureHashedIpid, + "\tlinking flags : " ++ show thisLinking + ]