@@ -880,9 +880,13 @@ public def buildStaticLib
880880 compileStaticLib libFile oFiles (← getLeanAr) thin
881881 return art.path
882882
883+ /--
884+ Returns linker arguments to statically link in `objs` (e.g., object files or
885+ static libraries) and dynamically link to `libs` (but *not* their `deps`).
886+ -/
883887def mkLinkObjArgs
884- (objs : Array FilePath) (libs : Array Dynlib) : Array String
885- := Id.run do
888+ (objs : Array FilePath) (libs : Array Dynlib)
889+ : Array String : = Id.run do
886890 let mut args := #[]
887891 for obj in objs do
888892 args := args.push obj.toString
@@ -896,7 +900,7 @@ def mkLinkObjArgs
896900Topologically sorts the library dependency tree by name.
897901Libraries come *before* their dependencies.
898902-/
899- partial def mkLinkOrder (libs : Array Dynlib) : JobM (Array Dynlib) := do
903+ public partial def mkLinkOrder (libs : Array Dynlib) : JobM (Array Dynlib) := do
900904 let r := libs.foldlM (m := Except (Cycle String)) (init := ({}, #[])) fun (v, o) lib =>
901905 go lib [] v o
902906 match r with
@@ -916,8 +920,66 @@ where
916920 return (v, o)
917921
918922/--
919- Build a shared library by linking the results of `linkJobs`
920- using the Lean toolchain's C compiler.
923+ Returns linker arguments to statically link in `objs` (e.g., object files or
924+ static libraries) and, if `linkDeps := true`, dynamically link to `libs` (and their
925+ transitive `deps`).
926+ -/
927+ @[inline] public def mkLinkArgs
928+ (objs : Array FilePath) (libs : Array Dynlib)
929+ (linkDeps := Platform.isWindows)
930+ : JobM (Array String) := do
931+ let libs ← if linkDeps then mkLinkOrder libs else pure #[]
932+ return mkLinkObjArgs objs libs
933+
934+ @[inline] def mkLeanLinkArgs
935+ (objs : Array FilePath) (libs : Array Dynlib) (args : Array String)
936+ (linkDeps := Platform.isWindows) (sharedLean := true )
937+ : JobM (Array String) := do
938+ let lean ← getLeanInstall
939+ let baseArgs ← mkLinkArgs objs libs linkDeps
940+ return baseArgs ++ args ++ #["-L" , lean.leanLibDir.toString] ++ lean.ccLinkFlags sharedLean
941+
942+ /--
943+ Build a shared library using `linker`.
944+
945+ The library will statically link in `linkObjs` (e.g., object files or
946+ static libraries) and, if `linkDeps := true`, dynamically link to `linkLibs`
947+ (and their transitive `deps`).
948+
949+ Additional arguments to the linker can be provided via `args`.
950+ These will come *after* any other arguments.
951+
952+ If `plugin := true`, the resulting `Dynlib` will be marked as a Lean plugin.
953+ This means it is expected to have a `initialize_<libName>` symbol.
954+ -/
955+ public def buildSharedLibSync
956+ (libName : String) (libFile : FilePath)
957+ (linkObjs : Array FilePath) (linkLibs : Array Dynlib)
958+ (args : Array String := #[]) (linker := "c++" )
959+ (plugin := false ) (linkDeps := Platform.isWindows)
960+ : JobM Dynlib := do
961+ -- shared libraries are platform-dependent artifacts
962+ addPlatformTrace
963+ -- Lean plugins are required to have a specific name
964+ -- and thus need to restored from the cache with that name
965+ let art ← buildArtifactUnlessUpToDate libFile (ext := sharedLibExt) (restore := true ) do
966+ let baseArgs ← mkLinkArgs linkObjs linkLibs linkDeps
967+ compileSharedLib libFile (baseArgs ++ args) linker
968+ return {name := libName, path := art.path, deps := linkLibs, plugin}
969+
970+ /--
971+ Build a shared library using `linker`.
972+
973+ The library will statically link in the results of `linkObjs` (e.g., object
974+ files or static libraries) and, if `linkDeps := true`, dynamically link to the
975+ results of `linkLibs`.
976+
977+ Additional arguments to the linker can be provided via `weakArgs` and `traceArgs`.
978+ These will come *after* any other arguments. `traceArgs` will be included in
979+ the build's input trace, `weakArgs` will not.
980+
981+ If `plugin := true`, the resulting `Dynlib` will be marked as a Lean plugin.
982+ This means it is expected to have a `initialize_<libName>` symbol.
921983-/
922984public def buildSharedLib
923985 (libName : String) (libFile : FilePath)
@@ -928,20 +990,50 @@ public def buildSharedLib
928990: SpawnM (Job Dynlib) :=
929991 (Job.collectArray linkObjs "linkObjs" ).bindM (sync := true ) fun objs => do
930992 (Job.collectArray linkLibs "linkLibs" ).mapM fun libs => do
931- addPureTrace traceArgs "traceArgs"
932- addPlatformTrace -- shared libraries are platform-dependent artifacts
933993 addTrace (← extraDepTrace)
934- -- Lean plugins are required to have a specific name
935- -- and thus need to copied from the cache with that name
936- let art ← buildArtifactUnlessUpToDate libFile (ext := sharedLibExt) (restore := true ) do
937- let libs ← if linkDeps then mkLinkOrder libs else pure #[]
938- let args := mkLinkObjArgs objs libs ++ weakArgs ++ traceArgs
939- compileSharedLib libFile args linker
940- return {name := libName, path := art.path, deps := libs, plugin}
994+ addPureTrace traceArgs "traceArgs"
995+ buildSharedLibSync libName libFile objs libs (weakArgs ++ traceArgs) linker plugin linkDeps
941996
942997/--
943- Build a shared library by linking the results of `linkJobs`
944- using `linker`.
998+ Build a shared library linking Lean by using the Lean toolchain's linker.
999+
1000+ The library will statically link in `linkObjs` (e.g., object files or
1001+ static libraries) and, if `linkDeps := true`, dynamically link to `linkLibs`
1002+ (and their transitive `deps`).
1003+
1004+ Additional arguments to the linker can be provided via `weakArgs` and `traceArgs`.
1005+ `traceArgs` will be included in the build's input trace, `weakArgs` will not.
1006+
1007+ If `plugin := true`, the resulting `Dynlib` will be marked as a Lean plugin.
1008+ This means it is expected to have a `initialize_<libName>` symbol.
1009+ -/
1010+ public def buildLeanSharedLibSync
1011+ (libName : String) (libFile : FilePath)
1012+ (linkObjs : Array FilePath) (linkLibs : Array Dynlib)
1013+ (args : Array String := #[]) (plugin := false )
1014+ (linkDeps := Platform.isWindows)
1015+ : JobM Dynlib := do
1016+ addLeanTrace
1017+ addPlatformTrace -- shared libraries are platform-dependent artifacts
1018+ -- Lean plugins are required to have a specific name
1019+ -- and thus need to restored from the cache with that name
1020+ let art ← buildArtifactUnlessUpToDate libFile (ext := sharedLibExt) (restore := true ) do
1021+ let args ← mkLeanLinkArgs linkObjs linkLibs args linkDeps (sharedLean := true )
1022+ compileSharedLib libFile args (← getLeanCc)
1023+ return {name := libName, path := art.path, deps := linkLibs, plugin}
1024+
1025+ /--
1026+ Build a shared library linking Lean by using the Lean toolchain's linker.
1027+
1028+ The library will statically link in the results of `linkObjs` (e.g., object
1029+ files or static libraries) and, if `linkDeps := true`, dynamically link to the
1030+ results of `linkLibs` (and their transitive `deps`).
1031+
1032+ Additional arguments to the linker can be provided via `weakArgs` and `traceArgs`.
1033+ `traceArgs` will be included in the build's input trace, `weakArgs` will not.
1034+
1035+ If `plugin := true`, the resulting `Dynlib` will be marked as a Lean plugin.
1036+ This means it is expected to have a `initialize_<libName>` symbol.
9451037-/
9461038public def buildLeanSharedLib
9471039 (libName : String) (libFile : FilePath)
@@ -951,22 +1043,48 @@ public def buildLeanSharedLib
9511043: SpawnM (Job Dynlib) :=
9521044 (Job.collectArray linkObjs "linkObjs" ).bindM (sync := true ) fun objs => do
9531045 (Job.collectArray linkLibs "linkLibs" ).mapM fun libs => do
954- addLeanTrace
9551046 addPureTrace traceArgs "traceArgs"
956- addPlatformTrace -- shared libraries are platform-dependent artifacts
957- -- Lean plugins are required to have a specific name
958- -- and thus need to copied from the cache with that name
959- let art ← buildArtifactUnlessUpToDate libFile (ext := sharedLibExt) (restore := true ) do
960- let lean ← getLeanInstall
961- let libs ← if linkDeps then mkLinkOrder libs else pure #[]
962- let args := mkLinkObjArgs objs libs ++ weakArgs ++ traceArgs ++
963- #["-L" , lean.leanLibDir.toString] ++ lean.ccLinkSharedFlags
964- compileSharedLib libFile args lean.cc
965- return {name := libName, path := art.path, deps := libs, plugin}
1047+ buildLeanSharedLibSync libName libFile objs libs (weakArgs ++ traceArgs) plugin linkDeps
1048+
1049+ /--
1050+ Build an executable linking Lean by using the Lean toolchain's linker.
1051+
1052+ The executable will statically link in `linkObjs` (e.g., object files or
1053+ static libraries) and dynamically link to `linkLibs` (and their transitive
1054+ `deps`).
1055+
1056+ By default, Lean will be statically linked to the exeutable.
1057+ If `sharedLean := true`, it will instead be dynamically linked.
1058+ This means users of the resulting executable will need to have Lean's
1059+ shared libraries on their system.
1060+
1061+ Additional arguments to the linker can be provided via `args`.
1062+ -/
1063+ public def buildLeanExeSync
1064+ (exeFile : FilePath) (linkObjs : Array FilePath) (linkLibs : Array Dynlib)
1065+ (args : Array String := #[]) (sharedLean : Bool := false )
1066+ : JobM FilePath := do
1067+ addLeanTrace
1068+ addPlatformTrace -- executables are platform-dependent artifacts
1069+ let art ← buildArtifactUnlessUpToDate exeFile (ext := FilePath.exeExtension) (exe := true ) (restore := true ) do
1070+ let args ← mkLeanLinkArgs linkObjs linkLibs args (linkDeps := true ) sharedLean
1071+ compileExe exeFile args (← getLeanCc)
1072+ return art.path
9661073
9671074/--
968- Build an executable by linking the results of `linkJobs`
969- using the Lean toolchain's linker.
1075+ Build an executable linking Lean by using the Lean toolchain's linker.
1076+
1077+ The executable will statically link in the results of `linkObjs` (e.g., object
1078+ files or static libraries) and dynamically link to the results of `linkLibs`
1079+ (and their transitive `deps`).
1080+
1081+ By default, Lean will be statically linked to the exeutable.
1082+ If `sharedLean := true`, it will instead be dynamically linked.
1083+ This means users of the resulting executable will need to have Lean's
1084+ shared libraries on their system.
1085+
1086+ Additional arguments to the linker can be provided via `weakArgs` and `traceArgs`.
1087+ `traceArgs` will be included in the build's input trace, `weakArgs` will not.
9701088-/
9711089public def buildLeanExe
9721090 (exeFile : FilePath)
@@ -975,13 +1093,5 @@ public def buildLeanExe
9751093: SpawnM (Job FilePath) :=
9761094 (Job.collectArray linkObjs "linkObjs" ).bindM (sync := true ) fun objs => do
9771095 (Job.collectArray linkLibs "linkLibs" ).mapM fun libs => do
978- addLeanTrace
9791096 addPureTrace traceArgs "traceArgs"
980- addPlatformTrace -- executables are platform-dependent artifacts
981- let art ← buildArtifactUnlessUpToDate exeFile (ext := FilePath.exeExtension) (exe := true ) (restore := true ) do
982- let lean ← getLeanInstall
983- let libs ← mkLinkOrder libs
984- let args := mkLinkObjArgs objs libs ++ weakArgs ++ traceArgs ++
985- #["-L" , lean.leanLibDir.toString] ++ lean.ccLinkFlags sharedLean
986- compileExe exeFile args lean.cc
987- return art.path
1097+ buildLeanExeSync exeFile objs libs (weakArgs ++ traceArgs) sharedLean
0 commit comments