78 lines
3.2 KiB
Text
78 lines
3.2 KiB
Text
/-
|
||
Copyright (c) 2022 Mac Malone. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Mac Malone
|
||
-/
|
||
import Lake.Build.Module
|
||
|
||
open Std System
|
||
open Lean hiding SearchPath
|
||
|
||
namespace Lake
|
||
|
||
-- # Build Package Lean Lib
|
||
|
||
def Package.getLibModuleArray (lib : LeanLibConfig) (self : Package) : IO (Array Module) := do
|
||
return (← lib.getModuleArray self.srcDir).map (⟨self, WfName.ofName ·⟩)
|
||
|
||
/--
|
||
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 Package.buildLibModules
|
||
(self : Package) (lib : LeanLibConfig) (facet : WfName)
|
||
[DynamicType ModuleData facet (ActiveBuildTarget α)] : SchedulerM Job := do
|
||
let buildMods : BuildM _ := do
|
||
let mods ← self.getLibModuleArray lib
|
||
let modTargets ← buildModuleFacetArray mods facet
|
||
(·.task) <$> ActiveTarget.collectOpaqueArray modTargets
|
||
buildMods.catchFailure fun _ => pure <| failure
|
||
|
||
def Package.mkLibTarget (self : Package) (lib : LeanLibConfig) : OpaqueTarget :=
|
||
Target.opaque <| self.buildLibModules lib &`lean
|
||
|
||
def Package.libTarget (self : Package) : OpaqueTarget :=
|
||
self.mkLibTarget self.builtinLibConfig
|
||
|
||
-- # Build Package Static Lib
|
||
|
||
def Package.localTargetsOf (map : NameMap (ActiveBuildTarget α)) (self : Package) : Array (BuildTarget α) :=
|
||
map.fold (fun a n v => if self.isLocalModule n then a.push (Target.active v) else a) #[]
|
||
|
||
def Package.mkStaticLibTarget (lib : LeanLibConfig) (self : Package) : FileTarget :=
|
||
let libFile := self.libDir / lib.staticLibFileName
|
||
BuildTarget.mk' libFile do
|
||
let mods ← self.getLibModuleArray lib
|
||
let oFileTargets := self.localTargetsOf <| ← buildModuleFacetMap mods &`lean.o
|
||
staticLibTarget libFile oFileTargets |>.materializeAsync
|
||
|
||
protected def Package.staticLibTarget (self : Package) : FileTarget :=
|
||
self.mkStaticLibTarget self.builtinLibConfig
|
||
|
||
-- # Build Package Shared Lib
|
||
|
||
def Package.linkTargetsOf
|
||
(targetMap : NameMap ActiveFileTarget) (self : Package) : LakeM (Array FileTarget) := do
|
||
let collect dep recurse := do
|
||
let pkg := (← findPackage? dep.name).get!
|
||
pkg.dependencies.forM fun dep => discard <| recurse dep
|
||
return pkg.localTargetsOf targetMap ++ pkg.externLibTargets
|
||
let ⟨x, map⟩ ← EStateT.run (mkRBMap _ _ Name.quickCmp) <|
|
||
self.dependencies.forM fun dep => discard <| buildTop Dependency.name collect dep
|
||
match x with
|
||
| Except.ok _ =>
|
||
let ts := map.fold (fun acc _ vs => acc ++ vs) #[]
|
||
return self.localTargetsOf targetMap ++ self.externLibTargets ++ ts
|
||
| Except.error _ => panic! "dependency cycle emerged after resolution"
|
||
|
||
def Package.mkSharedLibTarget (self : Package) (lib : LeanLibConfig) : FileTarget :=
|
||
let libFile := self.libDir / lib.sharedLibFileName
|
||
BuildTarget.mk' libFile do
|
||
let mods ← self.getLibModuleArray lib
|
||
let linkTargets ← self.linkTargetsOf <| ← buildModuleFacetMap mods &`lean.o
|
||
let target := leanSharedLibTarget libFile linkTargets lib.linkArgs
|
||
target.materializeAsync
|
||
|
||
protected def Package.sharedLibTarget (self : Package) : FileTarget :=
|
||
self.mkSharedLibTarget self.builtinLibConfig
|