/
NativeBridge.scala
98 lines (88 loc) · 3.18 KB
/
NativeBridge.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package bloop.scalanative
import java.nio.file.Files
import java.nio.file.Path
import scala.scalanative.build
import scala.scalanative.util.Scope
import bloop.config.Config.LinkerMode
import bloop.config.Config.NativeConfig
import bloop.data.Project
import bloop.io.Paths
import bloop.logging.DebugFilter
import bloop.logging.Logger
object NativeBridge {
private implicit val ctx: DebugFilter = DebugFilter.Link
private val sharedScope = Scope.unsafe()
def nativeLink(
config0: NativeConfig,
project: Project,
classpath: Array[Path],
entry: String,
target: Path,
logger: Logger
): Path = {
val workdir = project.out.resolve("native")
if (workdir.isDirectory) Paths.delete(workdir)
Files.createDirectories(workdir.underlying)
val nativeLogger =
build.Logger(logger.trace _, logger.debug _, logger.info _, logger.warn _, logger.error _)
val config = setUpNativeConfig(project, classpath, config0)
val nativeMode = config.mode match {
case LinkerMode.Debug => build.Mode.debug
case LinkerMode.Release => build.Mode.releaseFast
}
val nativeLTO = config.mode match {
case LinkerMode.Debug => build.LTO.none
case LinkerMode.Release if bloop.util.CrossPlatform.isMac => build.LTO.full
case LinkerMode.Release => build.LTO.thin
}
val nativeConfig =
build.Config.empty
.withMainClass(entry)
.withClassPath(classpath)
.withWorkdir(workdir.underlying)
.withLogger(nativeLogger)
.withCompilerConfig(
build.NativeConfig.empty
.withClang(config.clang)
.withClangPP(config.clangpp)
.withCompileOptions(config.options.compiler)
.withLinkingOptions(config.options.linker)
.withGC(build.GC(config.gc))
.withMode(nativeMode)
.withLTO(nativeLTO)
.withLinkStubs(config.linkStubs)
.withCheck(config.check)
.withDump(config.dump)
.withTargetTriple(config.targetTriple)
)
build.Build.build(nativeConfig, target)(sharedScope)
}
private[scalanative] def setUpNativeConfig(
project: Project,
classpath: Array[Path],
config: NativeConfig
): NativeConfig = {
val mode = config.mode
val options = config.options
val gc = if (config.gc.isEmpty) build.GC.default.name else config.gc
val clang = if (config.clang.toString.isEmpty) build.Discover.clang() else config.clang
val clangpp = if (config.clangpp.toString.isEmpty) build.Discover.clangpp() else config.clangpp
val lopts = if (options.linker.isEmpty) build.Discover.linkingOptions() else options.linker
val copts = if (options.compiler.isEmpty) build.Discover.compileOptions() else options.compiler
val targetTriple = config.targetTriple
NativeConfig.apply(
version = config.version,
mode = mode,
toolchain = Nil, // No worries, toolchain is on this project's classpath
gc = gc,
targetTriple = targetTriple,
clang = clang,
clangpp = clangpp,
options = options,
linkStubs = config.linkStubs,
check = config.check,
dump = config.dump,
output = config.output
)
}
}