@@ -6,6 +6,7 @@ Authors: Mac Malone
66prelude
77import Lake.Config.Monad
88import Lake.Util.JsonObject
9+ import Lake.Build.Target.Fetch
910import Lake.Build.Actions
1011import Lake.Build.Job
1112
@@ -382,75 +383,77 @@ def buildStaticLib
382383 compileStaticLib libFile oFiles (← getLeanAr) thin
383384 return libFile
384385
386+ private def mkLinkObjArgs
387+ (objs : Array FilePath) (libs : Array Dynlib) : Array String
388+ := Id.run do
389+ let mut args := #[]
390+ for obj in objs do
391+ args := args.push obj.toString
392+ for lib in libs do
393+ if let some dir := lib.dir? then
394+ args := args.push s! "-L{ dir} "
395+ args := args.push s! "-l{ lib.name} "
396+ return args
397+
385398/--
386399Build a shared library by linking the results of `linkJobs`
387400using the Lean toolchain's C compiler.
388401-/
402+ def buildSharedLib
403+ (libName : String) (libFile : FilePath)
404+ (linkObjs : Array (Job FilePath)) (linkLibs : Array (Job Dynlib))
405+ (weakArgs traceArgs : Array String := #[]) (linker := "c++" )
406+ (extraDepTrace : JobM _ := pure BuildTrace.nil)
407+ (plugin := false )
408+ : SpawnM (Job Dynlib) :=
409+ (Job.collectArray linkObjs).bindM fun objs => do
410+ (Job.collectArray linkLibs).mapM (sync := true ) fun libs => do
411+ addPureTrace traceArgs
412+ addPlatformTrace -- shared libraries are platform-dependent artifacts
413+ addTrace (← extraDepTrace)
414+ buildFileUnlessUpToDate' libFile do
415+ let args := mkLinkObjArgs objs libs ++ weakArgs ++ traceArgs
416+ compileSharedLib libFile args linker
417+ return {name := libName, path := libFile, plugin}
418+
419+ /--
420+ Build a shared library by linking the results of `linkJobs`
421+ using `linker`.
422+ -/
389423def buildLeanSharedLib
390- (libFile : FilePath) (linkJobs : Array (Job FilePath))
391- (weakArgs traceArgs : Array String := #[])
392- : SpawnM (Job FilePath) :=
393- (Job.collectArray linkJobs).mapM fun links => do
424+ (libName : String) (libFile : FilePath)
425+ (linkObjs : Array (Job FilePath)) (linkLibs : Array (Job Dynlib))
426+ (weakArgs traceArgs : Array String := #[]) (plugin := false )
427+ : SpawnM (Job Dynlib) :=
428+ (Job.collectArray linkObjs).bindM fun objs => do
429+ (Job.collectArray linkLibs).mapM (sync := true ) fun libs => do
394430 addLeanTrace
395431 addPureTrace traceArgs
396432 addPlatformTrace -- shared libraries are platform-dependent artifacts
397433 buildFileUnlessUpToDate' libFile do
398434 let lean ← getLeanInstall
399- let args := links.map toString ++ weakArgs ++ traceArgs ++ lean.ccLinkSharedFlags
435+ let args := mkLinkObjArgs objs libs ++
436+ weakArgs ++ traceArgs ++ lean.ccLinkSharedFlags
400437 compileSharedLib libFile args lean.cc
401- return libFile
438+ return {name := libName, path := libFile, plugin}
402439
403440/--
404441Build an executable by linking the results of `linkJobs`
405442using the Lean toolchain's linker.
406443-/
407444def buildLeanExe
408- (exeFile : FilePath) (linkJobs : Array (Job FilePath))
445+ (exeFile : FilePath)
446+ (linkObjs : Array (Job FilePath)) (linkLibs : Array (Job Dynlib))
409447 (weakArgs traceArgs : Array String := #[]) (sharedLean : Bool := false )
410448: SpawnM (Job FilePath) :=
411- (Job.collectArray linkJobs).mapM fun links => do
449+ (Job.collectArray linkObjs).bindM fun objs => do
450+ (Job.collectArray linkLibs).mapM (sync := true ) fun libs => do
412451 addLeanTrace
413452 addPureTrace traceArgs
414453 addPlatformTrace -- executables are platform-dependent artifacts
415454 buildFileUnlessUpToDate' exeFile do
416455 let lean ← getLeanInstall
417- let args := links.map toString ++ weakArgs ++ traceArgs ++ lean.ccLinkFlags sharedLean
456+ let args := mkLinkObjArgs objs libs ++
457+ weakArgs ++ traceArgs ++ lean.ccLinkFlags sharedLean
418458 compileExe exeFile args lean.cc
419459 return exeFile
420-
421- /--
422- Build a shared library from a static library using `leanc`
423- using the Lean toolchain's linker.
424- -/
425- def buildLeanSharedLibOfStatic
426- (staticLibJob : Job FilePath)
427- (weakArgs traceArgs : Array String := #[])
428- : SpawnM (Job FilePath) :=
429- staticLibJob.mapM fun staticLib => do
430- addLeanTrace
431- addPureTrace traceArgs
432- addPlatformTrace -- shared libraries are platform-dependent artifacts
433- let dynlib := staticLib.withExtension sharedLibExt
434- buildFileUnlessUpToDate' dynlib do
435- let lean ← getLeanInstall
436- let baseArgs :=
437- if System.Platform.isOSX then
438- #[s! "-Wl,-force_load,{ staticLib} " ]
439- else
440- #["-Wl,--whole-archive" , staticLib.toString, "-Wl,--no-whole-archive" ]
441- let args := baseArgs ++ weakArgs ++ traceArgs ++ lean.ccLinkSharedFlags
442- compileSharedLib dynlib args lean.cc
443- return dynlib
444-
445- /-- Construct a `Dynlib` object for a shared library target. -/
446- def computeDynlibOfShared (sharedLibTarget : Job FilePath) : SpawnM (Job Dynlib) :=
447- sharedLibTarget.mapM fun sharedLib => do
448- if let some stem := sharedLib.fileStem then
449- if Platform.isWindows then
450- return {path := sharedLib, name := stem}
451- else if stem.startsWith "lib" then
452- return {path := sharedLib, name := stem.drop 3 }
453- else
454- error s! "shared library `{ sharedLib} ` does not start with `lib`; this is not supported on Unix"
455- else
456- error s! "shared library `{ sharedLib} ` has no file name"
0 commit comments