diff options
Diffstat (limited to 'Config.hs')
-rw-r--r-- | Config.hs | 144 |
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 | |||
17 | module Config(config) where | ||
18 | |||
19 | import System.Process | ||
20 | import System.Exit | ||
21 | import System.Environment | ||
22 | import System.Directory(createDirectoryIfMissing) | ||
23 | import Data.List(isPrefixOf, intercalate) | ||
24 | import Distribution.Simple.LocalBuildInfo | ||
25 | import Distribution.Simple.Configure | ||
26 | import Distribution.PackageDescription | ||
27 | |||
28 | -- possible additional dependencies for the desired libs (by default gsl lapack) | ||
29 | |||
30 | opts = [ "" -- 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 | ||
42 | testprog 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 | |||
54 | join = intercalate " " | ||
55 | prepend x = unwords . map (x++) . words | ||
56 | |||
57 | check bInfo buildInfo libs fmks = (ExitSuccess ==) `fmap` system (testprog bInfo buildInfo libs fmks) | ||
58 | |||
59 | -- simple test for GSL | ||
60 | gsl 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 | ||
71 | gsl112 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 | |||
83 | checkCommand c = (ExitSuccess ==) `fmap` system c | ||
84 | |||
85 | -- test different configurations until the first one works | ||
86 | try _ _ _ _ [] = return Nothing | ||
87 | try 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 | ||
93 | linkop = "link:" | ||
94 | getUserLink = concatMap (g . drop (length linkop)) . filter (isPrefixOf linkop) | ||
95 | where g = map cs | ||
96 | cs ',' = ' ' | ||
97 | cs x = x | ||
98 | |||
99 | config = do | ||
100 | info <- maybeGetPersistBuildConfig "dist" | ||
101 | case info of | ||
102 | Nothing -> putStrLn "Please run \"cabal clean\" first." >> exitFailure | ||
103 | Just bInfo -> mainOk bInfo | ||
104 | |||
105 | mainOk 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" | ||