@@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
4
4
Authors: Mac Malone
5
5
-/
6
6
import Lake.Build.Roots
7
- import Lake.Build.Module
8
7
import Lake.Build.Topological
9
8
import Lake.Util.EStateT
10
9
@@ -14,146 +13,35 @@ import Lake.Util.EStateT
14
13
The Lake build index is the complete map of Lake build keys to
15
14
Lake build functions, which is used by Lake to build any Lake build info.
16
15
17
- This module contains the definitions used to formalize this concept,
18
- and it leverages the index to perform topologically-based recursive builds.
16
+ This module leverages the index to perform topologically-based recursive builds.
19
17
-/
20
18
21
19
open Std Lean
22
20
namespace Lake
23
21
24
- /-!
25
- ## Facet Build Maps
26
- -/
27
-
28
- /-- A map from module facet names to build functions. -/
29
- abbrev ModuleBuildMap (m : Type → Type v) :=
30
- DRBMap Name (cmp := Name.quickCmp) fun k =>
31
- Module → IndexBuildFn m → m (ModuleData k)
32
-
33
- @[inline] def ModuleBuildMap.empty : ModuleBuildMap m := DRBMap.empty
34
-
35
- /-- A map from package facet names to build functions. -/
36
- abbrev PackageBuildMap (m : Type → Type v) :=
37
- DRBMap Name (cmp := Name.quickCmp) fun k =>
38
- Package → IndexBuildFn m → m (PackageData k)
39
-
40
- @[inline] def PackageBuildMap.empty : PackageBuildMap m := DRBMap.empty
41
-
42
- /-- A map from target facet names to build functions. -/
43
- abbrev TargetBuildMap (m : Type → Type v) :=
44
- DRBMap Name (cmp := Name.quickCmp) fun k =>
45
- Package → IndexBuildFn m → m (PackageData k)
46
-
47
- @[inline] def TargetBuildMap.empty : PackageBuildMap m := DRBMap.empty
48
-
49
- /-!
50
- ## Build Function Constructor Helpers
51
- -/
52
-
53
- /--
54
- Converts a conveniently typed module facet build function into its
55
- dynamically typed equivalent.
56
- -/
57
- @[inline] def mkModuleFacetBuild {facet : Name} (build : Module → IndexT m α)
58
- [h : FamilyDef ModuleData facet α] : Module → IndexT m (ModuleData facet) :=
59
- cast (by rw [← h.family_key_eq_type]) build
60
-
61
- /--
62
- Converts a conveniently typed package facet build function into its
63
- dynamically typed equivalent.
64
- -/
65
- @[inline] def mkPackageFacetBuild {facet : Name} (build : Package → IndexT m α)
66
- [h : FamilyDef PackageData facet α] : Package → IndexT m (PackageData facet) :=
67
- cast (by rw [← h.family_key_eq_type]) build
68
-
69
22
/--
70
23
Converts a conveniently typed target facet build function into its
71
24
dynamically typed equivalent.
72
25
-/
73
- @[inline ] def mkTargetFacetBuild (facet : Name) (build : IndexT m α)
74
- [h : FamilyDef TargetData facet α] : IndexT m (TargetData facet) :=
26
+ @[macroInline ] def mkTargetFacetBuild (facet : Name) (build : IndexBuildM α)
27
+ [h : FamilyDef TargetData facet α] : IndexBuildM (TargetData facet) :=
75
28
cast (by rw [← h.family_key_eq_type]) build
76
29
77
- section
78
- variable [Monad m] [MonadLiftT BuildM m] [MonadBuildStore m]
79
-
80
- /-!
81
- ## Initial Facet Maps
82
- -/
83
-
84
- open Module in
85
- /--
86
- A module facet name to build function map that contains builders for
87
- the initial set of Lake module facets (e.g., `lean.{imports, c, o, dynlib]`).
88
- -/
89
- @[specialize] def moduleBuildMap : ModuleBuildMap m :=
90
- have : MonadLift BuildM m := ⟨liftM⟩
91
- ModuleBuildMap.empty (m := m)
92
- -- Compute unique imports (direct × transitive)
93
- |>.insert importFacet (mkModuleFacetBuild (·.recParseImports))
94
- -- Build module (`.olean`, `.ilean`, and possibly `.c`)
95
- |>.insert leanBinFacet (mkModuleFacetBuild (·.recBuildLean .leanBin))
96
- |>.insert oleanFacet (mkModuleFacetBuild (·.recBuildLean .olean))
97
- |>.insert ileanFacet (mkModuleFacetBuild (·.recBuildLean .ilean))
98
- |>.insert cFacet (mkModuleFacetBuild (·.recBuildLean .c))
99
- -- Build module `.o`
100
- |>.insert oFacet (mkModuleFacetBuild <| fun mod => do
101
- mod.mkOTarget (Target.active (← mod.c.recBuild)) |>.activate
102
- )
103
- -- Build shared library for `--load-dynlb`
104
- |>.insert dynlibFacet (mkModuleFacetBuild (·.recBuildDynlib))
105
-
106
- /--
107
- A package facet name to build function map that contains builders for
108
- the initial set of Lake package facets (e.g., `extraDep`).
109
- -/
110
- @[specialize] def packageBuildMap : PackageBuildMap m :=
111
- have : MonadLift BuildM m := ⟨liftM⟩
112
- PackageBuildMap.empty (m := m)
113
- -- Compute the package's transitive dependencies
114
- |>.insert `deps (mkPackageFacetBuild <| fun pkg => do
115
- let mut deps := #[]
116
- let mut depSet := PackageSet.empty
117
- for dep in pkg.deps do
118
- for depDep in (← recBuild <| dep.facet `deps) do
119
- unless depSet.contains depDep do
120
- deps := deps.push depDep
121
- depSet := depSet.insert depDep
122
- unless depSet.contains dep do
123
- deps := deps.push dep
124
- depSet := depSet.insert dep
125
- return deps
126
- )
127
- -- Build the `extraDepTarget` for the package and its transitive dependencies
128
- |>.insert `extraDep (mkPackageFacetBuild <| fun pkg => do
129
- let mut target := ActiveTarget.nil
130
- for dep in pkg.deps do
131
- target ← target.mixOpaqueAsync (← dep.extraDep.recBuild)
132
- target.mixOpaqueAsync <| ← pkg.extraDepTarget.activate
133
- )
134
-
135
30
/-!
136
31
## Topologically-based Recursive Build Using the Index
137
32
-/
138
33
139
34
/-- Recursive build function for anything in the Lake build index. -/
140
- @[specialize] def recBuildIndex (info : BuildInfo) : IndexT m (BuildData info.key) := do
141
- have : MonadLift BuildM m := ⟨liftM⟩
35
+ def recBuildWithIndex (info : BuildInfo) : IndexBuildM (BuildData info.key) := do
142
36
match info with
143
37
| .moduleFacet mod facet =>
144
- if let some build := moduleBuildMap.find? facet then
145
- build mod
146
- else if let some config := (← getWorkspace).findModuleFacetConfig? facet then
147
- have := config.familyDef
148
- mkModuleFacetBuild config.build mod
38
+ if let some config := (← getWorkspace).findModuleFacetConfig? facet then
39
+ config.build mod
149
40
else
150
41
error s! "do not know how to build module facet `{ facet} `"
151
42
| .packageFacet pkg facet =>
152
- if let some build := packageBuildMap.find? facet then
153
- build pkg
154
- else if let some config := (← getWorkspace).findPackageFacetConfig? facet then
155
- have := config.familyDef
156
- mkPackageFacetBuild config.build pkg
43
+ if let some config := (← getWorkspace).findPackageFacetConfig? facet then
44
+ config.build pkg
157
45
else
158
46
error s! "do not know how to build package facet `{ facet} `"
159
47
| .customTarget pkg target =>
@@ -170,7 +58,7 @@ the initial set of Lake package facets (e.g., `extraDep`).
170
58
| .sharedLeanLib lib =>
171
59
mkTargetFacetBuild LeanLib.sharedFacet lib.recBuildShared
172
60
| .leanExe exe =>
173
- mkTargetFacetBuild LeanExe.exeFacet exe.recBuild
61
+ mkTargetFacetBuild LeanExe.exeFacet exe.recBuildExe
174
62
| .staticExternLib lib =>
175
63
mkTargetFacetBuild ExternLib.staticFacet lib.target.activate
176
64
| .sharedExternLib lib =>
@@ -182,31 +70,41 @@ the initial set of Lake package facets (e.g., `extraDep`).
182
70
Recursively build the given info using the Lake build index
183
71
and a topological / suspending scheduler.
184
72
-/
185
- @[specialize] def buildIndexTop' (info : BuildInfo) : CycleT BuildKey m (BuildData info.key) :=
186
- buildDTop BuildData BuildInfo.key recBuildIndex info
73
+ def buildIndexTop' (info : BuildInfo) : RecBuildM (BuildData info.key) :=
74
+ buildDTop BuildData BuildInfo.key recBuildWithIndex info
187
75
188
76
/--
189
77
Recursively build the given info using the Lake build index
190
78
and a topological / suspending scheduler and return the dynamic result.
191
79
-/
192
- @[inline] def buildIndexTop (info : BuildInfo)
193
- [FamilyDef BuildData info.key α] : CycleT BuildKey m α := do
194
- cast (by simp) <| buildIndexTop' (m := m) info
195
-
196
- end
80
+ @[macroInline] def buildIndexTop (info : BuildInfo)
81
+ [FamilyDef BuildData info.key α] : RecBuildM α := do
82
+ cast (by simp) <| buildIndexTop' info
197
83
198
84
/-- Build the given Lake target using the given Lake build store. -/
199
- @[inline] def BuildInfo.buildIn (store : BuildStore) (self : BuildInfo)
200
- [FamilyDef BuildData self.key α] : BuildM α := do
201
- failOnBuildCycle <| ← EStateT.run' (m := BuildM) store <| buildIndexTop self
85
+ @[inline] def BuildInfo.buildIn
86
+ (store : BuildStore) (self : BuildInfo) [FamilyDef BuildData self.key α] : BuildM α := do
87
+ failOnBuildCycle <| ← EStateT.run' store <| buildIndexTop self
202
88
203
89
/-- Build the given Lake target in a fresh build store. -/
204
- @[inline] def BuildInfo.build (self : BuildInfo) [FamilyDef BuildData self.key α] : BuildM α :=
90
+ @[macroInline] def BuildInfo.build
91
+ (self : BuildInfo) [FamilyDef BuildData self.key α] : BuildM α :=
205
92
buildIn BuildStore.empty self
206
93
207
94
export BuildInfo (build buildIn)
208
95
209
- /-- An opaque target that builds the Lake target in a fresh build store. -/
96
+ /-! ## Targets Using the Build Index -/
97
+
98
+ /-- An opaque target that builds the info in a fresh build store. -/
210
99
@[inline] def BuildInfo.target (self : BuildInfo)
211
100
[FamilyDef BuildData self.key (ActiveBuildTarget α)] : OpaqueTarget :=
212
101
BuildTarget.mk' () <| self.build <&> (·.task)
102
+
103
+ /-- A smart constructor for facet configurations that generate targets. -/
104
+ @[inline] def mkFacetTargetConfig (build : ι → IndexBuildM (ActiveBuildTarget α))
105
+ [h : FamilyDef Fam facet (ActiveBuildTarget α)] : FacetConfig Fam ι facet where
106
+ build := cast (by rw [← h.family_key_eq_type]) build
107
+ toTarget? := fun info key_eq_type =>
108
+ have : FamilyDef BuildData info.key (ActiveBuildTarget α) :=
109
+ ⟨h.family_key_eq_type ▸ key_eq_type⟩
110
+ info.target
0 commit comments