@@ -14,8 +14,8 @@ namespace Lake
14
14
15
15
-- # Solo Module Targets
16
16
17
- def Module.soloTarget (mod : Module)
18
- (dynlibs : Array FilePath ) (depTarget : BuildTarget x) (c := true ) : OpaqueTarget :=
17
+ def Module.soloTarget (mod : Module) (dynlibs : Array FilePath)
18
+ (dynlibPath : SearchPath ) (depTarget : BuildTarget x) (c := true ) : OpaqueTarget :=
19
19
Target.opaque <| depTarget.bindOpaqueSync fun depTrace => do
20
20
let argTrace : BuildTrace := pureHash mod.leanArgs
21
21
let srcTrace : BuildTrace ← computeTrace mod.leanFile
@@ -25,12 +25,12 @@ def Module.soloTarget (mod : Module)
25
25
let cUpToDate ← modTrace.checkAgainstFile mod.cFile mod.cTraceFile
26
26
unless modUpToDate && cUpToDate do
27
27
compileLeanModule mod.leanFile mod.oleanFile mod.ileanFile mod.cFile
28
- (← getOleanPath) mod.pkg.rootDir dynlibs mod.leanArgs (← getLean)
28
+ (← getOleanPath) mod.pkg.rootDir dynlibs dynlibPath mod.leanArgs (← getLean)
29
29
modTrace.writeToFile mod.cTraceFile
30
30
else
31
31
unless modUpToDate do
32
32
compileLeanModule mod.leanFile mod.oleanFile mod.ileanFile none
33
- (← getOleanPath) mod.pkg.rootDir dynlibs mod.leanArgs (← getLean)
33
+ (← getOleanPath) mod.pkg.rootDir dynlibs dynlibPath mod.leanArgs (← getLean)
34
34
modTrace.writeToFile mod.traceFile
35
35
return depTrace
36
36
@@ -43,8 +43,15 @@ def Module.mkOTarget (cTarget : FileTarget) (self : Module) : FileTarget :=
43
43
leanOFileTarget self.oFile cTarget self.leancArgs
44
44
45
45
@[inline]
46
- def Module.mkDynlibTarget (linkTargets : Array FileTarget) (self : Module) : FileTarget :=
47
- leanSharedLibTarget self.dynlib linkTargets self.linkArgs
46
+ def Module.mkDynlibTarget (self : Module) (oTarget : FileTarget)
47
+ (libDirs : Array FilePath) (libTargets : Array FileTarget) : FileTarget :=
48
+ let libsTarget : BuildTarget _ := Target.collectArray libTargets
49
+ Target.mk self.dynlib do
50
+ oTarget.bindAsync fun oFile oTrace => do
51
+ libsTarget.bindSync fun libFiles libTrace => do
52
+ buildFileUnlessUpToDate self.dynlibFile (oTrace.mix libTrace) do
53
+ let args := #[oFile.toString] ++ libDirs.map (s! "-L{ ·} " ) ++ libFiles.map (s! "-l:{ ·} " )
54
+ compileSharedLib self.dynlibFile args (← getLeanc)
48
55
49
56
-- # Recursive Building
50
57
@@ -53,21 +60,33 @@ variable [Monad m] [MonadLiftT BuildM m] [MonadBuildStore m]
53
60
54
61
/-- Build the dynlibs of the imports that want precompilation. -/
55
62
@[specialize] def recBuildPrecompileDynlibs (pkg : Package) (imports : Array Module)
56
- : IndexT m (Array ActiveFileTarget × Array ActiveFileTarget) := do
63
+ : IndexT m (Array ActiveFileTarget × Array ActiveFileTarget × Array FilePath) := do
64
+ have : MonadLift BuildM m := ⟨liftM⟩
65
+ -- Build and collect precompiled imports
57
66
let mut pkgs := #[]
58
- let mut pkgSet := PackageSet.empty
67
+ let mut pkgSet := PackageSet.empty.insert pkg
59
68
let mut modTargets := #[]
60
69
for imp in imports do
61
70
if imp.shouldPrecompile then
62
71
unless pkgSet.contains imp.pkg do
63
72
pkgSet := pkgSet.insert imp.pkg
64
73
pkgs := pkgs.push imp.pkg
65
74
modTargets := modTargets.push <| ← imp.recBuildFacet &`lean.dynlib
75
+ pkgs := pkgs.push pkg
76
+ -- Compute library directories and external library targets
77
+ let mut libDirs := #[]
66
78
let mut pkgTargets := #[]
67
79
for pkg in pkgs do
68
- pkgTargets := pkgTargets.append <| ← pkg.recBuildFacet &`externSharedLibs
69
- pkgTargets := pkgTargets.append <| ← pkg.recBuildFacet &`externSharedLibs
70
- return (modTargets, pkgTargets)
80
+ libDirs := libDirs.push pkg.libDir
81
+ let externLibTargets ← pkg.recBuildFacet &`externSharedLibs
82
+ for target in externLibTargets do
83
+ if let some parent := target.info.parent then
84
+ libDirs := libDirs.push parent
85
+ if let some fileName := target.info.fileName then
86
+ pkgTargets := pkgTargets.push <| target.withInfo fileName
87
+ else
88
+ logWarning s! "external library `{ target.info} ` was skipped because it has no file name"
89
+ return (modTargets, pkgTargets, libDirs)
71
90
72
91
/--
73
92
Recursively build a module and its (transitive, local) imports,
@@ -78,7 +97,7 @@ optionally outputting a `.c` file as well if `c` is set to `true`.
78
97
have : MonadLift BuildM m := ⟨liftM⟩
79
98
let extraDepTarget ← mod.pkg.recBuildFacet &`extraDep
80
99
let (imports, transImports) ← mod.recBuildFacet &`lean.imports
81
- let (modTargets, pkgTargets) ← recBuildPrecompileDynlibs mod.pkg transImports
100
+ let (modTargets, pkgTargets, libDirs ) ← recBuildPrecompileDynlibs mod.pkg transImports
82
101
-- Note: Lean wants the external library symbols before module symbols
83
102
let dynlibsTarget ← ActiveTarget.collectArray <| pkgTargets ++ modTargets
84
103
let importTarget ←
@@ -90,7 +109,7 @@ optionally outputting a `.c` file as well if `c` is set to `true`.
90
109
<| ← imports.mapM (·.recBuildFacet &`lean)
91
110
let depTarget := Target.active <| ← extraDepTarget.mixOpaqueAsync
92
111
<| ← dynlibsTarget.mixOpaqueAsync importTarget
93
- let modTarget ← mod.soloTarget dynlibsTarget.info depTarget c |>.activate
112
+ let modTarget ← mod.soloTarget dynlibsTarget.info libDirs.toList depTarget c |>.activate
94
113
store (mod.mkBuildKey &`lean) modTarget
95
114
store (mod.mkBuildKey &`olean) <| modTarget.withInfo mod.oleanFile
96
115
store (mod.mkBuildKey &`ilean) <| modTarget.withInfo mod.ileanFile
@@ -132,9 +151,8 @@ Recursively build the shared library of a module (e.g., for `--load-dynlib`).
132
151
@[specialize] def Module.recBuildDynLib (mod : Module)
133
152
: IndexT m ActiveFileTarget := do
134
153
have : MonadLift BuildM m := ⟨liftM⟩
135
- let oTarget ← mod.recBuildFacet &`lean.o
154
+ let oTarget := Target.active <| ← mod.recBuildFacet &`lean.o
136
155
let (_, transImports) ← mod.recBuildFacet &`lean.imports
137
- let (modTargets, pkgTargets) ← recBuildPrecompileDynlibs mod.pkg transImports
138
- let linkTargets := #[oTarget] ++ modTargets ++ pkgTargets
139
- let linkTargets := linkTargets.map Target.active
140
- mod.mkDynlibTarget linkTargets |>.activate
156
+ let (modTargets, pkgTargets, libDirs) ← recBuildPrecompileDynlibs mod.pkg transImports
157
+ let libTargets := modTargets ++ pkgTargets |>.map Target.active
158
+ mod.mkDynlibTarget oTarget libDirs libTargets |>.activate
0 commit comments