/- 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.Info import Lake.Build.Store import Lake.Build.Targets namespace Lake variable [Monad m] [MonadLiftT BuildM m] [MonadBuildStore m] -- # Build Static Lib /-- Build and collect the specified facet of the library's local modules. -/ @[specialize] def LeanLib.recBuildLocalModules (facets : Array (ModuleFacet α)) (self : LeanLib) : IndexT m (Array α) := do have : MonadLift BuildM m := ⟨liftM⟩ let mut results := #[] let mut modSet := ModuleSet.empty let mods ← self.getModuleArray for mod in mods do let (_, mods) ← mod.imports.recBuild let mods := mods.push mod for mod in mods do if self.isLocalModule mod.name then unless modSet.contains mod do for facet in facets do results := results.push <| ← recBuild <| mod.facet facet.name modSet := modSet.insert mod return results @[specialize] protected def LeanLib.recBuildStatic (self : LeanLib) : IndexT m ActiveFileTarget := do have : MonadLift BuildM m := ⟨liftM⟩ let oTargets := (← self.recBuildLocalModules self.nativeFacets).map Target.active staticLibTarget self.staticLibFile oTargets |>.activate -- # Build Shared Lib /-- Build and collect the local object files and external libraries of a library and its modules' imports. -/ @[specialize] def LeanLib.recBuildLinks (facets : Array (ModuleFacet ActiveFileTarget)) (self : LeanLib) : IndexT m (Array ActiveFileTarget) := do have : MonadLift BuildM m := ⟨liftM⟩ -- Build and collect modules let mut pkgs := #[] let mut pkgSet := PackageSet.empty let mut modSet := ModuleSet.empty let mut targets := #[] let mods ← self.getModuleArray for mod in mods do let (_, mods) ← mod.imports.recBuild let mods := mods.push mod for mod in mods do unless modSet.contains mod do unless pkgSet.contains mod.pkg do pkgSet := pkgSet.insert mod.pkg pkgs := pkgs.push mod.pkg if self.isLocalModule mod.name then for facet in facets do targets := targets.push <| ← recBuild <| mod.facet facet.name modSet := modSet.insert mod -- Build and collect external library targets for pkg in pkgs do let externLibTargets ← pkg.externLibs.mapM (·.shared.recBuild) for target in externLibTargets do targets := targets.push target return targets @[specialize] protected def LeanLib.recBuildShared (self : LeanLib) : IndexT m ActiveFileTarget := do have : MonadLift BuildM m := ⟨liftM⟩ let linkTargets := (← self.recBuildLinks self.nativeFacets).map Target.active leanSharedLibTarget self.sharedLibFile linkTargets self.linkArgs |>.activate -- # Build Executable @[specialize] protected def LeanExe.recBuild (self : LeanExe) : IndexT m ActiveFileTarget := do have : MonadLift BuildM m := ⟨liftM⟩ let (_, imports) ← self.root.imports.recBuild let linkTargets := #[Target.active <| ← self.root.o.recBuild] let mut linkTargets ← imports.foldlM (init := linkTargets) fun arr mod => do let mut arr := arr for facet in mod.nativeFacets do arr := arr.push <| Target.active <| ← recBuild <| mod.facet facet.name return arr let deps := (← recBuild <| self.pkg.facet &`deps).push self.pkg for dep in deps do for lib in dep.externLibs do linkTargets := linkTargets.push <| Target.active <| ← lib.static.recBuild leanExeTarget self.file linkTargets self.linkArgs |>.activate