Skip to content

Commit 581b73f

Browse files
authored
Merge pull request #82 from tomsmeding/cabal-3.16
Support new Cabal library in Setup.hs (3.12, 3.14, 3.16)
2 parents bbe7404 + 39b1ed7 commit 581b73f

File tree

2 files changed

+116
-29
lines changed

2 files changed

+116
-29
lines changed

Setup.hs

Lines changed: 115 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE DataKinds #-}
23
{-# LANGUAGE QuasiQuotes #-}
34
{-# LANGUAGE TemplateHaskell #-}
45

@@ -33,13 +34,27 @@ import Distribution.PackageDescription.Parse
3334
#if MIN_VERSION_Cabal(3,8,0)
3435
import Distribution.Simple.PackageDescription
3536
#endif
37+
#if MIN_VERSION_Cabal(3,14,0)
38+
-- Note [Cabal 3.14]
39+
--
40+
-- If you change any path stuff, either test that the package still works with
41+
-- Cabal 3.12 or stop declaring support for it in cuda.cabal. (If you do the
42+
-- latter, also remove all of the other conditionals in this file.)
43+
-- Note that supporting old versions of Cabal is useful for being able to run
44+
-- e.g. Accelerate on old GPU clusters, which is nice.
45+
import Distribution.Utils.Path (SymbolicPath, FileOrDir(File, Dir), Lib, Include, Pkg, CWD, makeSymbolicPath, interpretSymbolicPath, makeRelativePathEx)
46+
import qualified Distribution.Types.LocalBuildConfig as LBC
47+
#else
48+
import Data.Kind (Constraint)
49+
#endif
3650

3751
import Control.Exception
3852
import Control.Monad
3953
import Data.Char (isDigit)
4054
import Data.Function
4155
import Data.List
4256
import Data.Maybe
57+
import Data.String (fromString)
4358
import System.Directory
4459
import System.Environment
4560
import System.FilePath
@@ -67,8 +82,9 @@ defaultCUDAInstallPath _ = "/usr/local/cuda" -- windows?
6782
main :: IO ()
6883
main = defaultMainWithHooks customHooks
6984
where
85+
-- Be careful changing flags/paths stuff here; see Note [Cabal 3.14].
7086
readHook get_verbosity a flags = do
71-
getHookedBuildInfo (fromFlag (get_verbosity flags))
87+
getHookedBuildInfo (flagToMaybe (workingDirFlag flags)) (fromFlag (get_verbosity flags))
7288

7389
preprocessors = hookedPreProcessors simpleUserHooks
7490

@@ -87,14 +103,16 @@ main = defaultMainWithHooks customHooks
87103
, preReg = readHook regVerbosity
88104
, preUnreg = readHook regVerbosity
89105
, postConf = postConfHook
90-
, hookedPreProcessors = ("chs", ppC2hs) : filter (\x -> fst x /= "chs") preprocessors
106+
, hookedPreProcessors = (fromString "chs", ppC2hs) : filter (\x -> fst x /= fromString "chs") preprocessors
91107
}
92108

93109
-- The hook just loads the HookedBuildInfo generated by postConfHook,
94110
-- unless there is user-provided info that overwrites it.
95111
--
96112
preBuildHook :: Args -> BuildFlags -> IO HookedBuildInfo
97-
preBuildHook _ flags = getHookedBuildInfo $ fromFlag $ buildVerbosity flags
113+
preBuildHook _ flags = getHookedBuildInfo cwd verbosity
114+
where cwd = flagToMaybe (workingDirFlag flags)
115+
verbosity = fromFlag (buildVerbosity flags)
98116

99117
-- The hook scans system in search for CUDA Toolkit. If the toolkit is not
100118
-- found, an error is raised. Otherwise the toolkit location is used to
@@ -103,12 +121,14 @@ main = defaultMainWithHooks customHooks
103121
postConfHook :: Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()
104122
postConfHook args flags pkg_descr lbi = do
105123
let
124+
cwd = flagToMaybe (workingDirFlag flags)
106125
verbosity = fromFlagOrDefault normal (configVerbosity flags)
107126
profile = fromFlagOrDefault False (configProfLib flags)
108127
currentPlatform = hostPlatform lbi
109128
compilerId_ = compilerId (compiler lbi)
110129
--
111130
generateAndStoreBuildInfo
131+
cwd
112132
verbosity
113133
profile
114134
currentPlatform
@@ -118,7 +138,7 @@ main = defaultMainWithHooks customHooks
118138
generatedBuildInfoFilePath
119139
validateLinker verbosity currentPlatform $ withPrograms lbi
120140
--
121-
actualBuildInfoToUse <- getHookedBuildInfo verbosity
141+
actualBuildInfoToUse <- getHookedBuildInfo cwd verbosity
122142
let pkg_descr' = updatePackageDescription actualBuildInfoToUse pkg_descr
123143
postConf simpleUserHooks args flags pkg_descr' lbi
124144

@@ -131,27 +151,29 @@ escBackslash (f:fs) = f : escBackslash fs
131151
-- visible to underlying build tools.
132152
--
133153
libraryBuildInfo
134-
:: Verbosity
154+
:: Maybe CWDPath
155+
-> Verbosity
135156
-> Bool
136157
-> FilePath
137158
-> Platform
138159
-> Version
139-
-> [FilePath]
140-
-> [FilePath]
160+
-> [ExtraLibsPath]
161+
-> [ExtraIncludesPath]
141162
-> IO HookedBuildInfo
142-
libraryBuildInfo verbosity profile installPath platform@(Platform arch os) ghcVersion extraLibs extraIncludes = do
163+
libraryBuildInfo cwd verbosity profile installPath platform@(Platform arch os) ghcVersion extraLibs extraIncludes = do
143164
let
144-
libraryPaths = cudaLibraryPaths platform installPath ++ extraLibs
145-
includePaths = cudaIncludePath platform installPath : extraIncludes
165+
-- Be careful changing flags/paths stuff here; see Note [Cabal 3.14].
166+
libraryPaths = map makeSymbolicPath (cudaLibraryPaths platform installPath) ++ extraLibs
167+
includePaths = makeSymbolicPath (cudaIncludePath platform installPath) : extraIncludes
146168

147169
takeFirstExisting paths = do
148-
existing <- filterM doesDirectoryExist libraryPaths
170+
existing <- filterM (doesDirectoryExist . interpretSymbolicPath cwd) libraryPaths
149171
case existing of
150172
(p0:_) -> return p0
151173
_ -> die' verbosity $ "Could not find path: " ++ show paths
152174

153175
-- This can only be defined once, so take the first path which exists
154-
canonicalLibraryPath <- takeFirstExisting libraryPaths
176+
canonicalLibraryPath <- interpretSymbolicPath cwd <$> takeFirstExisting libraryPaths
155177

156178
let
157179
-- OS-specific escaping for -D path defines
@@ -163,16 +185,16 @@ libraryBuildInfo verbosity profile installPath platform@(Platform arch os) ghcVe
163185
extraLibDirs' = libraryPaths
164186
ccOptions' = [ "-DCUDA_INSTALL_PATH=\"" ++ escDefPath installPath ++ "\""
165187
, "-DCUDA_LIBRARY_PATH=\"" ++ escDefPath canonicalLibraryPath ++ "\""
166-
] ++ map ("-I" ++) includePaths
167-
ldOptions' = map ("-L" ++) libraryPaths
188+
] ++ map (("-I" ++) . interpretSymbolicPath cwd) includePaths
189+
ldOptions' = map (("-L" ++) . interpretSymbolicPath cwd) libraryPaths
168190
ghcOptions = map ("-optc"++) ccOptions'
169191
++ map ("-optl"++) ldOptions'
170192
++ if os /= Windows && not profile
171-
then map ("-optl-Wl,-rpath,"++) extraLibDirs'
193+
then map (("-optl-Wl,-rpath," ++) . interpretSymbolicPath cwd) extraLibDirs'
172194
else []
173195
extraLibs' = cudaLibraries platform
174-
frameworks' = [ "CUDA" | os == OSX ]
175-
frameworkDirs' = [ "/Library/Frameworks" | os == OSX ]
196+
frameworks' = [ makeRelativePathEx "CUDA" | os == OSX ]
197+
frameworkDirs' = [ makeSymbolicPath "/Library/Frameworks" | os == OSX ]
176198

177199
-- options or c2hs
178200
archFlag = case arch of
@@ -427,17 +449,18 @@ windowsLinkerBugMsg ldPath = printf (unlines msg) windowsHelpPage ldPath
427449
-- Runs CUDA detection procedure and stores .buildinfo to a file.
428450
--
429451
generateAndStoreBuildInfo
430-
:: Verbosity
452+
:: Maybe CWDPath
453+
-> Verbosity
431454
-> Bool
432455
-> Platform
433456
-> CompilerId
434-
-> [FilePath]
435-
-> [FilePath]
457+
-> [ExtraLibsPath]
458+
-> [ExtraIncludesPath]
436459
-> FilePath
437460
-> IO ()
438-
generateAndStoreBuildInfo verbosity profile platform (CompilerId _ghcFlavor ghcVersion) extraLibs extraIncludes path = do
461+
generateAndStoreBuildInfo cwd verbosity profile platform (CompilerId _ghcFlavor ghcVersion) extraLibs extraIncludes path = do
439462
installPath <- findCUDAInstallPath verbosity platform
440-
hbi <- libraryBuildInfo verbosity profile installPath platform ghcVersion extraLibs extraIncludes
463+
hbi <- libraryBuildInfo cwd verbosity profile installPath platform ghcVersion extraLibs extraIncludes
441464
storeHookedBuildInfo verbosity path hbi
442465

443466
storeHookedBuildInfo
@@ -622,21 +645,22 @@ findProgram verbosity prog = do
622645
-- (generated one should be always present, as it is created in the post-conf step)
623646
--
624647
getHookedBuildInfo
625-
:: Verbosity
648+
:: Maybe CWDPath
649+
-> Verbosity
626650
-> IO HookedBuildInfo
627-
getHookedBuildInfo verbosity = do
628-
doesCustomBuildInfoExists <- doesFileExist customBuildInfoFilePath
651+
getHookedBuildInfo cwd verbosity = do
652+
doesCustomBuildInfoExists <- doesFileExist (customBuildInfoFilePath)
629653
if doesCustomBuildInfoExists
630654
then do
631655
notice verbosity $ printf "The user-provided buildinfo from file %s will be used. To use default settings, delete this file.\n" customBuildInfoFilePath
632-
readHookedBuildInfo verbosity customBuildInfoFilePath
656+
readHookedBuildInfoWithCWD verbosity cwd (makeSymbolicPath customBuildInfoFilePath)
633657
else do
634658
doesGeneratedBuildInfoExists <- doesFileExist generatedBuildInfoFilePath
635659
if doesGeneratedBuildInfoExists
636660
then do
637661
notice verbosity $ printf "Using build information from '%s'.\n" generatedBuildInfoFilePath
638662
notice verbosity $ printf "Provide a '%s' file to override this behaviour.\n" customBuildInfoFilePath
639-
readHookedBuildInfo verbosity generatedBuildInfoFilePath
663+
readHookedBuildInfoWithCWD verbosity cwd (makeSymbolicPath generatedBuildInfoFilePath)
640664
else
641665
die' verbosity $ printf "Unexpected failure. Neither the default %s nor custom %s exist.\n" generatedBuildInfoFilePath customBuildInfoFilePath
642666

@@ -672,7 +696,7 @@ ppC2hs bi lbi
672696
getCppOptions :: BuildInfo -> LocalBuildInfo -> [String]
673697
getCppOptions bi lbi
674698
= hcDefines (compiler lbi)
675-
++ ["-I" ++ dir | dir <- includeDirs bi]
699+
++ ["-I" ++ interpretSymbolicPath (lbiCWD lbi) dir | dir <- includeDirs bi]
676700
++ [opt | opt@('-':c:_) <- ccOptions bi, c `elem` "DIU"]
677701

678702
hcDefines :: Compiler -> [String]
@@ -706,3 +730,66 @@ die' :: Verbosity -> String -> IO a
706730
die' _ = die
707731
#endif
708732

733+
734+
-- Compatibility across Cabal 3.14 symbolic paths.
735+
-- If we want to drop pre-Cabal-3.14 compatibility at some point, this should all be merged in above.
736+
737+
workingDirFlag :: HasCommonFlags flags => flags -> Flag CWDPath
738+
lbiCWD :: LocalBuildInfo -> Maybe CWDPath
739+
740+
#if MIN_VERSION_Cabal(3,14,0)
741+
type ExtraLibsPath = SymbolicPath Pkg ('Dir Lib)
742+
type ExtraIncludesPath = SymbolicPath Pkg ('Dir Include)
743+
type CWDPath = SymbolicPath CWD ('Dir Pkg)
744+
745+
regVerbosity :: RegisterFlags -> Flag Verbosity
746+
regVerbosity = setupVerbosity . registerCommonFlags
747+
748+
workingDirFlag = setupWorkingDir . getCommonFlags
749+
750+
lbiCWD = flagToMaybe . setupWorkingDir . configCommonFlags . LBC.configFlags . LBC.packageBuildDescr . localBuildDescr
751+
752+
-- makeSymbolicPath is an actual useful function in Cabal 3.14
753+
-- makeRelativePathEx is an actual useful function in Cabal 3.14
754+
-- interpretSymbolicPath is an actual useful function in Cabal 3.14
755+
756+
class HasCommonFlags flags where getCommonFlags :: flags -> CommonSetupFlags
757+
instance HasCommonFlags BuildFlags where getCommonFlags = buildCommonFlags
758+
instance HasCommonFlags CleanFlags where getCommonFlags = cleanCommonFlags
759+
instance HasCommonFlags ConfigFlags where getCommonFlags = configCommonFlags
760+
instance HasCommonFlags CopyFlags where getCommonFlags = copyCommonFlags
761+
instance HasCommonFlags InstallFlags where getCommonFlags = installCommonFlags
762+
instance HasCommonFlags HscolourFlags where getCommonFlags = hscolourCommonFlags
763+
instance HasCommonFlags HaddockFlags where getCommonFlags = haddockCommonFlags
764+
instance HasCommonFlags RegisterFlags where getCommonFlags = registerCommonFlags
765+
766+
readHookedBuildInfoWithCWD :: Verbosity -> Maybe CWDPath -> SymbolicPath Pkg 'File -> IO HookedBuildInfo
767+
readHookedBuildInfoWithCWD = readHookedBuildInfo
768+
#else
769+
type ExtraLibsPath = FilePath
770+
type ExtraIncludesPath = FilePath
771+
type CWDPath = ()
772+
773+
-- regVerbosity is still present as an actual field in Cabal 3.12
774+
775+
workingDirFlag _ = NoFlag
776+
777+
lbiCWD _ = Nothing
778+
779+
makeSymbolicPath :: FilePath -> FilePath
780+
makeSymbolicPath = id
781+
782+
makeRelativePathEx :: FilePath -> FilePath
783+
makeRelativePathEx = id
784+
785+
interpretSymbolicPath :: Maybe CWDPath -> FilePath -> FilePath
786+
interpretSymbolicPath _ = id
787+
788+
type HasCommonFlags flags = () :: Constraint
789+
getCommonFlags :: flags -> ()
790+
getCommonFlags _ = ()
791+
792+
readHookedBuildInfoWithCWD :: Verbosity -> Maybe CWDPath -> FilePath -> IO HookedBuildInfo
793+
readHookedBuildInfoWithCWD verb _ path = readHookedBuildInfo verb path
794+
#endif
795+

cuda.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Extra-source-files:
6868
custom-setup
6969
setup-depends:
7070
base >= 4.7 && < 5
71-
, Cabal >= 1.24 && < 3.11
71+
, Cabal >= 1.24 && < 3.17
7272
, directory >= 1.0
7373
, filepath >= 1.0
7474

0 commit comments

Comments
 (0)