-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlakefile.lean
152 lines (126 loc) · 5.5 KB
/
lakefile.lean
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import Lake
open System Lake DSL
def cDir : FilePath := __dir__ / "c"
def buildDir := __dir__ / defaultBuildDir
def buildCDir := buildDir / "c"
def buildLibDir := buildDir / "lib"
package LeanCrypto where
-- customize layout
srcDir := "lib"
moreLeancArgs := #["-O3"]
-- Setting this to `true` produces `libCrypto` which conflicts on case-insensitive filesystems
-- with `libcrypto` produced from OpenSSL.
precompileModules := false
/-- Given a source path relative to `cDir`, build the corresponding `.o` in `buildCDir`. -/
def ffiOTarget (srcPath : FilePath) (compiler: FilePath) (deps : List (BuildJob FilePath))
(opts : Array String) : IndexBuildM (BuildJob FilePath) := do
let oFile := buildCDir / srcPath.withExtension "o"
let src := cDir / srcPath
buildFileAfterDepList oFile ((← inputFile src) :: deps) fun _ => do
compileO oFile.toString oFile src opts compiler
def includeFlag (path:FilePath) : String := "-I" ++ path.toString
target bindingsTarget : FilePath := do
-- IO.println $ "Lean: " ++ (← getLeanIncludeDir).toString
ffiOTarget "bindings.cpp" "c++" []
#["-O3",
"-DKATNUM=10",
includeFlag (cDir / "openssl" / "include"),
includeFlag (cDir / "keccak" / "include"),
includeFlag (cDir / "mceliece348864"),
includeFlag (← getLeanIncludeDir)]
def mcelieceFiles : Array FilePath :=
#[ "gf.c", "util.c" ]
def mcelieceTarget (srcPath : FilePath) : IndexBuildM (BuildJob FilePath) :=
let src := "mceliece348864" / srcPath
ffiOTarget src "cc" []
#["-O3",
"-DKATNUM=10",
"-DCRYPTO_NAMESPACE(x)=x",
includeFlag (cDir / "mceliece348864"),
-- includeFlag "/usr/local/Cellar/[email protected]/1.1.1l_1/include",
includeFlag (cDir / "keccak" / "include"),
includeFlag (cDir / "openssl" / "include")]
extern_lib libmceliece348864 (pkg : Package) := do
let libFile := buildLibDir / "libmceliece348864.a"
let dependencies ← mcelieceFiles.mapM mcelieceTarget
let bindings ← fetch (pkg.target ``bindingsTarget)
buildStaticLib libFile (dependencies.push bindings)
def keccakFiles : Array FilePath :=
let base : FilePath := "keccak"
#[ base / "Modes" / "SimpleFIPS202.c",
base / "Constructions" / "KeccakSponge.c",
base / "SnP" / "KeccakP-200" / "Reference" / "KeccakP-200-reference.c",
base / "SnP" / "KeccakP-400" / "Reference" / "KeccakP-400-reference.c",
base / "SnP" / "KeccakP-800" / "Reference" / "KeccakP-800-reference.c",
base / "SnP" / "KeccakP-1600" / "Reference" / "KeccakP-1600-reference.c"
]
def keccakTarget (srcPath : FilePath) : IndexBuildM (BuildJob FilePath) :=
let commonIncPath := cDir / "keccak" / "Common"
let incPath := cDir / "keccak" / "include" / "libkeccak.a.headers"
ffiOTarget srcPath "cc" [] #["-O3", includeFlag incPath, includeFlag commonIncPath]
extern_lib libkeccak := do
let libFile := buildLibDir / "libkeccak.a"
let dependencies ← keccakFiles.mapM keccakTarget
buildStaticLib libFile dependencies
--"-arch x86_64",
def opensslDefFlags : Array String :=
#["-O3",
"-Wall"
]
def opensslFiles : Array FilePath :=
let base : FilePath := "openssl"
#[ base / "crypto" / "aes" / "aes_core.c" ]
def opensslTarget (srcPath : FilePath) (extraOps : optParam (Array String) #[])
: IndexBuildM (BuildJob FilePath) :=
let rootPath := includeFlag $ cDir / "openssl"
let incPath := includeFlag $ cDir / "openssl" / "include"
ffiOTarget srcPath "cc" [] (opensslDefFlags ++ #[incPath, rootPath] ++ extraOps)
-- -DENGINESDIR="\"/usr/local/lib/engines-1.1\"" -D_REENTRANT -DNDEBUG -MMD -MF crypto/cryptlib.d.tmp -MT crypto/cryptlib.o -c -o crypto/cryptlib.o crypto/cryptlib.c
extern_lib libcrypto := do
let libFile := buildLibDir / "libcrypto.a"
let dependencies ← opensslFiles.mapM opensslTarget
buildStaticLib libFile dependencies
require smt from git
"https://github.com/ufmg-smite/lean-smt"@"main"
lean_lib LeanCrypto where
roots := #[`Crypto]
@[default_target]
lean_exe mceliece where
root := `McEliece
def getTestOutput (fname : FilePath) : ScriptM IO.Process.Output := do
-- Note: this only works on Unix since it needs the shared library `libSmt`
-- to also load its transitive dependencies.
let some smtDynlib := (← findModule? `Smt).map Module.dynlibFile
| throwThe IO.Error "cannot find module Smt"
IO.Process.output {
cmd := (← getLean).toString
args := #[s!"--load-dynlib={smtDynlib}", fname.toString],
env := (← getAugmentedEnv)
}
script runTest (args) do
let some fname := args[0]? | do printUsage; return 1
let fname := FilePath.mk fname
if fname.extension != some "lean" then printUsage; return 1
let out ← getTestOutput fname
let expected ← IO.FS.readFile (fname.withExtension "expected")
if ¬out.stderr.isEmpty ∨ out.stdout ≠ expected then
IO.println s!"Stderr:\n{out.stderr}"
IO.println s!"Stdout:\n{out.stdout}"
IO.println s!"Expected:\n{expected}"
return 2
return 0
where printUsage : ScriptM Unit := do
IO.println "Run a test file `test.lean` and compare the output to `test.expected`.
USAGE:
lake run runTest <file>.lean"
script updateTest (args) do
let some fname := args[0]? | do printUsage; return 1
let fname := FilePath.mk fname
if fname.extension != some "lean" then printUsage; return 1
let out ← getTestOutput fname
IO.FS.writeFile (fname.withExtension "expected") out.stdout
return 0
where printUsage : ScriptM Unit := do
IO.println "Run a test file `test.lean` and write the output to `test.expected`.
USAGE:
lake run updateTest <file>.lean"