feat: add isLeanOnly package config

closes leanprover/lake#74
This commit is contained in:
tydeu 2022-06-24 18:35:14 -04:00
parent 961a328bfd
commit 45ff2dbc9d
7 changed files with 57 additions and 42 deletions

View file

@ -25,22 +25,13 @@ def Workspace.processImportList
localImports := localImports.push mod
return localImports
/--
Whether the package is "lean-only".
That is, whether it has no need to build native files (e.g. `.c`).
A package is considered lean-only if the package does not include any executable
targets and is not precompiled.
-/
def Package.isLeanOnly (self : Package): Bool :=
self.leanExes.isEmpty && self.defaultFacet matches .none | .leanLib | .oleans
/--
Builds the workspace-local modules of list of imports.
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 "lean-only"
(see `isLeanOnly`). Otherwise, also build `.c` files.
Builds only module `.olean` and `.ilean` files if the package is configured
as "Lean-only". Otherwise, also build `.c` and `.o` files.
-/
def Package.buildImportsAndDeps (imports : List String) (self : Package) : BuildM (Array FilePath) := do
if imports.isEmpty then
@ -53,10 +44,10 @@ def Package.buildImportsAndDeps (imports : List String) (self : Package) : Build
let (res, bStore) ← EStateT.run BuildStore.empty <| mods.mapM fun mod =>
if mod.shouldPrecompile then
buildModuleTop mod &`lean.dynlib <&> (·.withoutInfo)
else if self.isLeanOnly then
buildModuleTop mod &`lean.c <&> (·.withoutInfo)
else
else if mod.isLeanOnly then
buildModuleTop mod &`lean
else
buildModuleTop mod &`lean.o <&> (·.withoutInfo)
let importTargets ← failOnBuildCycle res
let dynlibTargets := bStore.collectModuleFacetArray &`lean.dynlib
importTargets.forM (·.buildOpaque)

View file

@ -75,9 +75,15 @@ the initial set of Lake module facets (e.g., `lean.{imports, c, o, dynlib]`).
-- Compute unique imports (direct × transitive)
|>.insert &`lean.imports (mkModuleFacetBuild (·.recParseImports))
-- Build module (`.olean` and `.ilean`)
|>.insert &`lean (mkModuleFacetBuild (·.recBuildLean false))
|>.insert &`olean (mkModuleFacetBuild (·.recBuildFacet &`lean))
|>.insert &`ilean (mkModuleFacetBuild (·.recBuildFacet &`lean))
|>.insert &`lean (mkModuleFacetBuild (fun mod => do
mod.recBuildLean !mod.isLeanOnly
))
|>.insert &`olean (mkModuleFacetBuild (fun mod => do
mod.recBuildLean (!mod.isLeanOnly) <&> (·.withInfo mod.oleanFile)
))
|>.insert &`ilean (mkModuleFacetBuild (fun mod => do
mod.recBuildLean (!mod.isLeanOnly) <&> (·.withInfo mod.ileanFile)
))
-- Build module `.c` (and `.olean` and `.ilean`)
|>.insert &`lean.c (mkModuleFacetBuild <| fun mod => do
mod.recBuildLean true <&> (·.withInfo mod.cFile)

View file

@ -54,10 +54,10 @@ abbrev IndexT (m : Type → Type v) := EquipT (IndexBuildFn m) m
module_data lean : ActiveOpaqueTarget
/-- The `olean` file produced by `lean` -/
module_data olean : ActiveOpaqueTarget
module_data olean : ActiveFileTarget
/-- The `ilean` file produced by `lean` -/
module_data ilean : ActiveOpaqueTarget
module_data ilean : ActiveFileTarget
/-- The C file built from the Lean file via `lean` -/
module_data lean.c : ActiveFileTarget

View file

@ -82,8 +82,8 @@ optionally outputting a `.c` file as well if `c` is set to `true`.
<| ← dynlibsTarget.mixOpaqueAsync importTarget
let modTarget ← mod.soloTarget dynlibsTarget.info depTarget c |>.activate
store (mod.mkBuildKey &`lean) modTarget
store (mod.mkBuildKey &`olean) modTarget
store (mod.mkBuildKey &`ilean) modTarget
store (mod.mkBuildKey &`olean) <| modTarget.withInfo mod.oleanFile
store (mod.mkBuildKey &`ilean) <| modTarget.withInfo mod.ileanFile
if c then
let cTarget ← mod.mkCTarget (Target.active modTarget) |>.activate
store (mod.mkBuildKey &`lean.c) cTarget

View file

@ -66,6 +66,9 @@ def dynlib (self : Module) : FilePath :=
@[inline] def shouldPrecompile (self : Module) : Bool :=
self.pkg.precompileModules
@[inline] def isLeanOnly (self : Module) : Bool :=
self.pkg.isLeanOnly && !self.shouldPrecompile
-- ## Trace Helpers
protected def getMTime (self : Module) : IO MTime := do

View file

@ -103,6 +103,16 @@ structure PackageConfig extends WorkspaceConfig where
-/
precompileModules : Bool := false
/--
Whether the package is "Lean-only". A Lean-only package does not produce
native files for modules (e.g. `.c`, `.o`).
Defaults to `false`. Setting `precompileModules` to `true` will override this
setting and produce native files anyway (as they are needed to build module
dynlibs).
-/
isLeanOnly : Bool := false
/--
Additional arguments to pass to the Lean language server
(i.e., `lean --server`) launched by `lake server`.
@ -326,27 +336,27 @@ def IOPackager := (pkgDir : FilePath) → (args : List String) → IO PackageCon
namespace Package
/-- The package's `dependencies` configuration. -/
def dependencies (self : Package) : Array Dependency :=
@[inline] def dependencies (self : Package) : Array Dependency :=
self.config.dependencies
/-- The package's `extraDepTarget` configuration. -/
def extraDepTarget (self : Package) : OpaqueTarget :=
@[inline] def extraDepTarget (self : Package) : OpaqueTarget :=
self.config.extraDepTarget
/-- The package's `defaultFacet` configuration. -/
def defaultFacet (self : Package) : PackageFacet :=
@[inline] def defaultFacet (self : Package) : PackageFacet :=
self.config.defaultFacet
/-- Get the package's library configuration with the given name. -/
def findLeanLib? (name : Name) (self : Package) : Option LeanLibConfig :=
@[inline] def findLeanLib? (name : Name) (self : Package) : Option LeanLibConfig :=
self.leanLibs.find? name
/-- Get the package's executable configuration with the given name. -/
def findLeanExe? (name : Name) (self : Package) : Option LeanExeConfig :=
@[inline] def findLeanExe? (name : Name) (self : Package) : Option LeanExeConfig :=
self.leanExes.find? name
/-- Get the package's external library target with the given name. -/
def findExternLib? (name : Name) (self : Package) : Option ExternLibConfig :=
@[inline] def findExternLib? (name : Name) (self : Package) : Option ExternLibConfig :=
self.externLibs.find? name
/-- Get an `Array` of the package's external library targets. -/
@ -355,59 +365,63 @@ def externLibTargets (self : Package) : Array FileTarget :=
self.config.moreLibTargets
/-- The package's `precompileModules` configuration. -/
def precompileModules (self : Package) : Bool :=
@[inline] def precompileModules (self : Package) : Bool :=
self.config.precompileModules
/-- The package's `isLeanOnly` configuration. -/
@[inline] def isLeanOnly (self : Package) : Bool :=
self.config.isLeanOnly
/-- The package's `moreServerArgs` configuration. -/
def moreServerArgs (self : Package) : Array String :=
@[inline] def moreServerArgs (self : Package) : Array String :=
self.config.moreServerArgs
/-- The package's `dir` joined with its `srcDir` configuration. -/
def srcDir (self : Package) : FilePath :=
@[inline] def srcDir (self : Package) : FilePath :=
self.dir / self.config.srcDir
/-- The package's root directory for `lean` (i.e., `srcDir`). -/
def rootDir (self : Package) : FilePath :=
@[inline] def rootDir (self : Package) : FilePath :=
self.srcDir
/-- The package's `dir` joined with its `buildDir` configuration. -/
def buildDir (self : Package) : FilePath :=
@[inline] def buildDir (self : Package) : FilePath :=
self.dir / self.config.buildDir
/-- The package's `buildDir` joined with its `oleanDir` configuration. -/
def oleanDir (self : Package) : FilePath :=
@[inline] def oleanDir (self : Package) : FilePath :=
self.buildDir / self.config.oleanDir
/-- The package's `moreLeanArgs` configuration. -/
def moreLeanArgs (self : Package) : Array String :=
@[inline] def moreLeanArgs (self : Package) : Array String :=
self.config.moreLeanArgs
/- `-O3`, `-DNDEBUG`, and `moreLeancArgs` -/
def moreLeancArgs (self : Package) : Array String :=
@[inline] def moreLeancArgs (self : Package) : Array String :=
#["-O3", "-DNDEBUG"] ++ self.config.moreLeancArgs
/-- The package's `buildDir` joined with its `irDir` configuration. -/
def irDir (self : Package) : FilePath :=
@[inline] def irDir (self : Package) : FilePath :=
self.buildDir / self.config.irDir
/-- The package's `buildDir` joined with its `libDir` configuration. -/
def libDir (self : Package) : FilePath :=
@[inline] def libDir (self : Package) : FilePath :=
self.buildDir / self.config.libDir
/-- The package's `buildDir` joined with its `binDir` configuration. -/
def binDir (self : Package) : FilePath :=
@[inline] def binDir (self : Package) : FilePath :=
self.buildDir / self.config.binDir
/-- The library configuration built into the package configuration. -/
def builtinLibConfig (self : Package) : LeanLibConfig :=
@[inline] def builtinLibConfig (self : Package) : LeanLibConfig :=
self.config.toLeanLibConfig
/-- The binary executable configuration built into the package configuration. -/
def builtinExeConfig (self : Package) : LeanExeConfig :=
@[inline] def builtinExeConfig (self : Package) : LeanExeConfig :=
self.config.toLeanExeConfig
/-- Get an `Array` of the package's modules. -/
def getModuleArray (self : Package) : IO (Array Name) :=
@[inline] def getModuleArray (self : Package) : IO (Array Name) :=
self.builtinLibConfig.getModuleArray self.srcDir
/-- Whether the given module is considered local to the package. -/

View file

@ -115,7 +115,8 @@ Workspace options are shared across a package and its dependencies.
* `libDir`: The build subdirectory to which Lake should output the package's libraries. Defaults to `lib`.
* `binDir`: The build subdirectory to which Lake should output the package's binary executables. Defaults to `bin`.
* `extraDepTarget`: An extra `OpaqueTarget` that should be built before the package. `Target.collectOpaqueList/collectOpaqueArray` can be used combine multiple extra targets into a single `extraDepTarget`.
* `precompileModules`: Whether to compile each module into a native shared library that is loaded whenever the module is imported. This speeds up evaluation of metaprograms and enables the interpreter to run functions marked `@[extern]`. Defaults to `false`.
* `precompileModules`: Whether to compile each module into a native shared library that is loaded whenever the module is imported. This speeds up the evaluation of metaprograms and enables the interpreter to run functions marked `@[extern]`. Defaults to `false`.
* `isLeanOnly`: Whether the package is "Lean-only". A Lean-only package does not produce native files for modules (e.g. `.c`, `.o`). Defaults to `false`. Setting `precompileModules` to `true` will override this setting and produce native files anyway (as they are needed to build module dynlibs).
* `moreServerArgs`: Additional arguments to pass to the Lean language server (i.e., `lean --server`) launched by `lake serve`.
* `moreLeanArgs`: An `Array` of additional arguments to pass to `lean` while compiling Lean source files.
* `moreLeancArgs`: An `Array` of additional arguments to pass to `leanc` while compiling the 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`.