Skip to content

Commit 00eebd8

Browse files
committed
Refactor to better represent to changes and fix comments
1 parent ecb0ef2 commit 00eebd8

File tree

2 files changed

+111
-129
lines changed

2 files changed

+111
-129
lines changed

tools/src/main/scala/scala/scalanative/build/Filter.scala

-119
This file was deleted.

tools/src/main/scala/scala/scalanative/build/NativeLib.scala

+111-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ import java.io.File
55
import java.nio.file.{Files, Path}
66
import java.util.Arrays
77
import java.util.regex._
8+
89
import scala.concurrent._
10+
import scala.util.Failure
11+
import scala.util.Success
12+
13+
import scalanative.build.IO.RichPath
914
import scala.scalanative.linker.ReachabilityAnalysis
1015

1116
/** Original jar or dir path and generated dir path for native code */
@@ -14,16 +19,18 @@ private[scalanative] case class NativeLib(src: Path, dest: Path)
1419
/** Utilities for dealing with native library code */
1520
private[scalanative] object NativeLib {
1621

17-
/** Name of directory that contains native code: "scala-native"
18-
*/
22+
/** Name of directory that contains native code: "scala-native" */
1923
val nativeCodeDir = "scala-native"
2024

25+
/** Project Descriptor properties file: "scala-native.properties" */
26+
private val nativeProjectProps = s"${nativeCodeDir}.properties"
27+
2128
/** Compiles the native code from the library
2229
*
2330
* @param config
2431
* the configuration options
2532
* @param linkerResult
26-
* needed for filtering
33+
* needed for configuration based on NIR
2734
* @param nativeLib
2835
* the native lib to unpack
2936
* @return
@@ -34,11 +41,105 @@ private[scalanative] object NativeLib {
3441
analysis: ReachabilityAnalysis.Result,
3542
nativeLib: NativeLib
3643
)(implicit ec: ExecutionContext): Future[Seq[Path]] = {
37-
val destPath = NativeLib.unpackNativeCode(nativeLib)
38-
val paths = NativeLib.findNativePaths(config.workDir, destPath)
39-
val (projPaths, projConfig) =
40-
Filter.filterNativelib(config, analysis, destPath, paths)
41-
LLVM.compile(projConfig, projPaths)
44+
val destPath = unpackNativeCode(nativeLib)
45+
val paths = findNativePaths(config.workDir, destPath)
46+
val projConfig = configureNativelib(config, analysis, destPath)
47+
LLVM.compile(projConfig, paths)
48+
}
49+
50+
/** Update the project configuration the if a project `Descriptor` is present.
51+
*
52+
* @param config
53+
* The configuration of the toolchain.
54+
* @param linkerResult
55+
* The results from the linker.
56+
* @param destPath
57+
* The unpacked location of the Scala Native nativelib.
58+
* @return
59+
* The config for this native library.
60+
*/
61+
private def configureNativelib(
62+
config: Config,
63+
analysis: ReachabilityAnalysis.Result,
64+
destPath: Path
65+
): Config = {
66+
val nativeCodePath = destPath.resolve(nativeCodeDir)
67+
// check if filtering is needed, o.w. return all paths
68+
findDescriptor(nativeCodePath).fold(config) { filepath =>
69+
70+
val desc =
71+
Descriptor.load(filepath) match {
72+
case Success(v) => v
73+
case Failure(e) =>
74+
throw new BuildException(
75+
s"Problem reading $nativeProjectProps: ${e.getMessage}"
76+
)
77+
}
78+
79+
config.logger.debug(desc.toString())
80+
81+
val projectConfig = desc match {
82+
case Descriptor(Some(groupId), Some(artifactId), _)
83+
if (groupId == "org.scala-native" && artifactId == "nativelib") =>
84+
createGcConfig(nativeCodePath, config)
85+
case Descriptor(_, _, _) =>
86+
createLinkConfig(desc, analysis, config)
87+
}
88+
89+
projectConfig
90+
}
91+
}
92+
93+
private def createLinkConfig(
94+
desc: Descriptor,
95+
analysis: ReachabilityAnalysis.Result,
96+
config: Config
97+
): Config = {
98+
val linkDefines =
99+
desc.link
100+
.filter(name => analysis.links.exists(_.name == name))
101+
.map(name => s"-DSCALANATIVE_LINK_${name.toUpperCase}")
102+
103+
config.withCompilerConfig(
104+
_.withCompileOptions(_ ++ linkDefines)
105+
)
106+
}
107+
108+
private def createGcConfig(
109+
nativeCodePath: Path,
110+
config: Config
111+
): Config = {
112+
/* A conditional compilation define is used to compile the
113+
* correct garbage collector code because code is shared.
114+
* This avoids handling all the paths needed and compiling
115+
* all the GC code for a given platform.
116+
*
117+
* Note: The zone directory is also part of the garbage collection
118+
* system and shares code from the gc directory.
119+
*/
120+
val gcFlag = {
121+
val gc = config.compilerConfig.gc.toString
122+
s"-DSCALANATIVE_GC_${gc.toUpperCase}"
123+
}
124+
125+
val gcPath = nativeCodePath.resolve("gc").abs
126+
127+
config.withCompilerConfig(
128+
_.withCompileOptions(_ :+ ("-I" + gcPath) :+ gcFlag)
129+
)
130+
}
131+
132+
/** Check for compile Descriptor in destination native code directory.
133+
*
134+
* @param nativeCodePath
135+
* The native code directory
136+
* @return
137+
* The optional path to the file or none
138+
*/
139+
private def findDescriptor(nativeCodePath: Path): Option[Path] = {
140+
val file = nativeCodePath.resolve(nativeProjectProps)
141+
if (Files.exists(file)) Some(file)
142+
else None
42143
}
43144

44145
/** Finds all the native libs on the classpath.
@@ -103,7 +204,7 @@ private[scalanative] object NativeLib {
103204
* @return
104205
* All file paths to compile
105206
*/
106-
def findNativePaths(workDir: Path, destPath: Path): Seq[Path] = {
207+
private def findNativePaths(workDir: Path, destPath: Path): Seq[Path] = {
107208
val srcPatterns = destSrcPattern(workDir, destPath)
108209
IO.getAll(workDir, srcPatterns)
109210
}
@@ -136,7 +237,7 @@ private[scalanative] object NativeLib {
136237
* @return
137238
* The destination path of the directory
138239
*/
139-
def unpackNativeCode(nativelib: NativeLib): Path =
240+
private def unpackNativeCode(nativelib: NativeLib): Path =
140241
if (isJar(nativelib)) unpackNativeJar(nativelib)
141242
else copyNativeDir(nativelib)
142243

0 commit comments

Comments
 (0)