refactor: add LeanLib/LeanExe/ExternLib + reorg & cleanup
This commit is contained in:
parent
a8d1ff5fdc
commit
c0bc0344b0
23 changed files with 476 additions and 331 deletions
|
|
@ -5,7 +5,6 @@ Authors: Mac Malone
|
|||
-/
|
||||
import Lake.Build.Monad
|
||||
import Lake.Build.Actions
|
||||
import Lake.Build.Module
|
||||
import Lake.Build.Library
|
||||
import Lake.Build.Executable
|
||||
import Lake.Build.LeanLib
|
||||
import Lake.Build.LeanExe
|
||||
import Lake.Build.Imports
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
/-
|
||||
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.Library
|
||||
|
||||
namespace Lake
|
||||
|
||||
-- # Build Package Executable
|
||||
|
||||
def Package.mkExeTarget (self : Package) (exe : LeanExeConfig) : FileTarget :=
|
||||
let exeFile := self.binDir / exe.fileName
|
||||
BuildTarget.mk' exeFile do
|
||||
let root : Module := ⟨self, WfName.ofName exe.root⟩
|
||||
let cTargetMap ← buildModuleFacetMap #[root] &`lean.c
|
||||
let pkgLinkTargets ← self.linkTargetsOf cTargetMap
|
||||
let linkTargets :=
|
||||
if self.isLocalModule exe.root then
|
||||
pkgLinkTargets
|
||||
else
|
||||
let rootTarget := cTargetMap.find? root.name |>.get!
|
||||
let rootLinkTarget := root.mkOTarget <| Target.active rootTarget
|
||||
#[rootLinkTarget] ++ pkgLinkTargets
|
||||
let target := leanExeTarget exeFile linkTargets exe.linkArgs
|
||||
target.materializeAsync
|
||||
|
||||
protected def Package.exeTarget (self : Package) : FileTarget :=
|
||||
self.mkExeTarget self.builtinExeConfig
|
||||
|
|
@ -31,7 +31,7 @@ Used by `lake print-paths` to build modules for the Lean server.
|
|||
Returns the set of module dynlibs built (so they can be loaded by the server).
|
||||
|
||||
Builds only module `.olean` and `.ilean` files if the package is configured
|
||||
as "Lean-only". Otherwise, also build `.c` and `.o` files.
|
||||
as "Lean-only". Otherwise, also build `.c` files.
|
||||
-/
|
||||
def Package.buildImportsAndDeps (imports : List String) (self : Package) : BuildM (Array FilePath) := do
|
||||
if imports.isEmpty then
|
||||
|
|
@ -47,7 +47,7 @@ def Package.buildImportsAndDeps (imports : List String) (self : Package) : Build
|
|||
else if mod.isLeanOnly then
|
||||
buildModuleTop mod &`lean
|
||||
else
|
||||
buildModuleTop mod &`lean.o <&> (·.withoutInfo)
|
||||
buildModuleTop mod &`lean.c <&> (·.withoutInfo)
|
||||
let importTargets ← failOnBuildCycle res
|
||||
let dynlibTargets := bStore.collectModuleFacetArray &`lean.dynlib
|
||||
let externLibTargets := bStore.collectPackageFacetArray &`externSharedLibs
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ the initial set of Lake package facets (e.g., `extraDep`).
|
|||
-- Build the `extern_lib` targets of the package
|
||||
|>.insert &`externSharedLibs (mkPackageFacetBuild <| fun pkg => do
|
||||
let mut targets := #[]
|
||||
for (_, config) in pkg.externLibs.toList do
|
||||
for (_, config) in pkg.externLibConfigs.toList do
|
||||
let target := staticToLeanDynlibTarget config.target
|
||||
targets := targets.push <| ← target.activate
|
||||
return targets
|
||||
|
|
|
|||
27
Lake/Build/LeanExe.lean
Normal file
27
Lake/Build/LeanExe.lean
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/-
|
||||
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.LeanLib
|
||||
|
||||
namespace Lake
|
||||
|
||||
-- # Build Package Executable
|
||||
|
||||
def LeanExe.target (self : LeanExe) : FileTarget :=
|
||||
BuildTarget.mk' self.file do
|
||||
let cTargetMap ← buildModuleFacetMap #[self.root] &`lean.c
|
||||
let pkgLinkTargets ← self.pkg.linkTargetsOf cTargetMap
|
||||
let linkTargets :=
|
||||
if self.pkg.isLocalModule self.root.name then
|
||||
pkgLinkTargets
|
||||
else
|
||||
let rootTarget := cTargetMap.find? self.root.name |>.get!
|
||||
let rootLinkTarget := self.root.mkOTarget <| Target.active rootTarget
|
||||
#[rootLinkTarget] ++ pkgLinkTargets
|
||||
let target := leanExeTarget self.file linkTargets self.linkArgs
|
||||
target.materializeAsync
|
||||
|
||||
protected def Package.exeTarget (self : Package) : FileTarget :=
|
||||
self.builtinExe.target
|
||||
|
|
@ -10,48 +10,46 @@ 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 Lean Lib
|
||||
|
||||
/--
|
||||
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)
|
||||
def LeanLib.buildModules (self : LeanLib) (facet : WfName)
|
||||
[DynamicType ModuleData facet (ActiveBuildTarget α)] : SchedulerM Job := do
|
||||
let buildMods : BuildM _ := do
|
||||
let mods ← self.getLibModuleArray lib
|
||||
let mods ← self.getModuleArray
|
||||
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 LeanLib.leanTarget (self : LeanLib) : OpaqueTarget :=
|
||||
Target.opaque <| self.buildModules &`lean
|
||||
|
||||
def Package.libTarget (self : Package) : OpaqueTarget :=
|
||||
self.mkLibTarget self.builtinLibConfig
|
||||
self.builtinLib.leanTarget
|
||||
|
||||
-- # Build Package Static Lib
|
||||
-- # Build Static Lib
|
||||
|
||||
def LeanLib.localTargetsOf (map : NameMap (ActiveBuildTarget α)) (self : LeanLib) : Array (BuildTarget α) :=
|
||||
map.fold (fun a n v => if self.isLocalModule n then a.push (Target.active v) else a) #[]
|
||||
|
||||
protected def LeanLib.staticLibTarget (self : LeanLib) : FileTarget :=
|
||||
BuildTarget.mk' self.staticLibFile do
|
||||
let mods ← self.getModuleArray
|
||||
let oFileTargets := self.localTargetsOf <| ← buildModuleFacetMap mods &`lean.o
|
||||
staticLibTarget self.staticLibFile oFileTargets |>.materializeAsync
|
||||
|
||||
protected def Package.staticLibTarget (self : Package) : FileTarget :=
|
||||
self.builtinLib.staticLibTarget
|
||||
|
||||
-- # Build Shared 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
|
||||
|
|
@ -66,13 +64,12 @@ def Package.linkTargetsOf
|
|||
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
|
||||
protected def LeanLib.sharedLibTarget (self : LeanLib) : FileTarget :=
|
||||
BuildTarget.mk' self.sharedLibFile do
|
||||
let mods ← self.getModuleArray
|
||||
let linkTargets ← self.pkg.linkTargetsOf <| ← buildModuleFacetMap mods &`lean.o
|
||||
let target := leanSharedLibTarget self.sharedLibFile linkTargets self.linkArgs
|
||||
target.materializeAsync
|
||||
|
||||
protected def Package.sharedLibTarget (self : Package) : FileTarget :=
|
||||
self.mkSharedLibTarget self.builtinLibConfig
|
||||
self.builtinLib.sharedLibTarget
|
||||
|
|
@ -40,32 +40,32 @@ def resolveModuleTarget (mod : Module) (facet : String) : Except CliError Opaque
|
|||
else
|
||||
throw <| CliError.unknownFacet "module" facet
|
||||
|
||||
def resolveLibTarget (pkg : Package) (lib : LeanLibConfig) (facet : String) : Except CliError OpaqueTarget :=
|
||||
def resolveLibTarget (lib : LeanLib) (facet : String) : Except CliError OpaqueTarget :=
|
||||
if facet.isEmpty || facet == "lean" || facet == "oleans" then
|
||||
return pkg.mkLibTarget lib
|
||||
return lib.leanTarget
|
||||
else if facet == "static" then
|
||||
return pkg.mkStaticLibTarget lib |>.withoutInfo
|
||||
return lib.staticLibTarget |>.withoutInfo
|
||||
else if facet == "shared" then
|
||||
return pkg.mkSharedLibTarget lib |>.withoutInfo
|
||||
return lib.sharedLibTarget |>.withoutInfo
|
||||
else
|
||||
throw <| CliError.unknownFacet "library" facet
|
||||
|
||||
def resolveExeTarget (pkg : Package) (exe : LeanExeConfig) (facet : String) : Except CliError OpaqueTarget :=
|
||||
def resolveExeTarget (exe : LeanExe) (facet : String) : Except CliError OpaqueTarget :=
|
||||
if facet.isEmpty || facet == "exe" then
|
||||
return pkg.mkExeTarget exe |>.withoutInfo
|
||||
return exe.target |>.withoutInfo
|
||||
else
|
||||
throw <| CliError.unknownFacet "executable" facet
|
||||
|
||||
def resolveTargetInPackage (pkg : Package) (target : Name) (facet : String) : Except CliError OpaqueTarget :=
|
||||
if let some exe := pkg.findLeanExe? target then
|
||||
resolveExeTarget pkg exe facet
|
||||
resolveExeTarget exe facet
|
||||
else if let some lib := pkg.findExternLib? target then
|
||||
if facet.isEmpty then
|
||||
return lib.target.withoutInfo
|
||||
else
|
||||
throw <| CliError.invalidFacet target facet
|
||||
else if let some lib := pkg.findLeanLib? target then
|
||||
resolveLibTarget pkg lib facet
|
||||
resolveLibTarget lib facet
|
||||
else if let some mod := pkg.findModule? target then
|
||||
resolveModuleTarget mod facet
|
||||
else
|
||||
|
|
@ -93,15 +93,15 @@ def resolvePackageTarget (pkg : Package) (facet : String) : Except CliError Opaq
|
|||
throw <| CliError.unknownFacet "package" facet
|
||||
|
||||
def resolveTargetInWorkspace (ws : Workspace) (spec : String) (facet : String) : Except CliError OpaqueTarget :=
|
||||
if let some (pkg, exe) := ws.findLeanExe? spec.toName then
|
||||
resolveExeTarget pkg exe facet
|
||||
else if let some (_, lib) := ws.findExternLib? spec.toName then
|
||||
if let some exe := ws.findLeanExe? spec.toName then
|
||||
resolveExeTarget exe facet
|
||||
else if let some lib := ws.findExternLib? spec.toName then
|
||||
if facet.isEmpty then
|
||||
return lib.target.withoutInfo
|
||||
else
|
||||
throw <| CliError.invalidFacet spec facet
|
||||
else if let some (pkg, lib) := ws.findLeanLib? spec.toName then
|
||||
resolveLibTarget pkg lib facet
|
||||
else if let some lib := ws.findLeanLib? spec.toName then
|
||||
resolveLibTarget lib facet
|
||||
else if let some pkg := ws.findPackage? spec.toName then
|
||||
resolvePackageTarget pkg facet
|
||||
else if let some mod := ws.findModule? spec.toName then
|
||||
|
|
|
|||
26
Lake/Config/ExternLib.lean
Normal file
26
Lake/Config/ExternLib.lean
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/-
|
||||
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.Config.Package
|
||||
|
||||
namespace Lake
|
||||
|
||||
/-- An external library -- its package plus its configuration. -/
|
||||
structure ExternLib where
|
||||
/-- The package the library belongs to. -/
|
||||
pkg : Package
|
||||
/-- The library's user-defined configuration. -/
|
||||
config : ExternLibConfig
|
||||
deriving Inhabited
|
||||
|
||||
/-- Try to find a external library in the package with the given name. -/
|
||||
@[inline] def Package.findExternLib? (name : Name) (self : Package) : Option ExternLib :=
|
||||
self.externLibConfigs.find? name |>.map (⟨self, ·⟩)
|
||||
|
||||
namespace ExternLib
|
||||
|
||||
/-- The external library's user-defined `target`. -/
|
||||
@[inline] def target (self : ExternLib) : FileTarget :=
|
||||
self.config.target
|
||||
19
Lake/Config/ExternLibConfig.lean
Normal file
19
Lake/Config/ExternLibConfig.lean
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/-
|
||||
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.TargetTypes
|
||||
|
||||
namespace Lake
|
||||
open Lean System
|
||||
|
||||
/-- A external library's declarative configuration. -/
|
||||
structure ExternLibConfig where
|
||||
/-- The name of the target. -/
|
||||
name : Name
|
||||
|
||||
/-- The library's build target. -/
|
||||
target : FileTarget
|
||||
|
||||
deriving Inhabited
|
||||
|
|
@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Mario Carneiro, Mac Malone
|
||||
-/
|
||||
import Lean.Util.Path
|
||||
import Lake.Util.Name
|
||||
|
||||
open Lean (Name)
|
||||
open System (FilePath)
|
||||
|
|
@ -22,29 +23,25 @@ deriving Inhabited, Repr
|
|||
|
||||
instance : Coe Name Glob := ⟨Glob.one⟩
|
||||
|
||||
def Glob.matches (m : Name) : (self : Glob) → Bool
|
||||
partial def forEachNoduleIn [Monad m] [MonadLiftT IO m]
|
||||
(dir : FilePath) (f : WfName → m PUnit) : m PUnit := do
|
||||
for entry in (← dir.readDir) do
|
||||
if (← liftM (m := IO) <| entry.path.isDir) then
|
||||
f entry.fileName
|
||||
else if entry.path.extension == some "lean" then
|
||||
f <| FilePath.withExtension entry.fileName "" |>.toString
|
||||
|
||||
namespace Glob
|
||||
|
||||
def «matches» (m : Name) : (self : Glob) → Bool
|
||||
| one n => n == m
|
||||
| submodules n => n.isPrefixOf m && n != m
|
||||
| andSubmodules n => n.isPrefixOf m
|
||||
|
||||
partial def pushSubmodules
|
||||
(rootDir : FilePath) (mod : Name) (arr : Array Name) : IO (Array Name) := do
|
||||
let mut arr := arr
|
||||
let dirPath := Lean.modToFilePath rootDir mod ""
|
||||
for entry in (← dirPath.readDir) do
|
||||
let path := entry.path
|
||||
if (← path.isDir) then
|
||||
arr ← pushSubmodules rootDir (mod ++ entry.fileName) arr
|
||||
else if path.extension == some "lean" then
|
||||
let fileName := FilePath.withExtension entry.fileName "" |>.toString
|
||||
arr := arr.push (mod ++ fileName)
|
||||
return arr
|
||||
|
||||
def Glob.pushModules
|
||||
(dir : FilePath) (arr : Array Name) : (self : Glob) → IO (Array Name)
|
||||
| one n => pure #[n]
|
||||
| submodules n => pushSubmodules dir n arr
|
||||
| andSubmodules n => pushSubmodules dir n (arr.push n)
|
||||
|
||||
def Glob.getModules (dir : FilePath) (self : Glob) : IO (Array Name) :=
|
||||
self.pushModules dir #[]
|
||||
def forEachModuleIn [Monad m] [MonadLiftT IO m]
|
||||
(dir : FilePath) (f : WfName → m PUnit) : (self : Glob) → m PUnit
|
||||
| one n => f (WfName.ofName n)
|
||||
| submodules n => forEachNoduleIn (Lean.modToFilePath dir n "") f
|
||||
| andSubmodules n =>
|
||||
f (WfName.ofName n) *>
|
||||
forEachNoduleIn (Lean.modToFilePath dir n "") f
|
||||
|
|
|
|||
54
Lake/Config/LeanExe.lean
Normal file
54
Lake/Config/LeanExe.lean
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/-
|
||||
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.Config.Module
|
||||
|
||||
namespace Lake
|
||||
open Lean System
|
||||
|
||||
/-- A Lean executable -- its package plus its configuration. -/
|
||||
structure LeanExe where
|
||||
/-- The package the executable belongs to. -/
|
||||
pkg : Package
|
||||
/-- The executable's user-defined configuration. -/
|
||||
config : LeanExeConfig
|
||||
deriving Inhabited
|
||||
|
||||
/-- The Lean executable built into the package. -/
|
||||
@[inline] def Package.builtinExe (self : Package) : LeanExe :=
|
||||
⟨self, self.builtinExeConfig⟩
|
||||
|
||||
/-- Try to find a Lean executable in the package with the given name. -/
|
||||
@[inline] def Package.findLeanExe? (name : Name) (self : Package) : Option LeanExe :=
|
||||
self.leanExeConfigs.find? name |>.map (⟨self, ·⟩)
|
||||
|
||||
namespace LeanExe
|
||||
|
||||
/-- The executable's root module. -/
|
||||
@[inline] def root (self : LeanExe) : Module :=
|
||||
⟨self.pkg, WfName.ofName self.config.root⟩
|
||||
|
||||
/--
|
||||
The file name of binary executable
|
||||
(i.e., `exeName` plus the platform's `exeExtension`).
|
||||
-/
|
||||
@[inline] def fileName (self : LeanExe) : FilePath :=
|
||||
FilePath.withExtension self.config.exeName FilePath.exeExtension
|
||||
|
||||
/-- The path to the executable in the package's `binDir`. -/
|
||||
@[inline] def file (self : LeanExe) : FilePath :=
|
||||
self.pkg.binDir / self.fileName
|
||||
|
||||
/--
|
||||
The arguments to pass to `leanc` when linking the binary executable.
|
||||
|
||||
That is, `-rdynamic` (if non-Windows and `supportInterpreter`) plus the
|
||||
package's and then the executable's `moreLinkArgs`.
|
||||
-/
|
||||
def linkArgs (self : LeanExe) : Array String :=
|
||||
if self.config.supportInterpreter && !Platform.isWindows then
|
||||
#["-rdynamic"] ++ self.pkg.moreLinkArgs ++ self.config.moreLinkArgs
|
||||
else
|
||||
self.pkg.moreLinkArgs ++ self.config.moreLinkArgs
|
||||
50
Lake/Config/LeanExeConfig.lean
Normal file
50
Lake/Config/LeanExeConfig.lean
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/-
|
||||
Copyright (c) 2022 Mac Malone. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Mac Malone
|
||||
-/
|
||||
namespace Lake
|
||||
open Lean System
|
||||
|
||||
/-- A Lean executable's declarative configuration. -/
|
||||
structure LeanExeConfig where
|
||||
/-- The name of the target. -/
|
||||
name : Name
|
||||
|
||||
/--
|
||||
The root module of the binary executable.
|
||||
Should include a `main` definition that will serve
|
||||
as the entry point of the program.
|
||||
|
||||
The root is built by recursively building its
|
||||
local imports (i.e., fellow modules of the workspace).
|
||||
|
||||
Defaults to the name of the target.
|
||||
-/
|
||||
root : Name := name
|
||||
|
||||
/--
|
||||
The name of the binary executable.
|
||||
Defaults to the target name with any `.` replaced with a `-`.
|
||||
-/
|
||||
exeName : String := name.toStringWithSep "-" (escape := false)
|
||||
|
||||
/--
|
||||
Whether to expose symbols within the executable to the Lean interpreter.
|
||||
This allows the executable to interpret Lean files (e.g., via
|
||||
`Lean.Elab.runFrontend`).
|
||||
|
||||
Implementation-wise, this passes `-rdynamic` to the linker when building
|
||||
on non-Windows systems.
|
||||
|
||||
Defaults to `false`.
|
||||
-/
|
||||
supportInterpreter : Bool := false
|
||||
|
||||
/--
|
||||
Additional arguments to pass to `leanc` when linking the binary executable.
|
||||
These will come *after* the paths of the package's external libraries.
|
||||
-/
|
||||
moreLinkArgs : Array String := #[]
|
||||
|
||||
deriving Inhabited, Repr
|
||||
72
Lake/Config/LeanLib.lean
Normal file
72
Lake/Config/LeanLib.lean
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/-
|
||||
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.Config.Package
|
||||
|
||||
namespace Lake
|
||||
open Lean System
|
||||
|
||||
/-- A Lean library -- its package plus its configuration. -/
|
||||
structure LeanLib where
|
||||
/-- The package the library belongs to. -/
|
||||
pkg : Package
|
||||
/-- The library's user-defined configuration. -/
|
||||
config : LeanLibConfig
|
||||
deriving Inhabited
|
||||
|
||||
/-- The Lean library built into the package. -/
|
||||
@[inline] def Package.builtinLib (self : Package) : LeanLib :=
|
||||
⟨self, self.builtinLibConfig⟩
|
||||
|
||||
/-- Try to find a Lean library in the package with the given name. -/
|
||||
@[inline] def Package.findLeanLib? (name : Name) (self : Package) : Option LeanLib :=
|
||||
self.leanLibConfigs.find? name |>.map (⟨self, ·⟩)
|
||||
|
||||
namespace LeanLib
|
||||
|
||||
/- The package's `srcDir` joined with the library's `srcDir`. -/
|
||||
def srcDir (self : LeanLib) : FilePath :=
|
||||
self.pkg.srcDir / self.config.srcDir
|
||||
|
||||
/-- Whether the given module is considered local to the library. -/
|
||||
@[inline] def isLocalModule (mod : Name) (self : LeanLib) : Bool :=
|
||||
self.config.isLocalModule mod
|
||||
|
||||
/-- Whether the given module is a buildable part of the library. -/
|
||||
@[inline] def isBuildableModule (mod : Name) (self : LeanLib) : Bool :=
|
||||
self.config.isBuildableModule mod
|
||||
|
||||
/-- The file name of the library's static binary (i.e., `lib{libName}.a`) -/
|
||||
def staticLibFileName (self : LeanLib) : FilePath :=
|
||||
s!"lib{self.config.libName}.a"
|
||||
|
||||
/-- The path to the static library in the package's `libDir`. -/
|
||||
def staticLibFile (self : LeanLib) : FilePath :=
|
||||
self.pkg.libDir / self.staticLibFileName
|
||||
|
||||
/-- The file name of the library's shared binary (i.e., its `dll`/`dylib`/`so`) . -/
|
||||
def sharedLibFileName (self : LeanLib) : FilePath :=
|
||||
s!"{self.config.libName}.{sharedLibExt}"
|
||||
|
||||
/-- The path to the shared library in the package's `libDir`. -/
|
||||
def sharedLibFile (self : LeanLib) : FilePath :=
|
||||
self.pkg.libDir / self.sharedLibFileName
|
||||
|
||||
/--
|
||||
The arguments to pass to `leanc` when compiling the library's C files.
|
||||
It is `-O3`, `-DNDEBUG`, the package's `moreLeancArgs`, and then the library's
|
||||
`moreLeancArgs`.
|
||||
|
||||
TODO: Use this option.
|
||||
-/
|
||||
def leancArgs (self : LeanLib) : Array String :=
|
||||
self.pkg.moreLeancArgs ++ self.config.moreLeancArgs
|
||||
|
||||
/--
|
||||
The arguments to pass to `leanc` when linking the shared library.
|
||||
That is, the package's `moreLinkArgs` plus the library's `moreLinkArgs`.
|
||||
-/
|
||||
def linkArgs (self : LeanLib) : Array String :=
|
||||
self.pkg.moreLinkArgs ++ self.config.moreLinkArgs
|
||||
80
Lake/Config/LeanLibConfig.lean
Normal file
80
Lake/Config/LeanLibConfig.lean
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/-
|
||||
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.Util.Casing
|
||||
import Lake.Config.InstallPath
|
||||
import Lake.Config.Glob
|
||||
|
||||
namespace Lake
|
||||
open Lean System
|
||||
|
||||
/-- A Lean library's declarative configuration. -/
|
||||
structure LeanLibConfig where
|
||||
/-- The name of the target. -/
|
||||
name : Name
|
||||
|
||||
/--
|
||||
The subdirectory of the package containing the library's Lean source files.
|
||||
Defaults to the package's `srcDir`.
|
||||
|
||||
(This will be passed to `lean` as the `-R` option.)
|
||||
-/
|
||||
srcDir : FilePath := "."
|
||||
|
||||
/--
|
||||
The root module(s) of the library.
|
||||
|
||||
Submodules of these roots (e.g., `Lib.Foo` of `Lib`) are considered
|
||||
part of the package.
|
||||
|
||||
Defaults to a single root of the library's upper camel case name.
|
||||
-/
|
||||
roots : Array Name := #[toUpperCamelCase name]
|
||||
|
||||
/--
|
||||
An `Array` of module `Glob`s to build for the library.
|
||||
Defaults to a `Glob.one` of each of the library's `roots`.
|
||||
|
||||
Submodule globs build every source file within their directory.
|
||||
Local imports of glob'ed files (i.e., fellow modules of the workspace) are
|
||||
also recursively built.
|
||||
-/
|
||||
globs : Array Glob := roots.map Glob.one
|
||||
|
||||
/--
|
||||
The name of the library.
|
||||
Used as a base for the file names of its static and dynamic binaries.
|
||||
Defaults to the upper camel case name of the target.
|
||||
-/
|
||||
libName := toUpperCamelCase name |>.toString (escape := false)
|
||||
|
||||
/--
|
||||
Additional arguments to pass to `leanc`
|
||||
while compiling the library's C source files generated by `lean`.
|
||||
|
||||
Lake already passes `-O3` and `-DNDEBUG` automatically,
|
||||
but you can change this by, for example, adding `-O0` and `-UNDEBUG`.
|
||||
-/
|
||||
moreLeancArgs : Array String := #[]
|
||||
|
||||
/--
|
||||
Additional arguments to pass to `leanc` while linking the shared library.
|
||||
These will come *after* the paths of package's external libraries.
|
||||
-/
|
||||
moreLinkArgs : Array String := #[]
|
||||
|
||||
deriving Inhabited, Repr
|
||||
|
||||
namespace LeanLibConfig
|
||||
|
||||
/-- Whether the given module is considered local to the library. -/
|
||||
def isLocalModule (mod : Name) (self : LeanLibConfig) : Bool :=
|
||||
self.roots.any (fun root => root.isPrefixOf mod) ||
|
||||
self.globs.any (fun glob => glob.matches mod)
|
||||
|
||||
/-- Whether the given module is a buildable part of the library. -/
|
||||
def isBuildableModule (mod : Name) (self : LeanLibConfig) : Bool :=
|
||||
self.globs.any (fun glob => glob.matches mod) ||
|
||||
self.roots.any (fun root => root.isPrefixOf mod && self.globs.any (·.matches root))
|
||||
|
|
@ -107,22 +107,24 @@ unsafe def loadUnsafe (dir : FilePath) (args : List String := [])
|
|||
let config := {config with dependencies := depsExt.getState env ++ config.dependencies}
|
||||
let scripts ← scriptAttr.ext.getState env |>.foldM (init := {})
|
||||
fun m d => return m.insert d <| ← evalScriptDecl env d leanOpts
|
||||
let leanLibs ← leanLibAttr.ext.getState env |>.foldM (init := {}) fun m d =>
|
||||
let leanLibConfigs ← leanLibAttr.ext.getState env |>.foldM (init := {}) fun m d =>
|
||||
let eval := env.evalConstCheck LeanLibConfig leanOpts ``LeanLibConfig d
|
||||
return m.insert d <| ← IO.ofExcept eval.run.run
|
||||
let leanExes ← leanExeAttr.ext.getState env |>.foldM (init := {}) fun m d =>
|
||||
let leanExeConfigs ← leanExeAttr.ext.getState env |>.foldM (init := {}) fun m d =>
|
||||
let eval := env.evalConstCheck LeanExeConfig leanOpts ``LeanExeConfig d
|
||||
return m.insert d <| ← IO.ofExcept eval.run.run
|
||||
let externLibs ← externLibAttr.ext.getState env |>.foldM (init := {}) fun m d =>
|
||||
let externLibConfigs ← externLibAttr.ext.getState env |>.foldM (init := {}) fun m d =>
|
||||
let eval := env.evalConstCheck ExternLibConfig leanOpts ``ExternLibConfig d
|
||||
return m.insert d <| ← IO.ofExcept eval.run.run
|
||||
|
||||
|
||||
if leanLibs.isEmpty && leanExes.isEmpty && config.defaultFacet ≠ .none then
|
||||
if leanLibConfigs.isEmpty && leanExeConfigs.isEmpty && config.defaultFacet ≠ .none then
|
||||
logWarning <| "Package targets are deprecated. " ++
|
||||
"Add a `lean_exe` and/or `lean_lib` default target to the package instead."
|
||||
let defaultTargets := defaultTargetAttr.ext.getState env |>.toArray
|
||||
return {dir, config, scripts, leanLibs, leanExes, externLibs, defaultTargets}
|
||||
return {
|
||||
dir, config, scripts,
|
||||
leanLibConfigs, leanExeConfigs, externLibConfigs,
|
||||
defaultTargets
|
||||
}
|
||||
| _ => error s!"configuration file has multiple `package` declarations"
|
||||
else
|
||||
error s!"package configuration `{configFile}` has errors"
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Mac Malone
|
||||
-/
|
||||
import Lake.Build.Trace
|
||||
import Lake.Config.Package
|
||||
import Lake.Util.Name
|
||||
import Lake.Config.LeanLib
|
||||
|
||||
namespace Lake
|
||||
open Std System
|
||||
|
|
@ -22,7 +21,19 @@ abbrev ModuleSet := RBTree Module (·.name.quickCmp ·.name)
|
|||
abbrev ModuleMap (α) := RBMap Module α (·.name.quickCmp ·.name)
|
||||
@[inline] def ModuleMap.empty : ModuleMap α := RBMap.empty
|
||||
|
||||
/-- Locate the named module in the package (if it is local to it). -/
|
||||
/-- 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 ⟨self.pkg, 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 ⟨self.pkg, mod⟩)
|
||||
|
||||
/-- Locate the named module in the package (if it is buildable and local to it). -/
|
||||
def Package.findModule? (mod : Name) (self : Package) : Option Module :=
|
||||
let mod := WfName.ofName mod
|
||||
if self.isBuildableModule mod then some ⟨self, mod⟩ else none
|
||||
|
|
|
|||
|
|
@ -3,13 +3,11 @@ Copyright (c) 2017 Microsoft Corporation. All rights reserved.
|
|||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Gabriel Ebner, Sebastian Ullrich, Mac Malone
|
||||
-/
|
||||
import Lake.Util.Name
|
||||
import Lake.Util.String
|
||||
import Lake.Build.TargetTypes
|
||||
import Lake.Config.Glob
|
||||
import Lake.Config.Opaque
|
||||
import Lake.Config.LeanLibConfig
|
||||
import Lake.Config.LeanExeConfig
|
||||
import Lake.Config.ExternLibConfig
|
||||
import Lake.Config.WorkspaceConfig
|
||||
import Lake.Config.Targets
|
||||
import Lake.Config.Dependency
|
||||
import Lake.Config.Script
|
||||
|
||||
|
|
@ -31,7 +29,7 @@ def defaultBinDir : FilePath := "bin"
|
|||
def defaultLibDir : FilePath := "lib"
|
||||
|
||||
/-- The default setting for a `PackageConfig`'s `oleanDir` option. -/
|
||||
def defaultOleanDir : FilePath := "lib"
|
||||
def defaultOleanDir : FilePath := defaultLibDir
|
||||
|
||||
/-- The default setting for a `PackageConfig`'s `irDir` option. -/
|
||||
def defaultIrDir : FilePath := "ir"
|
||||
|
|
@ -281,18 +279,18 @@ end PackageConfig
|
|||
structure Package where
|
||||
/-- The path to the package's directory. -/
|
||||
dir : FilePath
|
||||
/-- The package's configuration. -/
|
||||
/-- The package's user-defined configuration. -/
|
||||
config : PackageConfig
|
||||
/-- The package's well-formed name. -/
|
||||
name : WfName := WfName.ofName config.name
|
||||
/-- Scripts for the package. -/
|
||||
scripts : NameMap Script := {}
|
||||
/-- Lean library targets for the package. -/
|
||||
leanLibs : NameMap LeanLibConfig := {}
|
||||
/-- Lean binary executable targets for the package. -/
|
||||
leanExes : NameMap LeanExeConfig := {}
|
||||
/-- Lean library configurations for the package. -/
|
||||
leanLibConfigs : NameMap LeanLibConfig := {}
|
||||
/-- Lean binary executable configurations for the package. -/
|
||||
leanExeConfigs : NameMap LeanExeConfig := {}
|
||||
/-- External library targets for the package. -/
|
||||
externLibs : NameMap ExternLibConfig := {}
|
||||
externLibConfigs : NameMap ExternLibConfig := {}
|
||||
/--
|
||||
The names of the package's targets to build by default
|
||||
(i.e., on a bare `lake build` of the package).
|
||||
|
|
@ -350,21 +348,9 @@ namespace Package
|
|||
@[inline] def defaultFacet (self : Package) : PackageFacet :=
|
||||
self.config.defaultFacet
|
||||
|
||||
/-- Get the package's library configuration with the given name. -/
|
||||
@[inline] def findLeanLib? (name : Name) (self : Package) : Option LeanLibConfig :=
|
||||
self.leanLibs.find? name
|
||||
|
||||
/-- Get the package's executable configuration with the given name. -/
|
||||
@[inline] def findLeanExe? (name : Name) (self : Package) : Option LeanExeConfig :=
|
||||
self.leanExes.find? name
|
||||
|
||||
/-- Get the package's external library target with the given name. -/
|
||||
@[inline] def findExternLib? (name : Name) (self : Package) : Option ExternLibConfig :=
|
||||
self.externLibs.find? name
|
||||
|
||||
/-- Get an `Array` of the package's external library targets. -/
|
||||
def externLibTargets (self : Package) : Array FileTarget :=
|
||||
self.externLibs.fold (fun xs _ x => xs.push x.target) #[] ++
|
||||
self.externLibConfigs.fold (fun xs _ x => xs.push x.target) #[] ++
|
||||
self.config.moreLibTargets
|
||||
|
||||
/-- The package's `precompileModules` configuration. -/
|
||||
|
|
@ -403,6 +389,10 @@ def externLibTargets (self : Package) : Array FileTarget :=
|
|||
@[inline] def moreLeancArgs (self : Package) : Array String :=
|
||||
#["-O3", "-DNDEBUG"] ++ self.config.moreLeancArgs
|
||||
|
||||
/-- The package's `moreLinkArgs` configuration. -/
|
||||
@[inline] def moreLinkArgs (self : Package) : Array String :=
|
||||
self.config.moreLinkArgs
|
||||
|
||||
/-- The package's `buildDir` joined with its `irDir` configuration. -/
|
||||
@[inline] def irDir (self : Package) : FilePath :=
|
||||
self.buildDir / self.config.irDir
|
||||
|
|
@ -423,18 +413,14 @@ def externLibTargets (self : Package) : Array FileTarget :=
|
|||
@[inline] def builtinExeConfig (self : Package) : LeanExeConfig :=
|
||||
self.config.toLeanExeConfig
|
||||
|
||||
/-- Get an `Array` of the package's modules. -/
|
||||
@[inline] def getModuleArray (self : Package) : IO (Array Name) :=
|
||||
self.builtinLibConfig.getModuleArray self.srcDir
|
||||
|
||||
/-- Whether the given module is considered local to the package. -/
|
||||
def isLocalModule (mod : Name) (self : Package) : Bool :=
|
||||
self.leanLibs.any (fun _ lib => lib.isLocalModule mod) ||
|
||||
self.leanLibConfigs.any (fun _ lib => lib.isLocalModule mod) ||
|
||||
self.builtinLibConfig.isLocalModule mod
|
||||
|
||||
/-- Whether the given module is in the package (i.e., can build it). -/
|
||||
def isBuildableModule (mod : Name) (self : Package) : Bool :=
|
||||
self.leanLibs.any (fun _ lib => lib.isBuildableModule mod) ||
|
||||
self.leanExes.any (fun _ exe => exe.root == mod) ||
|
||||
self.leanLibConfigs.any (fun _ lib => lib.isBuildableModule mod) ||
|
||||
self.leanExeConfigs.any (fun _ exe => exe.root == mod) ||
|
||||
self.builtinLibConfig.isBuildableModule mod ||
|
||||
self.config.binRoot == mod
|
||||
|
|
|
|||
|
|
@ -1,173 +0,0 @@
|
|||
/-
|
||||
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.Util.String
|
||||
import Lake.Build.TargetTypes
|
||||
import Lake.Config.Glob
|
||||
|
||||
namespace Lake
|
||||
open Lean System
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- # Lean Library Build Configuration
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
/-- A Lean library's declarative configuration. -/
|
||||
structure LeanLibConfig where
|
||||
/-- The name of the target. -/
|
||||
name : Name
|
||||
|
||||
/--
|
||||
The root module(s) of the library.
|
||||
|
||||
Submodules of these roots (e.g., `Lib.Foo` of `Lib`) are considered
|
||||
part of the package.
|
||||
|
||||
Defaults to a single root of the library's upper camel case name.
|
||||
-/
|
||||
roots : Array Name := #[toUpperCamelCase name]
|
||||
|
||||
/--
|
||||
An `Array` of module `Glob`s to build for the library.
|
||||
Defaults to a `Glob.one` of each of the library's `roots`.
|
||||
|
||||
Submodule globs build every source file within their directory.
|
||||
Local imports of glob'ed files (i.e., fellow modules of the workspace) are
|
||||
also recursively built.
|
||||
-/
|
||||
globs : Array Glob := roots.map Glob.one
|
||||
|
||||
/--
|
||||
The name of the library.
|
||||
Used as a base for the file names of its static and dynamic binaries.
|
||||
Defaults to the upper camel case name of the target.
|
||||
-/
|
||||
libName := toUpperCamelCase name |>.toString (escape := false)
|
||||
|
||||
/--
|
||||
Additional arguments to pass to `leanc` while linking the shared library.
|
||||
These will come *after* the paths of package's external libraries.
|
||||
-/
|
||||
moreLinkArgs : Array String := #[]
|
||||
|
||||
deriving Inhabited, Repr
|
||||
|
||||
namespace LeanLibConfig
|
||||
|
||||
/-- Whether the given module is considered local to the library. -/
|
||||
def isLocalModule (mod : Name) (self : LeanLibConfig) : Bool :=
|
||||
self.roots.any (fun root => root.isPrefixOf mod) ||
|
||||
self.globs.any (fun glob => glob.matches mod)
|
||||
|
||||
/-- Whether the given module is a buildable part of the library. -/
|
||||
def isBuildableModule (mod : Name) (self : LeanLibConfig) : Bool :=
|
||||
self.globs.any (fun glob => glob.matches mod) ||
|
||||
self.roots.any (fun root => root.isPrefixOf mod && self.globs.any (·.matches root))
|
||||
|
||||
/-- Get an `Array` of the library's modules. -/
|
||||
def getModuleArray (self : LeanLibConfig) (srcDir : FilePath) : IO (Array Name) := do
|
||||
let mut mods := #[]
|
||||
for glob in self.globs do
|
||||
mods ← glob.pushModules srcDir mods
|
||||
return mods
|
||||
|
||||
/-- The file name of package's static library (i.e., `lib{libName}.a`) -/
|
||||
def staticLibFileName (self : LeanLibConfig) : FilePath :=
|
||||
s!"lib{self.libName}.a"
|
||||
|
||||
/-- The file name of package's shared library. -/
|
||||
def sharedLibFileName (self : LeanLibConfig) : FilePath :=
|
||||
s!"{self.libName}.{sharedLibExt}"
|
||||
|
||||
/--
|
||||
The arguments to pass to `leanc` when linking the shared library.
|
||||
Just `moreLinkArgs`.
|
||||
-/
|
||||
def linkArgs (self : LeanLibConfig) : Array String :=
|
||||
self.moreLinkArgs
|
||||
|
||||
end LeanLibConfig
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- # Lean Executable Build Configuration
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
/-- A Lean executable's declarative configuration. -/
|
||||
structure LeanExeConfig where
|
||||
/-- The name of the target. -/
|
||||
name : Name
|
||||
|
||||
/--
|
||||
The root module of the binary executable.
|
||||
Should include a `main` definition that will serve
|
||||
as the entry point of the program.
|
||||
|
||||
The root is built by recursively building its
|
||||
local imports (i.e., fellow modules of the workspace).
|
||||
|
||||
Defaults to the name of the target.
|
||||
-/
|
||||
root : Name := name
|
||||
|
||||
/--
|
||||
The name of the binary executable.
|
||||
Defaults to the target name with any `.` replaced with a `-`.
|
||||
-/
|
||||
exeName : String := name.toStringWithSep "-" (escape := false)
|
||||
|
||||
/--
|
||||
Whether to expose symbols within the executable to the Lean interpreter.
|
||||
This allows the executable to interpret Lean files (e.g., via
|
||||
`Lean.Elab.runFrontend`).
|
||||
|
||||
Implementation-wise, this passes `-rdynamic` to the linker when building
|
||||
on non-Windows systems.
|
||||
|
||||
Defaults to `false`.
|
||||
-/
|
||||
supportInterpreter : Bool := false
|
||||
|
||||
/--
|
||||
Additional arguments to pass to `leanc` when linking the binary executable.
|
||||
These will come *after* the paths of the package's external libraries.
|
||||
-/
|
||||
moreLinkArgs : Array String := #[]
|
||||
|
||||
deriving Inhabited, Repr
|
||||
|
||||
namespace LeanExeConfig
|
||||
|
||||
/--
|
||||
The file name of binary executable
|
||||
(i.e., `exeName` plus the platform's `exeExtension`).
|
||||
-/
|
||||
def fileName (self : LeanExeConfig) : FilePath :=
|
||||
FilePath.withExtension self.exeName FilePath.exeExtension
|
||||
|
||||
/--
|
||||
The arguments to pass to `leanc` when linking the binary executable.
|
||||
`-rdynamic` (if non-Windows and `supportInterpreter`) plus `moreLinkArgs`.
|
||||
-/
|
||||
def linkArgs (self : LeanExeConfig) : Array String :=
|
||||
if self.supportInterpreter && !Platform.isWindows then
|
||||
#["-rdynamic"] ++ self.moreLinkArgs
|
||||
else
|
||||
self.moreLinkArgs
|
||||
|
||||
end LeanExeConfig
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- # External Library Build Configuration
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
/-- A external library's declarative configuration. -/
|
||||
structure ExternLibConfig where
|
||||
/-- The name of the target. -/
|
||||
name : Name
|
||||
|
||||
/-- The library's build target. -/
|
||||
target : FileTarget
|
||||
|
||||
deriving Inhabited
|
||||
|
|
@ -4,10 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Mac Malone
|
||||
-/
|
||||
import Lean.Util.Paths
|
||||
import Lake.Config.Opaque
|
||||
import Lake.Config.WorkspaceConfig
|
||||
import Lake.Config.Package
|
||||
import Lake.Config.Module
|
||||
import Lake.Config.LeanExe
|
||||
import Lake.Config.ExternLib
|
||||
|
||||
open System
|
||||
open Lean (LeanPaths)
|
||||
|
|
@ -92,17 +90,17 @@ def isLocalModule (mod : Name) (self : Workspace) : Bool :=
|
|||
def findModule? (mod : Name) (self : Workspace) : Option Module :=
|
||||
self.packageArray.findSome? (·.findModule? mod)
|
||||
|
||||
/-- Get the workspace's library configuration with the given name. -/
|
||||
def findLeanLib? (name : Name) (self : Workspace) : Option (Package × LeanLibConfig) :=
|
||||
self.packageArray.findSome? fun pkg => pkg.findLeanLib? name <&> (pkg, ·)
|
||||
/-- Try to find a Lean library in the workspace with the given name. -/
|
||||
def findLeanLib? (name : Name) (self : Workspace) : Option LeanLib :=
|
||||
self.packageArray.findSome? fun pkg => pkg.findLeanLib? name
|
||||
|
||||
/-- Get the workspace's executable configuration with the given name. -/
|
||||
def findLeanExe? (name : Name) (self : Workspace) : Option (Package × LeanExeConfig) :=
|
||||
self.packageArray.findSome? fun pkg => pkg.findLeanExe? name <&> (pkg, ·)
|
||||
/-- Try to find a Lean executable in the workspace with the given name. -/
|
||||
def findLeanExe? (name : Name) (self : Workspace) : Option LeanExe :=
|
||||
self.packageArray.findSome? fun pkg => pkg.findLeanExe? name
|
||||
|
||||
/-- Get the workspace's external library with the given name. -/
|
||||
def findExternLib? (name : Name) (self : Workspace) : Option (Package × ExternLibConfig) :=
|
||||
self.packageArray.findSome? fun pkg => pkg.findExternLib? name <&> (pkg, ·)
|
||||
def findExternLib? (name : Name) (self : Workspace) : Option ExternLib :=
|
||||
self.packageArray.findSome? fun pkg => pkg.findExternLib? name
|
||||
|
||||
/-- The `LEAN_PATH` of the workspace. -/
|
||||
def oleanPath (self : Workspace) : SearchPath :=
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ Authors: Mac Malone
|
|||
-/
|
||||
import Lake.DSL.DeclUtil
|
||||
import Lake.DSL.Attributes
|
||||
import Lake.Config.Targets
|
||||
import Lake.Config.LeanExeConfig
|
||||
import Lake.Config.LeanLibConfig
|
||||
import Lake.Config.ExternLibConfig
|
||||
|
||||
namespace Lake.DSL
|
||||
open Lean Parser Command
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ def WellFormed.elimNum : WellFormed (Name.num p v h) → WellFormed p
|
|||
| numWff w rfl => w
|
||||
|
||||
theorem eq_of_wf_quickCmpAux
|
||||
(n : Name) (w : Name.WellFormed n) (n' : Name) (w' : Name.WellFormed n')
|
||||
(n : Name) (w : WellFormed n) (n' : Name) (w' : WellFormed n')
|
||||
: Name.quickCmpAux n n' = Ordering.eq → n = n' := by
|
||||
revert n'
|
||||
induction w with
|
||||
|
|
@ -84,6 +84,20 @@ theorem eq_of_wf_quickCmpAux
|
|||
next =>
|
||||
contradiction
|
||||
|
||||
theorem wf_of_append {n n' : Name}
|
||||
(w : WellFormed n) (w' : WellFormed n') : WellFormed (n.append n') := by
|
||||
induction w' with
|
||||
| anonymousWff =>
|
||||
simp [w, Name.append]
|
||||
| @strWff n' p s w' h' ih =>
|
||||
unfold Name.mkStr at h'
|
||||
simp only [Name.append, h']
|
||||
exact WellFormed.strWff ih rfl
|
||||
| @numWff n' p v w' h' ih =>
|
||||
unfold Name.mkNum at h'
|
||||
simp only [Name.append, h']
|
||||
exact WellFormed.numWff ih rfl
|
||||
|
||||
end Name
|
||||
|
||||
-- # Subtype Helpers
|
||||
|
|
@ -144,6 +158,11 @@ def ofName : Name → WfName
|
|||
| .str p s _ => mkStr (ofName p) s
|
||||
| .num p v _ => mkNum (ofName p) v
|
||||
|
||||
def ofString (str : String) : WfName :=
|
||||
str.splitOn "." |>.foldl (fun n p => mkStr n p.trim) anonymous
|
||||
|
||||
instance : Coe String WfName := ⟨ofString⟩
|
||||
|
||||
@[inline] protected def toString (escape := true) : WfName → String
|
||||
| ⟨n, _⟩ => n.toString escape
|
||||
|
||||
|
|
@ -152,6 +171,14 @@ def ofName : Name → WfName
|
|||
|
||||
instance : ToString WfName := ⟨(·.toString)⟩
|
||||
|
||||
def isPrefixOf : WfName → WfName → Bool
|
||||
| ⟨n, _⟩, ⟨n', _⟩ => n.isPrefixOf n'
|
||||
|
||||
def append : WfName → WfName → WfName
|
||||
| ⟨n, w⟩, ⟨n', w'⟩ => ⟨n.append n', Name.wf_of_append w w'⟩
|
||||
|
||||
instance : Append WfName := ⟨append⟩
|
||||
|
||||
@[inline] protected def hash : WfName → UInt64
|
||||
| ⟨n, _⟩ => n.hash
|
||||
|
||||
|
|
|
|||
4
examples/init/.gitignore
vendored
4
examples/init/.gitignore
vendored
|
|
@ -1,2 +1,2 @@
|
|||
/helloNew
|
||||
/helloInit
|
||||
/hello_world
|
||||
/hello-world
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue