lean4-htt/Lake/Config/Package.lean

368 lines
13 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
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.Config.Opaque
import Lake.Config.LeanLibConfig
import Lake.Config.LeanExeConfig
import Lake.Config.ExternLibConfig
import Lake.Config.WorkspaceConfig
import Lake.Config.Dependency
import Lake.Config.Script
import Lake.Util.DRBMap
open Std System
namespace Lake
--------------------------------------------------------------------------------
-- # Defaults
--------------------------------------------------------------------------------
/-- The default setting for a `PackageConfig`'s `buildDir` option. -/
def defaultBuildDir : FilePath := "build"
/-- The default setting for a `PackageConfig`'s `binDir` option. -/
def defaultBinDir : FilePath := "bin"
/-- The default setting for a `PackageConfig`'s `libDir` option. -/
def defaultLibDir : FilePath := "lib"
/-- The default setting for a `PackageConfig`'s `oleanDir` option. -/
def defaultOleanDir : FilePath := defaultLibDir
/-- The default setting for a `PackageConfig`'s `irDir` option. -/
def defaultIrDir : FilePath := "ir"
/-- The default setting for a `PackageConfig`'s `binRoot` option. -/
def defaultBinRoot : Name := `Main
--------------------------------------------------------------------------------
-- # PackageFacet
--------------------------------------------------------------------------------
/- A buildable component of a `Package`. -/
inductive PackageFacet
| /-- The package's binary executable. -/ exe
| /-- The package's static library. -/ staticLib
| /-- The package's shared library. -/ sharedLib
| /-- The package's lean library (e.g. `olean` / `ilean` files). -/ leanLib
| /-- The package has no buildable component. -/ none
deriving BEq, DecidableEq, Repr
instance : Inhabited PackageFacet := ⟨PackageFacet.exe⟩
--------------------------------------------------------------------------------
-- # PackageConfig
--------------------------------------------------------------------------------
/-- A `Package`'s declarative configuration. -/
structure PackageConfig extends WorkspaceConfig, LeanConfig where
/-- The `Name` of the package. -/
name : Name
/--
An extra `OpaqueTarget` that should be built before the package.
`OpaqueTarget.collectList/collectArray` can be used combine multiple
extra targets into a single `extraDepTarget`.
**DEPRECATED:** Use separate custom `target` declarations instead?
-/
extraDepTarget : Option OpaqueTarget.{0} := none
/--
The optional `PackageFacet` to build on a bare `lake build` of the package.
Can be one of `exe`, `leanLib`, `staticLib`, `sharedLib`, or `none`.
Defaults to `exe`. See `lake help build` for more info on build facets.
**DEPRECATED:**
Package facets will be removed in a future version of Lake.
Use a separate `lean_lib` or `lean_exe` default target instead.
-/
defaultFacet : PackageFacet := .exe
/--
Whether to compile each of the package's 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 : 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`.
-/
moreServerArgs : Array String := #[]
/--
The directory containing the package's Lean source files.
Defaults to the package's directory.
(This will be passed to `lean` as the `-R` option.)
-/
srcDir : FilePath := "."
/--
The directory to which Lake should output the package's build results.
Defaults to `defaultBuildDir` (i.e., `build`).
-/
buildDir : FilePath := defaultBuildDir
/--
The build subdirectory to which Lake should output the package's `.olean` files.
Defaults to `defaultOleanDir` (i.e., `lib`).
-/
oleanDir : FilePath := defaultOleanDir
/--
The root module(s) of the package's library.
Submodules of these roots (e.g., `Pkg.Foo` of `Pkg`) are considered
part of the package.
Defaults to a single root of the package's upper camel case `name`.
-/
libRoots : Array Name := #[toUpperCamelCase name]
/--
An `Array` of module `Glob`s to build for the package's library.
Defaults to a `Glob.one` of each of the module's `libRoots`.
Submodule globs build every source file within their directory.
Local imports of glob'ed files (i.e., fellow modules of the package) are
also recursively built.
-/
libGlobs : Array Glob := libRoots.map Glob.one
/--
The build subdirectory to which Lake should output
the package's intermediary results (e.g., `.c` and `.o` files).
Defaults to `defaultIrDir` (i.e., `ir`).
-/
irDir : FilePath := defaultIrDir
/--
The name of the package's static library.
Defaults to the package's upper camel case `name`.
-/
libName : String := toUpperCamelCase name |>.toString (escape := false)
/--
The build subdirectory to which Lake should output the package's static library.
Defaults to `defaultLibDir` (i.e., `lib`).
-/
libDir : FilePath := defaultLibDir
/--
The name of the package's binary executable.
Defaults to the package's `name` with any `.` replaced with a `-`.
-/
binName : String := name.toStringWithSep "-" (escape := false)
/--
The build subdirectory to which Lake should output the package's binary executable.
Defaults to `defaultBinDir` (i.e., `bin`).
-/
binDir : FilePath := defaultBinDir
/--
The root module of the package's binary executable.
Defaults to `defaultBinRoot` (i.e., `Main`).
The root is built by recursively building its
local imports (i.e., fellow modules of the workspace).
This setting is most useful for packages that are distributing both a
library and a binary (like Lake itself). In such cases, it is common for
there to be code (e.g., `main`) that is needed for the binary but should
not be included in the library proper.
-/
binRoot : Name := defaultBinRoot
/--
Additional library `FileTarget`s (beyond the package's and its dependencies'
Lean libraries) to build and link to the package's binaries (and to dependent
packages' binaries).
**DEPRECATED:** Use separate `extern_lib` targets instead.
-/
moreLibTargets : Array FileTarget := #[]
/--
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
deriving Inhabited
namespace PackageConfig
/-- The configuration of the package's library. -/
def toLeanLibConfig (self : PackageConfig) : LeanLibConfig where
name := self.libName
roots := self.libRoots
globs := self.libGlobs
toLeanConfig := self.toLeanConfig
/-- The configuration of the package's binary executable. -/
def toLeanExeConfig (self : PackageConfig) : LeanExeConfig where
root := self.binRoot
name := self.binName
supportInterpreter := self.supportInterpreter
toLeanConfig := self.toLeanConfig
end PackageConfig
--------------------------------------------------------------------------------
-- # Package
--------------------------------------------------------------------------------
abbrev DNameMap α := DRBMap WfName α WfName.quickCmp
/-- A Lake package -- its location plus its configuration. -/
structure Package where
/-- The path to the package's directory. -/
dir : FilePath
/-- 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 := {}
/- An `Array` of the package's dependencies. -/
dependencies : Array Dependency := #[]
/-- 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. -/
externLibConfigs : NameMap ExternLibConfig := {}
/-- (Opaque references to) module facets defined in the package. -/
opaqueModuleFacetConfigs : DNameMap OpaqueModuleFacetConfig := {}
/-- (Opaque references to) module facets defined in the package. -/
opaquePackageFacetConfigs : DNameMap OpaquePackageFacetConfig := {}
/-- (Opaque references to) targets defined in the package. -/
opaqueTargetConfigs : NameMap OpaqueTargetConfig := {}
/--
The names of the package's targets to build by default
(i.e., on a bare `lake build` of the package).
-/
defaultTargets : Array WfName := #[]
deriving Inhabited
hydrate_opaque_type OpaquePackage Package
abbrev PackageSet := RBTree Package (·.name.quickCmp ·.name)
@[inline] def PackageSet.empty : PackageSet := RBTree.empty
namespace Package
/-- The package's `extraDepTarget` configuration. -/
@[inline] def extraDepTarget (self : Package) : OpaqueTarget :=
self.config.extraDepTarget.getD Target.nil
/-- The package's `defaultFacet` configuration. -/
@[inline] def defaultFacet (self : Package) : PackageFacet :=
self.config.defaultFacet
/-- The package's `precompileModules` configuration. -/
@[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. -/
@[inline] def moreServerArgs (self : Package) : Array String :=
self.config.moreServerArgs
/-- The package's `dir` joined with its `srcDir` configuration. -/
@[inline] def srcDir (self : Package) : FilePath :=
self.dir / self.config.srcDir
/-- The package's root directory for `lean` (i.e., `srcDir`). -/
@[inline] def rootDir (self : Package) : FilePath :=
self.srcDir
/-- The package's `dir` joined with its `buildDir` configuration. -/
@[inline] def buildDir (self : Package) : FilePath :=
self.dir / self.config.buildDir
/-- The package's `buildDir` joined with its `oleanDir` configuration. -/
@[inline] def oleanDir (self : Package) : FilePath :=
self.buildDir / self.config.oleanDir
/- The package's `buildType` configuration. -/
@[inline] def buildType (self : Package) : BuildType :=
self.config.buildType
/-- The package's `moreLeanArgs` configuration. -/
@[inline] def moreLeanArgs (self : Package) : Array String :=
self.config.moreLeanArgs
/- The package's `moreLeancArgs` configuration. -/
@[inline] def moreLeancArgs (self : Package) : Array String :=
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
/-- The package's `buildDir` joined with its `libDir` configuration. -/
@[inline] def libDir (self : Package) : FilePath :=
self.buildDir / self.config.libDir
/-- The package's `buildDir` joined with its `binDir` configuration. -/
@[inline] def binDir (self : Package) : FilePath :=
self.buildDir / self.config.binDir
/-- The library configuration built into the package configuration. -/
@[inline] def builtinLibConfig (self : Package) : LeanLibConfig :=
self.config.toLeanLibConfig
/-- The binary executable configuration built into the package configuration. -/
@[inline] def builtinExeConfig (self : Package) : LeanExeConfig :=
self.config.toLeanExeConfig
/-- Whether the given module is considered local to the package. -/
def isLocalModule (mod : Name) (self : Package) : Bool :=
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.leanLibConfigs.any (fun _ lib => lib.isBuildableModule mod) ||
self.leanExeConfigs.any (fun _ exe => exe.root == mod) ||
self.builtinLibConfig.isBuildableModule mod ||
self.config.binRoot == mod
/-- Remove the package's build outputs (i.e., delete its build directory). -/
def clean (self : Package) : IO PUnit := do
if (← self.buildDir.pathExists) then
IO.FS.removeDirAll self.buildDir