summaryrefslogtreecommitdiff
path: root/Config.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Config.hs')
-rw-r--r--Config.hs144
1 files changed, 144 insertions, 0 deletions
diff --git a/Config.hs b/Config.hs
new file mode 100644
index 0000000..d76a6a2
--- /dev/null
+++ b/Config.hs
@@ -0,0 +1,144 @@
1{-
2 GSL and LAPACK may require auxiliary libraries which depend on OS,
3 distribution, and implementation. This script tries to to find out
4 the correct link command for your system.
5 Suggestions and contributions are welcome.
6
7 By default we try to link -lgsl -llapack. This works in ubuntu/debian,
8 both with and without ATLAS.
9 If this fails we try different sets of additional libraries which are
10 known to work in some systems.
11
12 The desired libraries can also be explicitly given by the user using cabal
13 flags (e.g., -fmkl, -faccelerate) or --configure-option=link:lib1,lib2,lib3,...
14
15-}
16
17module Config(config) where
18
19import System.Process
20import System.Exit
21import System.Environment
22import System.Directory(createDirectoryIfMissing)
23import Data.List(isPrefixOf, intercalate)
24import Distribution.Simple.LocalBuildInfo
25import Distribution.Simple.Configure
26import Distribution.PackageDescription
27
28-- possible additional dependencies for the desired libs (by default gsl lapack)
29
30opts = [ "" -- Ubuntu/Debian
31 , "blas"
32 , "blas cblas"
33 , "cblas"
34 , "gslcblas"
35 , "blas gslcblas"
36 , "f77blas"
37 , "f77blas cblas atlas gcc_s" -- Arch Linux (older version of atlas-lapack)
38 , "blas gslcblas gfortran" -- Arch Linux with normal blas and lapack
39 ]
40
41-- compile a simple program with symbols from GSL and LAPACK with the given libs
42testprog bInfo buildInfo libs fmks =
43 "echo \"#include <gsl/gsl_sf_gamma.h>\nint main(){zgesvd_(); gsl_sf_gamma(5);}\""
44 ++" > " ++ (buildDir bInfo) ++ "/dummy.c; gcc "
45 ++ (join $ ccOptions buildInfo) ++ " "
46 ++ (join $ cppOptions buildInfo) ++ " "
47 ++ (join $ map ("-I"++) $ includeDirs buildInfo) ++ " "
48 ++ (buildDir bInfo) ++ "/dummy.c -o "
49 ++ (buildDir bInfo) ++ "/dummy "
50 ++ (join $ map ("-L"++) $ extraLibDirs buildInfo) ++ " "
51 ++ (prepend "-l" $ libs) ++ " "
52 ++ (prepend "-framework " fmks) ++ " > /dev/null 2> /dev/null"
53
54join = intercalate " "
55prepend x = unwords . map (x++) . words
56
57check bInfo buildInfo libs fmks = (ExitSuccess ==) `fmap` system (testprog bInfo buildInfo libs fmks)
58
59-- simple test for GSL
60gsl bInfo buildInfo = "echo \"#include <gsl/gsl_sf_gamma.h>\nint main(){gsl_sf_gamma(5);}\""
61 ++" > " ++ (buildDir bInfo) ++ "/dummy.c; gcc "
62 ++ (join $ ccOptions buildInfo) ++ " "
63 ++ (join $ cppOptions buildInfo) ++ " "
64 ++ (join $ map ("-I"++) $ includeDirs buildInfo) ++ " "
65 ++ (buildDir bInfo) ++ "/dummy.c -o "
66 ++ (buildDir bInfo) ++ "/dummy "
67 ++ (join $ map ("-L"++) $ extraLibDirs buildInfo) ++ " -lgsl -lgslcblas"
68 ++ " > /dev/null 2> /dev/null"
69
70-- test for gsl >= 1.12
71gsl112 bInfo buildInfo =
72 "echo \"#include <gsl/gsl_sf_exp.h>\nint main(){gsl_sf_exprel_n_CF_e(1,1,0);}\""
73 ++" > " ++ (buildDir bInfo) ++ "/dummy.c; gcc "
74 ++ (buildDir bInfo) ++ "/dummy.c "
75 ++ (join $ ccOptions buildInfo) ++ " "
76 ++ (join $ cppOptions buildInfo) ++ " "
77 ++ (join $ map ("-I"++) $ includeDirs buildInfo)
78 ++" -o " ++ (buildDir bInfo) ++ "/dummy "
79 ++ (join $ map ("-L"++) $ extraLibDirs buildInfo) ++ " -lgsl -lgslcblas"
80 ++ " > /dev/null 2> /dev/null"
81
82
83checkCommand c = (ExitSuccess ==) `fmap` system c
84
85-- test different configurations until the first one works
86try _ _ _ _ [] = return Nothing
87try l i b f (opt:rest) = do
88 ok <- check l i (b ++ " " ++ opt) f
89 if ok then return (Just opt)
90 else try l i b f rest
91
92-- read --configure-option=link:lib1,lib2,lib3,etc
93linkop = "link:"
94getUserLink = concatMap (g . drop (length linkop)) . filter (isPrefixOf linkop)
95 where g = map cs
96 cs ',' = ' '
97 cs x = x
98
99config = do
100 info <- maybeGetPersistBuildConfig "dist"
101 case info of
102 Nothing -> putStrLn "Please run \"cabal clean\" first." >> exitFailure
103 Just bInfo -> mainOk bInfo
104
105mainOk bInfo = do
106 putStr "Checking foreign libraries..."
107 args <- getArgs
108
109 let Just lib = library . localPkgDescr $ bInfo
110 buildInfo = libBuildInfo lib
111 base = unwords . extraLibs $ buildInfo
112 fwks = unwords . frameworks $ buildInfo
113 auxpref = getUserLink args
114
115 -- We extract the desired libs from hmatrix.cabal (using a cabal flags)
116 -- and from a posible --configure-option=link:lib1,lib2,lib3
117 -- by default the desired libs are gsl lapack.
118
119 let pref = if null (words (base ++ " " ++ auxpref)) then "gsl lapack" else auxpref
120 fullOpts = map ((pref++" ")++) opts
121
122 -- create the build directory (used for tmp files) if necessary
123 createDirectoryIfMissing True $ buildDir bInfo
124
125 r <- try bInfo buildInfo base fwks fullOpts
126 case r of
127 Nothing -> do
128 putStrLn " FAIL"
129 g <- checkCommand $ gsl bInfo buildInfo
130 if g
131 then putStrLn " *** Sorry, I can't link LAPACK."
132 else putStrLn " *** Sorry, I can't link GSL."
133 putStrLn " *** Please make sure that the appropriate -dev packages are installed."
134 putStrLn " *** You can also specify the required libraries using"
135 putStrLn " *** cabal install hmatrix --configure-option=link:lib1,lib2,lib3,etc."
136 writeFile "hmatrix.buildinfo" ("buildable: False\n")
137 Just ops -> do
138 putStrLn " OK"
139 g <- checkCommand $ gsl112 bInfo buildInfo
140 writeFile "hmatrix.buildinfo" $ "extra-libraries: " ++
141 ops ++ "\n" ++
142 if g
143 then ""
144 else "cc-options: -DGSL110\n"