refactor: make LeanLib.buildModules a proper recursive build

This commit is contained in:
tydeu 2022-07-24 00:34:57 -04:00
parent abe8e8b1f8
commit 67775edd18
8 changed files with 69 additions and 61 deletions

View file

@ -70,6 +70,10 @@ package_data extraDep : ActiveOpaqueTarget
/-! ## Target Facets -/
/-- A Lean library's Lean libraries. -/
abbrev LeanLib.leanFacet := `leanLib.lean
target_data leanLib.lean : ActiveOpaqueTarget
/-- A Lean library's static binary. -/
abbrev LeanLib.staticFacet := `leanLib.static
target_data leanLib.static : ActiveFileTarget

View file

@ -32,39 +32,40 @@ dynamically typed equivalent.
-/
/-- Recursive build function for anything in the Lake build index. -/
def recBuildWithIndex (info : BuildInfo) : IndexBuildM (BuildData info.key) := do
match info with
| .moduleFacet mod facet =>
if let some config := (← getWorkspace).findModuleFacetConfig? facet then
config.build mod
def recBuildWithIndex : (info : BuildInfo) → IndexBuildM (BuildData info.key)
| .moduleFacet mod facet => do
if let some config := (← getWorkspace).findModuleFacetConfig? facet then
config.build mod
else
error s!"do not know how to build module facet `{facet}`"
| .packageFacet pkg facet => do
if let some config := (← getWorkspace).findPackageFacetConfig? facet then
config.build pkg
else
error s!"do not know how to build package facet `{facet}`"
| .customTarget pkg target =>
if let some config := pkg.findTargetConfig? target then
if h : pkg.name = config.package ∧ target = config.name then
have h' : CustomData (pkg.name, target) = ActiveBuildTarget config.resultType := by simp [h]
liftM <| cast (by rw [← h']) <| config.target.activate
else
error s!"do not know how to build module facet `{facet}`"
| .packageFacet pkg facet =>
if let some config := (← getWorkspace).findPackageFacetConfig? facet then
config.build pkg
else
error s!"do not know how to build package facet `{facet}`"
| .customTarget pkg target =>
if let some config := pkg.findTargetConfig? target then
if h : pkg.name = config.package ∧ target = config.name then
have h' : CustomData (pkg.name, target) = ActiveBuildTarget config.resultType := by simp [h]
liftM <| cast (by rw [← h']) <| config.target.activate
else
error "target's name in the configuration does not match the name it was registered with"
else
error s!"could not build `{target}` of `{pkg.name}` -- target not found"
| .staticLeanLib lib =>
mkTargetFacetBuild LeanLib.staticFacet lib.recBuildStatic
| .sharedLeanLib lib =>
mkTargetFacetBuild LeanLib.sharedFacet lib.recBuildShared
| .leanExe exe =>
mkTargetFacetBuild LeanExe.exeFacet exe.recBuildExe
| .staticExternLib lib =>
mkTargetFacetBuild ExternLib.staticFacet lib.target.activate
| .sharedExternLib lib =>
mkTargetFacetBuild ExternLib.sharedFacet do
let staticTarget := Target.active <| ← lib.static.recBuild
staticToLeanDynlibTarget staticTarget |>.activate
error "target's name in the configuration does not match the name it was registered with"
else
error s!"could not build `{target}` of `{pkg.name}` -- target not found"
| .leanLib lib =>
mkTargetFacetBuild LeanLib.leanFacet lib.recBuildLean
| .staticLeanLib lib =>
mkTargetFacetBuild LeanLib.staticFacet lib.recBuildStatic
| .sharedLeanLib lib =>
mkTargetFacetBuild LeanLib.sharedFacet lib.recBuildShared
| .leanExe exe =>
mkTargetFacetBuild LeanExe.exeFacet exe.recBuildExe
| .staticExternLib lib =>
mkTargetFacetBuild ExternLib.staticFacet lib.target.activate
| .sharedExternLib lib =>
mkTargetFacetBuild ExternLib.sharedFacet do
let staticTarget := Target.active <| ← lib.static.recBuild
staticToLeanDynlibTarget staticTarget |>.activate
/--
Recursively build the given info using the Lake build index

View file

@ -5,9 +5,6 @@ Authors: Mac Malone
-/
import Lake.Build.Index
open Std System
open Lean hiding SearchPath
namespace Lake
/-! ## Module Facet Targets -/
@ -19,22 +16,8 @@ namespace Lake
/-! ## Pure Lean Lib Targets -/
/--
Build the `extraDepTarget` of a package and its (transitive) dependencies
and then build the target `facet` of library's modules recursively, constructing
a single opaque target for the whole build.
-/
def LeanLib.buildModules (self : LeanLib) (facet : Name)
[FamilyDef ModuleData facet (ActiveBuildTarget α)] : SchedulerM Job := do
let buildMods : BuildM _ := do
let mods ← self.getModuleArray
let modTargets ← failOnBuildCycle <| ← EStateT.run' BuildStore.empty
<| mods.mapM fun mod => buildIndexTop <| mod.facet facet
(·.task) <$> ActiveTarget.collectOpaqueArray modTargets
buildMods.catchFailure fun _ => pure <| failure
@[inline] protected def LeanLib.leanTarget (self : LeanLib) : OpaqueTarget :=
Target.opaque <| self.buildModules Module.leanBinFacet
self.lean.target
@[inline] protected def Package.leanLibTarget (self : Package) : OpaqueTarget :=
self.builtinLib.leanTarget

View file

@ -22,6 +22,7 @@ namespace Lake
inductive BuildInfo
| moduleFacet (module : Module) (facet : Name)
| packageFacet (package : Package) (facet : Name)
| leanLib (lib : LeanLib)
| staticLeanLib (lib : LeanLib)
| sharedLeanLib (lib : LeanLib)
| leanExe (exe : LeanExe)
@ -44,6 +45,9 @@ abbrev Package.facetBuildKey (facet : Name) (self : Package) : BuildKey :=
abbrev Package.targetBuildKey (target : Name) (self : Package) : BuildKey :=
.customTarget self.name target
abbrev LeanLib.leanBuildKey (self : LeanLib) : BuildKey :=
.targetFacet self.pkg.name self.name leanFacet
abbrev LeanLib.staticBuildKey (self : LeanLib) : BuildKey :=
.targetFacet self.pkg.name self.name staticFacet
@ -65,6 +69,7 @@ abbrev ExternLib.sharedBuildKey (self : ExternLib) : BuildKey :=
abbrev BuildInfo.key : (self : BuildInfo) → BuildKey
| moduleFacet m f => m.facetBuildKey f
| packageFacet p f => p.facetBuildKey f
| leanLib l => l.leanBuildKey
| staticLeanLib l => l.staticBuildKey
| sharedLeanLib l => l.sharedBuildKey
| leanExe x => x.buildKey
@ -86,6 +91,10 @@ instance [FamilyDef CustomData (p.name, t) α]
: FamilyDef BuildData (BuildInfo.key (.customTarget p t)) α where
family_key_eq_type := by unfold BuildData; simp
instance [FamilyDef TargetData LeanLib.leanFacet α]
: FamilyDef BuildData (BuildInfo.key (.leanLib l)) α where
family_key_eq_type := by unfold BuildData; simp
instance [FamilyDef TargetData LeanLib.staticFacet α]
: FamilyDef BuildData (BuildInfo.key (.staticLeanLib l)) α where
family_key_eq_type := by unfold BuildData; simp
@ -185,6 +194,10 @@ abbrev Package.extraDep (self : Package) : BuildInfo :=
abbrev Package.customTarget (target : Name) (self : Package) : BuildInfo :=
.customTarget self target
/-- Build info of the Lean library's Lean binaries. -/
abbrev LeanLib.lean (self : LeanLib) : BuildInfo :=
.leanLib self
/-- Build info of the Lean library's static binary. -/
abbrev LeanLib.static (self : LeanLib) : BuildInfo :=
.staticLeanLib self

View file

@ -28,7 +28,13 @@ def LeanLib.recBuildLocalModules
modSet := modSet.insert mod
return results
protected def LeanLib.recBuildStatic (self : LeanLib) : IndexT RecBuildM ActiveFileTarget := do
protected def LeanLib.recBuildLean
(self : LeanLib) : IndexT RecBuildM ActiveOpaqueTarget := do
ActiveTarget.collectOpaqueArray (i := PUnit) <|
← self.recBuildLocalModules #[Module.leanBinFacet]
protected def LeanLib.recBuildStatic
(self : LeanLib) : IndexT RecBuildM ActiveFileTarget := do
let oTargets := (← self.recBuildLocalModules self.nativeFacets).map Target.active
staticLibTarget self.staticLibFile oTargets |>.activate
@ -38,8 +44,7 @@ protected def LeanLib.recBuildStatic (self : LeanLib) : IndexT RecBuildM ActiveF
Build and collect the local object files and external libraries
of a library and its modules' imports.
-/
def LeanLib.recBuildLinks
(facets : Array (ModuleFacet ActiveFileTarget)) (self : LeanLib)
def LeanLib.recBuildLinks (self : LeanLib)
: IndexT RecBuildM (Array ActiveFileTarget) := do
-- Build and collect modules
let mut pkgs := #[]
@ -56,7 +61,7 @@ def LeanLib.recBuildLinks
pkgSet := pkgSet.insert mod.pkg
pkgs := pkgs.push mod.pkg
if self.isLocalModule mod.name then
for facet in facets do
for facet in self.nativeFacets do
targets := targets.push <| ← recBuild <| mod.facet facet.name
modSet := modSet.insert mod
-- Build and collect external library targets
@ -66,13 +71,15 @@ def LeanLib.recBuildLinks
targets := targets.push target
return targets
protected def LeanLib.recBuildShared (self : LeanLib) : IndexT RecBuildM ActiveFileTarget := do
let linkTargets := (← self.recBuildLinks self.nativeFacets).map Target.active
protected def LeanLib.recBuildShared
(self : LeanLib) : IndexT RecBuildM ActiveFileTarget := do
let linkTargets := (← self.recBuildLinks).map Target.active
leanSharedLibTarget self.sharedLibFile linkTargets self.linkArgs |>.activate
/-! # Build Executable -/
protected def LeanExe.recBuildExe (self : LeanExe) : IndexT RecBuildM ActiveFileTarget := do
protected def LeanExe.recBuildExe
(self : LeanExe) : IndexT RecBuildM ActiveFileTarget := do
let (_, imports) ← self.root.imports.recBuild
let linkTargets := #[Target.active <| ← self.root.o.recBuild]
let mut linkTargets ← imports.foldlM (init := linkTargets) fun arr mod => do

View file

@ -63,10 +63,10 @@ abbrev ActiveFileTarget := ActiveBuildTarget FilePath
--------------------------------------------------------------------------------
/-- A `BuildTarget` with no artifact information. -/
abbrev OpaqueTarget := BuildTarget PUnit
abbrev OpaqueTarget := BuildTarget Unit
/-- An `ActiveBuildTarget` with no artifact information. -/
abbrev ActiveOpaqueTarget := ActiveBuildTarget PUnit
abbrev ActiveOpaqueTarget := ActiveBuildTarget Unit
namespace OpaqueTarget

View file

@ -13,7 +13,7 @@ structure FacetConfig (DataFam : Name → Type) (ι : Type) (name : Name) : Type
/-- The facet's build (function). -/
build : ι → IndexBuildM (DataFam name)
/-- Is this facet a buildable target? -/
toTarget? : (info : BuildInfo) → BuildData info.key = DataFam name → Option (OpaqueTarget.{0})
toTarget? : (info : BuildInfo) → BuildData info.key = DataFam name → Option OpaqueTarget
deriving Inhabited
protected abbrev FacetConfig.name (_ : FacetConfig DataFam ι name) := name

View file

@ -70,7 +70,7 @@ structure PackageConfig extends WorkspaceConfig, LeanConfig where
**DEPRECATED:** Use separate custom `target` declarations instead?
-/
extraDepTarget : Option OpaqueTarget.{0} := none
extraDepTarget : Option OpaqueTarget := none
/--
The optional `PackageFacet` to build on a bare `lake build` of the package.