Skip to content
This repository was archived by the owner on Oct 25, 2023. It is now read-only.

Commit e4930e0

Browse files
committed
refactor: add LeanLib/LeanExe/ExternLib + reorg & cleanup
1 parent ac87b53 commit e4930e0

23 files changed

+472
-327
lines changed

Diff for: Lake/Build.lean

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ Authors: Mac Malone
55
-/
66
import Lake.Build.Monad
77
import Lake.Build.Actions
8-
import Lake.Build.Module
9-
import Lake.Build.Library
10-
import Lake.Build.Executable
8+
import Lake.Build.LeanLib
9+
import Lake.Build.LeanExe
1110
import Lake.Build.Imports

Diff for: Lake/Build/Executable.lean

-29
This file was deleted.

Diff for: Lake/Build/Imports.lean

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Used by `lake print-paths` to build modules for the Lean server.
3131
Returns the set of module dynlibs built (so they can be loaded by the server).
3232
3333
Builds only module `.olean` and `.ilean` files if the package is configured
34-
as "Lean-only". Otherwise, also build `.c` and `.o` files.
34+
as "Lean-only". Otherwise, also build `.c` files.
3535
-/
3636
def Package.buildImportsAndDeps (imports : List String) (self : Package) : BuildM (Array FilePath) := do
3737
if imports.isEmpty then
@@ -47,7 +47,7 @@ def Package.buildImportsAndDeps (imports : List String) (self : Package) : Build
4747
else if mod.isLeanOnly then
4848
buildModuleTop mod &`lean
4949
else
50-
buildModuleTop mod &`lean.o <&> (·.withoutInfo)
50+
buildModuleTop mod &`lean.c <&> (·.withoutInfo)
5151
let importTargets ← failOnBuildCycle res
5252
let dynlibTargets := bStore.collectModuleFacetArray &`lean.dynlib
5353
let externLibTargets := bStore.collectPackageFacetArray &`externSharedLibs

Diff for: Lake/Build/Index.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ the initial set of Lake package facets (e.g., `extraDep`).
130130
-- Build the `extern_lib` targets of the package
131131
|>.insert &`externSharedLibs (mkPackageFacetBuild <| fun pkg => do
132132
let mut targets := #[]
133-
for (_, config) in pkg.externLibs.toList do
133+
for (_, config) in pkg.externLibConfigs.toList do
134134
let target := staticToLeanDynlibTarget config.target
135135
targets := targets.push <| ← target.activate
136136
return targets

Diff for: Lake/Build/LeanExe.lean

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/-
2+
Copyright (c) 2022 Mac Malone. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Mac Malone
5+
-/
6+
import Lake.Build.LeanLib
7+
8+
namespace Lake
9+
10+
-- # Build Package Executable
11+
12+
def LeanExe.target (self : LeanExe) : FileTarget :=
13+
BuildTarget.mk' self.file do
14+
let cTargetMap ← buildModuleFacetMap #[self.root] &`lean.c
15+
let pkgLinkTargets ← self.pkg.linkTargetsOf cTargetMap
16+
let linkTargets :=
17+
if self.pkg.isLocalModule self.root.name then
18+
pkgLinkTargets
19+
else
20+
let rootTarget := cTargetMap.find? self.root.name |>.get!
21+
let rootLinkTarget := self.root.mkOTarget <| Target.active rootTarget
22+
#[rootLinkTarget] ++ pkgLinkTargets
23+
let target := leanExeTarget self.file linkTargets self.linkArgs
24+
target.materializeAsync
25+
26+
protected def Package.exeTarget (self : Package) : FileTarget :=
27+
self.builtinExe.target

Diff for: Lake/Build/Library.lean renamed to Lake/Build/LeanLib.lean

+23-26
Original file line numberDiff line numberDiff line change
@@ -10,47 +10,45 @@ open Lean hiding SearchPath
1010

1111
namespace Lake
1212

13-
-- # Build Package Lean Lib
14-
15-
def Package.getLibModuleArray (lib : LeanLibConfig) (self : Package) : IO (Array Module) := do
16-
return (← lib.getModuleArray self.srcDir).map (⟨self, WfName.ofName ·⟩)
13+
-- # Build Lean Lib
1714

1815
/--
1916
Build the `extraDepTarget` of a package and its (transitive) dependencies
2017
and then build the target `facet` of library's modules recursively, constructing
2118
a single opaque target for the whole build.
2219
-/
23-
def Package.buildLibModules
24-
(self : Package) (lib : LeanLibConfig) (facet : WfName)
20+
def LeanLib.buildModules (self : LeanLib) (facet : WfName)
2521
[DynamicType ModuleData facet (ActiveBuildTarget α)] : SchedulerM Job := do
2622
let buildMods : BuildM _ := do
27-
let mods ← self.getLibModuleArray lib
23+
let mods ← self.getModuleArray
2824
let modTargets ← buildModuleFacetArray mods facet
2925
(·.task) <$> ActiveTarget.collectOpaqueArray modTargets
3026
buildMods.catchFailure fun _ => pure <| failure
3127

32-
def Package.mkLibTarget (self : Package) (lib : LeanLibConfig) : OpaqueTarget :=
33-
Target.opaque <| self.buildLibModules lib &`lean
28+
def LeanLib.leanTarget (self : LeanLib) : OpaqueTarget :=
29+
Target.opaque <| self.buildModules &`lean
3430

3531
def Package.libTarget (self : Package) : OpaqueTarget :=
36-
self.mkLibTarget self.builtinLibConfig
32+
self.builtinLib.leanTarget
3733

38-
-- # Build Package Static Lib
34+
-- # Build Static Lib
3935

40-
def Package.localTargetsOf (map : NameMap (ActiveBuildTarget α)) (self : Package) : Array (BuildTarget α) :=
36+
def LeanLib.localTargetsOf (map : NameMap (ActiveBuildTarget α)) (self : LeanLib) : Array (BuildTarget α) :=
4137
map.fold (fun a n v => if self.isLocalModule n then a.push (Target.active v) else a) #[]
4238

43-
def Package.mkStaticLibTarget (lib : LeanLibConfig) (self : Package) : FileTarget :=
44-
let libFile := self.libDir / lib.staticLibFileName
45-
BuildTarget.mk' libFile do
46-
let mods ← self.getLibModuleArray lib
39+
protected def LeanLib.staticLibTarget (self : LeanLib) : FileTarget :=
40+
BuildTarget.mk' self.staticLibFile do
41+
let mods ← self.getModuleArray
4742
let oFileTargets := self.localTargetsOf <| ← buildModuleFacetMap mods &`lean.o
48-
staticLibTarget libFile oFileTargets |>.materializeAsync
43+
staticLibTarget self.staticLibFile oFileTargets |>.materializeAsync
4944

5045
protected def Package.staticLibTarget (self : Package) : FileTarget :=
51-
self.mkStaticLibTarget self.builtinLibConfig
46+
self.builtinLib.staticLibTarget
47+
48+
-- # Build Shared Lib
5249

53-
-- # Build Package Shared Lib
50+
def Package.localTargetsOf (map : NameMap (ActiveBuildTarget α)) (self : Package) : Array (BuildTarget α) :=
51+
map.fold (fun a n v => if self.isLocalModule n then a.push (Target.active v) else a) #[]
5452

5553
def Package.linkTargetsOf
5654
(targetMap : NameMap ActiveFileTarget) (self : Package) : LakeM (Array FileTarget) := do
@@ -66,13 +64,12 @@ def Package.linkTargetsOf
6664
return self.localTargetsOf targetMap ++ self.externLibTargets ++ ts
6765
| Except.error _ => panic! "dependency cycle emerged after resolution"
6866

69-
def Package.mkSharedLibTarget (self : Package) (lib : LeanLibConfig) : FileTarget :=
70-
let libFile := self.libDir / lib.sharedLibFileName
71-
BuildTarget.mk' libFile do
72-
let mods ← self.getLibModuleArray lib
73-
let linkTargets ← self.linkTargetsOf <| ← buildModuleFacetMap mods &`lean.o
74-
let target := leanSharedLibTarget libFile linkTargets lib.linkArgs
67+
protected def LeanLib.sharedLibTarget (self : LeanLib) : FileTarget :=
68+
BuildTarget.mk' self.sharedLibFile do
69+
let mods ← self.getModuleArray
70+
let linkTargets ← self.pkg.linkTargetsOf <| ← buildModuleFacetMap mods &`lean.o
71+
let target := leanSharedLibTarget self.sharedLibFile linkTargets self.linkArgs
7572
target.materializeAsync
7673

7774
protected def Package.sharedLibTarget (self : Package) : FileTarget :=
78-
self.mkSharedLibTarget self.builtinLibConfig
75+
self.builtinLib.sharedLibTarget

Diff for: Lake/CLI/Build.lean

+13-13
Original file line numberDiff line numberDiff line change
@@ -40,32 +40,32 @@ def resolveModuleTarget (mod : Module) (facet : String) : Except CliError Opaque
4040
else
4141
throw <| CliError.unknownFacet "module" facet
4242

43-
def resolveLibTarget (pkg : Package) (lib : LeanLibConfig) (facet : String) : Except CliError OpaqueTarget :=
43+
def resolveLibTarget (lib : LeanLib) (facet : String) : Except CliError OpaqueTarget :=
4444
if facet.isEmpty || facet == "lean" || facet == "oleans" then
45-
return pkg.mkLibTarget lib
45+
return lib.leanTarget
4646
else if facet == "static" then
47-
return pkg.mkStaticLibTarget lib |>.withoutInfo
47+
return lib.staticLibTarget |>.withoutInfo
4848
else if facet == "shared" then
49-
return pkg.mkSharedLibTarget lib |>.withoutInfo
49+
return lib.sharedLibTarget |>.withoutInfo
5050
else
5151
throw <| CliError.unknownFacet "library" facet
5252

53-
def resolveExeTarget (pkg : Package) (exe : LeanExeConfig) (facet : String) : Except CliError OpaqueTarget :=
53+
def resolveExeTarget (exe : LeanExe) (facet : String) : Except CliError OpaqueTarget :=
5454
if facet.isEmpty || facet == "exe" then
55-
return pkg.mkExeTarget exe |>.withoutInfo
55+
return exe.target |>.withoutInfo
5656
else
5757
throw <| CliError.unknownFacet "executable" facet
5858

5959
def resolveTargetInPackage (pkg : Package) (target : Name) (facet : String) : Except CliError OpaqueTarget :=
6060
if let some exe := pkg.findLeanExe? target then
61-
resolveExeTarget pkg exe facet
61+
resolveExeTarget exe facet
6262
else if let some lib := pkg.findExternLib? target then
6363
if facet.isEmpty then
6464
return lib.target.withoutInfo
6565
else
6666
throw <| CliError.invalidFacet target facet
6767
else if let some lib := pkg.findLeanLib? target then
68-
resolveLibTarget pkg lib facet
68+
resolveLibTarget lib facet
6969
else if let some mod := pkg.findModule? target then
7070
resolveModuleTarget mod facet
7171
else
@@ -93,15 +93,15 @@ def resolvePackageTarget (pkg : Package) (facet : String) : Except CliError Opaq
9393
throw <| CliError.unknownFacet "package" facet
9494

9595
def resolveTargetInWorkspace (ws : Workspace) (spec : String) (facet : String) : Except CliError OpaqueTarget :=
96-
if let some (pkg, exe) := ws.findLeanExe? spec.toName then
97-
resolveExeTarget pkg exe facet
98-
else if let some (_, lib) := ws.findExternLib? spec.toName then
96+
if let some exe := ws.findLeanExe? spec.toName then
97+
resolveExeTarget exe facet
98+
else if let some lib := ws.findExternLib? spec.toName then
9999
if facet.isEmpty then
100100
return lib.target.withoutInfo
101101
else
102102
throw <| CliError.invalidFacet spec facet
103-
else if let some (pkg, lib) := ws.findLeanLib? spec.toName then
104-
resolveLibTarget pkg lib facet
103+
else if let some lib := ws.findLeanLib? spec.toName then
104+
resolveLibTarget lib facet
105105
else if let some pkg := ws.findPackage? spec.toName then
106106
resolvePackageTarget pkg facet
107107
else if let some mod := ws.findModule? spec.toName then

Diff for: Lake/Config/ExternLib.lean

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/-
2+
Copyright (c) 2022 Mac Malone. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Mac Malone
5+
-/
6+
import Lake.Config.Package
7+
8+
namespace Lake
9+
10+
/-- An external library -- its package plus its configuration. -/
11+
structure ExternLib where
12+
/-- The package the library belongs to. -/
13+
pkg : Package
14+
/-- The library's user-defined configuration. -/
15+
config : ExternLibConfig
16+
deriving Inhabited
17+
18+
/-- Try to find a external library in the package with the given name. -/
19+
@[inline] def Package.findExternLib? (name : Name) (self : Package) : Option ExternLib :=
20+
self.externLibConfigs.find? name |>.map (⟨self, ·⟩)
21+
22+
namespace ExternLib
23+
24+
/-- The external library's user-defined `target`. -/
25+
@[inline] def target (self : ExternLib) : FileTarget :=
26+
self.config.target

Diff for: Lake/Config/ExternLibConfig.lean

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/-
2+
Copyright (c) 2022 Mac Malone. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Mac Malone
5+
-/
6+
import Lake.Build.TargetTypes
7+
8+
namespace Lake
9+
open Lean System
10+
11+
/-- A external library's declarative configuration. -/
12+
structure ExternLibConfig where
13+
/-- The name of the target. -/
14+
name : Name
15+
16+
/-- The library's build target. -/
17+
target : FileTarget
18+
19+
deriving Inhabited

Diff for: Lake/Config/Glob.lean

+19-22
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Mario Carneiro, Mac Malone
55
-/
66
import Lean.Util.Path
7+
import Lake.Util.Name
78

89
open Lean (Name)
910
open System (FilePath)
@@ -22,29 +23,25 @@ deriving Inhabited, Repr
2223

2324
instance : Coe Name Glob := ⟨Glob.one⟩
2425

25-
def Glob.matches (m : Name) : (self : Glob) → Bool
26+
partial def forEachNoduleIn [Monad m] [MonadLiftT IO m]
27+
(dir : FilePath) (f : WfName → m PUnit) : m PUnit := do
28+
for entry in (← dir.readDir) do
29+
if (← liftM (m := IO) <| entry.path.isDir) then
30+
f entry.fileName
31+
else if entry.path.extension == some "lean" then
32+
f <| FilePath.withExtension entry.fileName "" |>.toString
33+
34+
namespace Glob
35+
36+
def «matches» (m : Name) : (self : Glob) → Bool
2637
| one n => n == m
2738
| submodules n => n.isPrefixOf m && n != m
2839
| andSubmodules n => n.isPrefixOf m
2940

30-
partial def pushSubmodules
31-
(rootDir : FilePath) (mod : Name) (arr : Array Name) : IO (Array Name) := do
32-
let mut arr := arr
33-
let dirPath := Lean.modToFilePath rootDir mod ""
34-
for entry in (← dirPath.readDir) do
35-
let path := entry.path
36-
if (← path.isDir) then
37-
arr ← pushSubmodules rootDir (mod ++ entry.fileName) arr
38-
else if path.extension == some "lean" then
39-
let fileName := FilePath.withExtension entry.fileName "" |>.toString
40-
arr := arr.push (mod ++ fileName)
41-
return arr
42-
43-
def Glob.pushModules
44-
(dir : FilePath) (arr : Array Name) : (self : Glob) → IO (Array Name)
45-
| one n => pure #[n]
46-
| submodules n => pushSubmodules dir n arr
47-
| andSubmodules n => pushSubmodules dir n (arr.push n)
48-
49-
def Glob.getModules (dir : FilePath) (self : Glob) : IO (Array Name) :=
50-
self.pushModules dir #[]
41+
def forEachModuleIn [Monad m] [MonadLiftT IO m]
42+
(dir : FilePath) (f : WfName → m PUnit) : (self : Glob) → m PUnit
43+
| one n => f (WfName.ofName n)
44+
| submodules n => forEachNoduleIn (Lean.modToFilePath dir n "") f
45+
| andSubmodules n =>
46+
f (WfName.ofName n) *>
47+
forEachNoduleIn (Lean.modToFilePath dir n "") f

Diff for: Lake/Config/LeanExe.lean

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/-
2+
Copyright (c) 2022 Mac Malone. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Mac Malone
5+
-/
6+
import Lake.Config.Module
7+
8+
namespace Lake
9+
open Lean System
10+
11+
/-- A Lean executable -- its package plus its configuration. -/
12+
structure LeanExe where
13+
/-- The package the executable belongs to. -/
14+
pkg : Package
15+
/-- The executable's user-defined configuration. -/
16+
config : LeanExeConfig
17+
deriving Inhabited
18+
19+
/-- The Lean executable built into the package. -/
20+
@[inline] def Package.builtinExe (self : Package) : LeanExe :=
21+
⟨self, self.builtinExeConfig⟩
22+
23+
/-- Try to find a Lean executable in the package with the given name. -/
24+
@[inline] def Package.findLeanExe? (name : Name) (self : Package) : Option LeanExe :=
25+
self.leanExeConfigs.find? name |>.map (⟨self, ·⟩)
26+
27+
namespace LeanExe
28+
29+
/-- The executable's root module. -/
30+
@[inline] def root (self : LeanExe) : Module :=
31+
⟨self.pkg, WfName.ofName self.config.root⟩
32+
33+
/--
34+
The file name of binary executable
35+
(i.e., `exeName` plus the platform's `exeExtension`).
36+
-/
37+
@[inline] def fileName (self : LeanExe) : FilePath :=
38+
FilePath.withExtension self.config.exeName FilePath.exeExtension
39+
40+
/-- The path to the executable in the package's `binDir`. -/
41+
@[inline] def file (self : LeanExe) : FilePath :=
42+
self.pkg.binDir / self.fileName
43+
44+
/--
45+
The arguments to pass to `leanc` when linking the binary executable.
46+
47+
That is, `-rdynamic` (if non-Windows and `supportInterpreter`) plus the
48+
package's and then the executable's `moreLinkArgs`.
49+
-/
50+
def linkArgs (self : LeanExe) : Array String :=
51+
if self.config.supportInterpreter && !Platform.isWindows then
52+
#["-rdynamic"] ++ self.pkg.moreLinkArgs ++ self.config.moreLinkArgs
53+
else
54+
self.pkg.moreLinkArgs ++ self.config.moreLinkArgs

0 commit comments

Comments
 (0)