125 lines
3.8 KiB
Text
125 lines
3.8 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.Trace
|
||
import Lake.Config.LeanLib
|
||
|
||
namespace Lake
|
||
open Std System
|
||
|
||
/-- A buildable Lean module of a `LeanLib`. -/
|
||
structure Module where
|
||
lib : LeanLib
|
||
name : WfName
|
||
/--
|
||
The name of the module as a key.
|
||
Used to create private modules (e.g., executable roots).
|
||
-/
|
||
keyName : WfName := name
|
||
deriving Inhabited
|
||
|
||
abbrev ModuleSet := RBTree Module (·.name.quickCmp ·.name)
|
||
@[inline] def ModuleSet.empty : ModuleSet := RBTree.empty
|
||
|
||
abbrev ModuleMap (α) := RBMap Module α (·.name.quickCmp ·.name)
|
||
@[inline] def ModuleMap.empty : ModuleMap α := RBMap.empty
|
||
|
||
/-- Locate the named module in the library (if it is buildable and local to it). -/
|
||
def LeanLib.findModule? (mod : Name) (self : LeanLib) : Option Module :=
|
||
let mod := WfName.ofName mod
|
||
if self.isBuildableModule mod then some {lib := self, name := mod} else none
|
||
|
||
/-- Get an `Array` of the library's modules. -/
|
||
def LeanLib.getModuleArray (self : LeanLib) : IO (Array Module) :=
|
||
(·.2) <$> StateT.run (s := #[]) do
|
||
self.config.globs.forM fun glob => do
|
||
glob.forEachModuleIn self.srcDir fun mod => do
|
||
modify (·.push {lib := self, name := mod})
|
||
|
||
namespace Module
|
||
|
||
abbrev pkg (self : Module) : Package :=
|
||
self.lib.pkg
|
||
|
||
@[inline] def rootDir (self : Module) : FilePath :=
|
||
self.lib.rootDir
|
||
|
||
@[inline] def filePath (dir : FilePath) (ext : String) (self : Module) : FilePath :=
|
||
Lean.modToFilePath dir self.name ext
|
||
|
||
@[inline] def srcPath (ext : String) (self : Module) : FilePath :=
|
||
self.filePath self.lib.srcDir ext
|
||
|
||
@[inline] def leanFile (self : Module) : FilePath :=
|
||
self.srcPath "lean"
|
||
|
||
@[inline] def leanLibPath (ext : String) (self : Module) : FilePath :=
|
||
self.filePath self.pkg.oleanDir ext
|
||
|
||
@[inline] def oleanFile (self : Module) : FilePath :=
|
||
self.leanLibPath "olean"
|
||
|
||
@[inline] def ileanFile (self : Module) : FilePath :=
|
||
self.leanLibPath "ilean"
|
||
|
||
@[inline] def traceFile (self : Module) : FilePath :=
|
||
self.leanLibPath "trace"
|
||
|
||
@[inline] def irPath (ext : String) (self : Module) : FilePath :=
|
||
self.filePath self.pkg.irDir ext
|
||
|
||
@[inline] def cFile (self : Module) : FilePath :=
|
||
self.irPath "c"
|
||
|
||
@[inline] def cTraceFile (self : Module) : FilePath :=
|
||
self.irPath "c.trace"
|
||
|
||
@[inline] def oFile (self : Module) : FilePath :=
|
||
self.irPath "o"
|
||
|
||
@[inline] def dynlibName (self : Module) : String :=
|
||
-- NOTE: file name MUST be unique on Windows
|
||
self.name.toStringWithSep "-"
|
||
|
||
@[inline] def dynlibFile (self : Module) : FilePath :=
|
||
self.pkg.libDir / nameToSharedLib self.dynlibName
|
||
|
||
@[inline] def buildType (self : Module) : BuildType :=
|
||
self.lib.buildType
|
||
|
||
@[inline] def leanArgs (self : Module) : Array String :=
|
||
self.lib.leanArgs
|
||
|
||
@[inline] def leancArgs (self : Module) : Array String :=
|
||
self.lib.leancArgs
|
||
|
||
@[inline] def linkArgs (self : Module) : Array String :=
|
||
self.lib.linkArgs
|
||
|
||
@[inline] def shouldPrecompile (self : Module) : Bool :=
|
||
self.lib.precompileModules
|
||
|
||
@[inline] def nativeFacets (self : Module) : Array (ModuleFacet ActiveFileTarget) :=
|
||
self.lib.nativeFacets
|
||
|
||
@[inline] def isLeanOnly (self : Module) : Bool :=
|
||
self.pkg.isLeanOnly && !self.shouldPrecompile
|
||
|
||
-- ## Trace Helpers
|
||
|
||
protected def getMTime (self : Module) : IO MTime := do
|
||
return mixTrace (← getMTime self.oleanFile) (← getMTime self.ileanFile)
|
||
|
||
instance : GetMTime Module := ⟨Module.getMTime⟩
|
||
|
||
protected def computeHash (self : Module) : IO Hash := do
|
||
return mixTrace (← computeHash self.oleanFile) (← computeHash self.ileanFile)
|
||
|
||
instance : ComputeHash Module IO := ⟨Module.computeHash⟩
|
||
|
||
protected def checkExists (self : Module) : BaseIO Bool := do
|
||
return (← checkExists self.oleanFile) && (← checkExists self.ileanFile)
|
||
|
||
instance : CheckExists Module := ⟨Module.checkExists⟩
|