lean4-htt/Lake/Build/Common.lean

111 lines
4.5 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) 2021 Mac Malone. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mac Malone
-/
import Lake.Build.Job
import Lake.Build.Actions
import Lake.Build.Monad
open System
namespace Lake
/-! # General Utilities -/
@[inline] def inputFile (path : FilePath) : SchedulerM (BuildJob FilePath) :=
Job.async <| (path, ·) <$> computeTrace path
@[inline] def buildUnlessUpToDate [CheckExists ι] [GetMTime ι] (info : ι)
(depTrace : BuildTrace) (traceFile : FilePath) (build : JobM PUnit) : JobM PUnit := do
let isOldMode ← getIsOldMode
let upToDate ←
if isOldMode then
depTrace.checkAgainstTime info
else
depTrace.checkAgainstFile info traceFile
unless upToDate do
build
unless isOldMode do
depTrace.writeToFile traceFile
@[inline] def buildFileUnlessUpToDate (file : FilePath)
(depTrace : BuildTrace) (build : BuildM PUnit) : BuildM BuildTrace := do
let traceFile := FilePath.mk <| file.toString ++ ".trace"
buildUnlessUpToDate file depTrace traceFile build
computeTrace file
@[inline] def buildFileAfterDep
(file : FilePath) (dep : BuildJob α) (build : α → BuildM PUnit)
(extraDepTrace : BuildM _ := pure BuildTrace.nil) : SchedulerM (BuildJob FilePath) :=
dep.bindSync fun depInfo depTrace => do
let depTrace := depTrace.mix (← extraDepTrace)
let trace ← buildFileUnlessUpToDate file depTrace <| build depInfo
return (file, trace)
@[inline] def buildFileAfterDepList
(file : FilePath) (deps : List (BuildJob α)) (build : List α → BuildM PUnit)
(extraDepTrace : BuildM _ := pure BuildTrace.nil) : SchedulerM (BuildJob FilePath) := do
buildFileAfterDep file (← BuildJob.collectList deps) build extraDepTrace
@[inline] def buildFileAfterDepArray
(file : FilePath) (deps : Array (BuildJob α)) (build : Array α → BuildM PUnit)
(extraDepTrace : BuildM _ := pure BuildTrace.nil) : SchedulerM (BuildJob FilePath) := do
buildFileAfterDep file (← BuildJob.collectArray deps) build extraDepTrace
/-! # Common Builds -/
def buildLeanO (name : String)
(oFile : FilePath) (srcJob : BuildJob FilePath)
(args : Array String := #[]) : SchedulerM (BuildJob FilePath) :=
buildFileAfterDep oFile srcJob (extraDepTrace := computeHash args) fun srcFile => do
compileO name oFile srcFile args (← getLeanc)
def buildStaticLib (libFile : FilePath)
(oFileJobs : Array (BuildJob FilePath)) : SchedulerM (BuildJob FilePath) :=
let name := libFile.fileName.getD libFile.toString
buildFileAfterDepArray libFile oFileJobs fun oFiles => do
compileStaticLib name libFile oFiles (← getLeanAr)
def buildLeanSharedLib
(libFile : FilePath) (linkJobs : Array (BuildJob FilePath))
(linkArgs : Array String := #[]) : SchedulerM (BuildJob FilePath) :=
let name := libFile.fileName.getD libFile.toString
buildFileAfterDepArray libFile linkJobs
(extraDepTrace := computeHash linkArgs) fun links => do
compileSharedLib name libFile (links.map toString ++ linkArgs) (← getLeanc)
def buildLeanExe
(exeFile : FilePath) (linkJobs : Array (BuildJob FilePath))
(linkArgs : Array String := #[]) : SchedulerM (BuildJob FilePath) :=
let name := exeFile.fileName.getD exeFile.toString
buildFileAfterDepArray exeFile linkJobs
(extraDepTrace := computeHash linkArgs) fun links => do
compileExe name exeFile links linkArgs (← getLeanc)
def buildLeanSharedLibOfStatic
(staticLibJob : BuildJob FilePath) (linkArgs : Array String := #[])
: SchedulerM (BuildJob FilePath) :=
staticLibJob.bindSync fun staticLib staticTrace => do
let dynlib := staticLib.withExtension sharedLibExt
let trace ← buildFileUnlessUpToDate dynlib staticTrace do
let args :=
if System.Platform.isOSX then
#[s!"-Wl,-force_load,{staticLib}"]
else
#["-Wl,--whole-archive", staticLib.toString, "-Wl,--no-whole-archive"]
let name := dynlib.fileName.getD dynlib.toString
compileSharedLib name dynlib (args ++ linkArgs) (← getLeanc)
return (dynlib, trace)
def computeDynlibOfShared
(sharedLibTarget : BuildJob FilePath) : SchedulerM (BuildJob Dynlib) :=
sharedLibTarget.bindSync fun sharedLib trace => do
if let some stem := sharedLib.fileStem then
if Platform.isWindows then
return ((sharedLib.parent, stem), trace)
else if stem.startsWith "lib" then
return ((sharedLib.parent, stem.drop 3), trace)
else
error s!"shared library `{sharedLib}` does not start with `lib`; this is not supported on Unix"
else
error s!"shared library `{sharedLib}` has no file name"