-
Notifications
You must be signed in to change notification settings - Fork 23
/
Setup.hs
129 lines (120 loc) · 6.19 KB
/
Setup.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import Data.ProtoLens.Setup
import Distribution.PackageDescription
import Distribution.Simple
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Setup
import Distribution.Simple.Utils
import Distribution.System
import Distribution.Verbosity
import System.Environment
concordiumLibs :: [String]
concordiumLibs =
[ "concordium_base",
"sha_2"
]
type WithEnvAndVerbosity = [(String, String)] -> Verbosity -> IO ()
-- Add features that should be enabled for the rust-src to the end of options.
addFeatures :: [String] -> [String]
addFeatures opts = opts ++ ["--features", "concordium_base/ffi"]
-- | In linux, we will produce two kind of builds:
-- - Static with musl: the rust libraries will only build static artifacts. Intended to be used inside alpine to produce a static binary.
-- - With glibc: Normal compilation. Rust will produce static and dynamic artifacts.
--
-- The first argument chooses whether to build statically with musl or not.
linuxBuild :: Bool -> WithEnvAndVerbosity
linuxBuild True env verbosity = do
noticeNoWrap verbosity "Static linking."
-- the target-feature=-crt-static is needed so that C symbols are not included in the generated rust libraries. For more information check https://rust-lang.github.io/rfcs/1721-crt-static.html
rawSystemExitWithEnv
verbosity
"cargo"
(addFeatures ["build", "--release", "--manifest-path", "rust-src/Cargo.toml", "--target", "x86_64-unknown-linux-musl"])
(("RUSTFLAGS", "-C target-feature=-crt-static") : env)
let copyLib lib = do
let source = "../rust-src/target/x86_64-unknown-linux-musl/release/lib" ++ lib ++ ".a"
target = "./lib/lib" ++ lib ++ ".a"
rawSystemExit verbosity "ln" ["-s", "-f", source, target]
noticeNoWrap verbosity $ "Linked: " ++ target ++ " -> " ++ source
mapM_ copyLib concordiumLibs
linuxBuild False env verbosity = do
noticeNoWrap verbosity "Dynamic linking."
rawSystemExitWithEnv verbosity "cargo" (addFeatures ["build", "--release", "--manifest-path", "rust-src/Cargo.toml"]) env
let copyLib lib = do
let source = "../rust-src/target/release/lib" ++ lib
target = "./lib/lib" ++ lib
rawSystemExit verbosity "ln" ["-s", "-f", source ++ ".a", target ++ ".a"]
rawSystemExit verbosity "ln" ["-s", "-f", source ++ ".so", target ++ ".so"]
noticeNoWrap verbosity $ "Linked: " ++ target ++ " -> " ++ source
notice verbosity "Linking libraries to ./lib"
mapM_ copyLib concordiumLibs
windowsBuild :: WithEnvAndVerbosity
windowsBuild env verbosity = do
let copyLib lib = do
-- We delete the static library if present to ensure that we only link with the
-- dynamic library.
rawSystemExit verbosity "rm" ["-f", "./lib/lib" ++ lib ++ ".a"]
rawSystemExit verbosity "cp" ["-u", "rust-src/target/release/" ++ lib ++ ".dll", "./lib/"]
notice verbosity $ "Copied " ++ lib ++ "."
rawSystemExitWithEnv verbosity "cargo" (addFeatures ["build", "--release", "--manifest-path", "rust-src/Cargo.toml"]) env
notice verbosity "Copying libraries to ./lib"
mapM_ copyLib concordiumLibs
-- | On Mac, we will delete the dynamic artifacts if we want to create a static binary.
--
-- The flag tells whether we want a static compilation or not.
osxBuild :: Bool -> WithEnvAndVerbosity
osxBuild static env verbosity = do
let copyLib lib = do
if static
then do
let source = "../rust-src/target/release/lib" ++ lib ++ ".a"
let target = "./lib/lib" ++ lib ++ ".a"
others = "./lib/lib" ++ lib ++ ".dylib"
rawSystemExit verbosity "rm" ["-f", others]
rawSystemExit verbosity "ln" ["-s", "-f", source, target]
noticeNoWrap verbosity $ "Linked: " ++ target ++ " -> " ++ source
noticeNoWrap verbosity $ "Removed: " ++ others
else do
let source = "../rust-src/target/release/lib" ++ lib ++ ".dylib"
let others = "./lib/lib" ++ lib ++ ".a"
target = "./lib/lib" ++ lib ++ ".dylib"
rawSystemExit verbosity "rm" ["-f", others]
rawSystemExit verbosity "ln" ["-s", "-f", source, target]
noticeNoWrap verbosity $ "Linked: " ++ target ++ " -> " ++ source
noticeNoWrap verbosity $ "Removed: " ++ others
rawSystemExitWithEnv verbosity "cargo" (addFeatures ["build", "--release", "--manifest-path", "rust-src/Cargo.toml"]) env
notice verbosity "Linking libraries to ./lib"
mapM_ copyLib concordiumLibs
makeRust :: Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()
makeRust _ flags _ lbi = do
let verbosity = fromFlag $ configVerbosity flags
staticLinking = Just True == lookupFlagAssignment (mkFlagName "static") (flagAssignment lbi)
build = case buildOS of
Windows -> windowsBuild
OSX -> osxBuild staticLinking
Linux -> linuxBuild staticLinking
env <- getEnvironment
rawSystemExit verbosity "mkdir" ["-p", "./lib"]
build env verbosity
-- | On Windows, copy the DLL files to the binary install directory. This is to ensure that they
-- are accessible when running the binaries, tests and benchmarks.
copyDlls :: Args -> CopyFlags -> PackageDescription -> LocalBuildInfo -> IO ()
copyDlls _ flags pkgDescr lbi = case buildOS of
Windows -> do
let installDirs = absoluteComponentInstallDirs pkgDescr lbi (localUnitId lbi) copydest
let copyLib lib = do
rawSystemExit verbosity "cp" ["-u", "./lib/" ++ lib ++ ".dll", bindir installDirs]
notice verbosity $ "Copy " ++ lib ++ " to " ++ bindir installDirs
mapM_ copyLib concordiumLibs
_ -> return ()
where
distPref = fromFlag (copyDistPref flags)
verbosity = fromFlag (copyVerbosity flags)
copydest = fromFlag (copyDest flags)
main =
defaultMainWithHooks $
generatingProtos
"./concordium-grpc-api"
simpleUserHooks
{ postConf = makeRust,
postCopy = copyDlls
}