Skip to content

Commit 3a9830b

Browse files
committed
Check for duplicate files generated by configure and shipped with the package.
1 parent af49513 commit 3a9830b

File tree

1 file changed

+50
-2
lines changed

1 file changed

+50
-2
lines changed

Cabal/Distribution/Simple/Configure.hs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
{-# LANGUAGE RankNTypes #-}
55
{-# LANGUAGE RecordWildCards #-}
66
{-# LANGUAGE ScopedTypeVariables #-}
7+
{-# LANGUAGE CPP #-}
78

89
-----------------------------------------------------------------------------
910
-- |
@@ -112,17 +113,19 @@ import qualified Distribution.Simple.HaskellSuite as HaskellSuite
112113

113114
import Control.Exception
114115
( ErrorCall, Exception, evaluate, throw, throwIO, try )
116+
import Control.Monad ( forM, forM_ )
115117
import Distribution.Compat.Binary ( decodeOrFailIO, encode )
116118
import Data.ByteString.Lazy (ByteString)
117119
import qualified Data.ByteString as BS
118120
import qualified Data.ByteString.Lazy.Char8 as BLC8
119121
import Data.List
120-
( (\\), partition, inits, stripPrefix )
122+
( (\\), partition, inits, stripPrefix, intersect )
121123
import Data.Either
122124
( partitionEithers )
123125
import qualified Data.Map as Map
124126
import System.Directory
125-
( doesFileExist, createDirectoryIfMissing, getTemporaryDirectory )
127+
( doesFileExist, createDirectoryIfMissing, getTemporaryDirectory
128+
, removeFile)
126129
import System.FilePath
127130
( (</>), isAbsolute, takeDirectory )
128131
import qualified System.Info
@@ -137,6 +140,18 @@ import Text.PrettyPrint
137140
import Distribution.Compat.Environment ( lookupEnv )
138141
import Distribution.Compat.Exception ( catchExit, catchIO )
139142

143+
144+
#if !MIN_VERSION_directory(1,2,5)
145+
import System.Directory (getDirectoryContents)
146+
listDirectory :: FilePath -> IO [FilePath]
147+
listDirectory path =
148+
(filter f) <$> (getDirectoryContents path)
149+
where f filename = filename /= "." && filename /= ".."
150+
#else
151+
import System.Directory (listDirectory)
152+
#endif
153+
154+
140155
type UseExternalInternalDeps = Bool
141156

142157
-- | The errors that can be thrown when reading the @setup-config@ file.
@@ -1647,9 +1662,42 @@ checkForeignDeps pkg lbi verbosity =
16471662
allLibs = collectField PD.extraLibs
16481663

16491664
ifBuildsWith headers args success failure = do
1665+
checkDuplicateHeaders
16501666
ok <- builds (makeProgram headers) args
16511667
if ok then success else failure
16521668

1669+
-- ensure that there is only one header with a given name
1670+
-- in either the generated (most likely by `configure`)
1671+
-- dist/build directory or in the source directory.
1672+
--
1673+
-- if it exists in both, we'll remove the one in the source
1674+
-- directory, as the generated should take precedence.
1675+
--
1676+
-- C compilers like to prefer source local relative
1677+
-- includes, as such providing the compiler with -I search
1678+
-- paths is ignored if the included file can be found
1679+
-- relative to the including file. As such we need to take
1680+
-- drastic measures and delete the offending file in the
1681+
-- source directory.
1682+
checkDuplicateHeaders = do
1683+
let relIncDirs = filter (not . isAbsolute) (collectField PD.includeDirs)
1684+
isHeader = isSuffixOf ".h"
1685+
genHeaders <- forM relIncDirs $ \dir ->
1686+
fmap (dir </>) . filter isHeader <$> listDirectory (buildDir lbi </> dir)
1687+
`catchIO` (\_ -> return [])
1688+
srcHeaders <- forM relIncDirs $ \dir ->
1689+
fmap (dir </>) . filter isHeader <$> listDirectory (baseDir lbi </> dir)
1690+
`catchIO` (\_ -> return [])
1691+
let commonHeaders = concat genHeaders `intersect` concat srcHeaders
1692+
forM_ commonHeaders $ \hdr -> do
1693+
warn verbosity $ "Duplicate header found in "
1694+
++ (buildDir lbi </> hdr)
1695+
++ " and "
1696+
++ (baseDir lbi </> hdr)
1697+
++ "; removing "
1698+
++ (baseDir lbi </> hdr)
1699+
removeFile (baseDir lbi </> hdr)
1700+
16531701
findOffendingHdr =
16541702
ifBuildsWith allHeaders ccArgs
16551703
(return Nothing)

0 commit comments

Comments
 (0)