Skip to content

Commit

Permalink
improvement: Detect user config change and prune generated/native sou…
Browse files Browse the repository at this point in the history
…rces on change (#3724)

* Detect user config change and prune generated/native sources on change

* sort resolved sources classpath to ensure stable builds

* fix jdk 8 compliance
  • Loading branch information
WojciechMazur committed Jan 31, 2024
1 parent 15634d1 commit 9b6a339
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -408,34 +408,37 @@ object ScalaNativePluginInternal {
): Seq[Path] = {
if (!userConfig.sourceLevelDebuggingConfig.enabled) Nil
else
externalClassPath.par.flatMap { classpath =>
try {
classpath.metadata
.get(moduleID.key)
.toSeq
.map(_.classifier("sources").withConfigurations(None))
.map(dependencyResolution.wrapDependencyInModule)
.map(
dependencyResolution.update(
_,
UpdateConfiguration(),
UnresolvedWarningConfiguration(),
util.Logger.Null
externalClassPath.par
.flatMap { classpath =>
try {
classpath.metadata
.get(moduleID.key)
.toSeq
.map(_.classifier("sources").withConfigurations(None))
.map(dependencyResolution.wrapDependencyInModule)
.map(
dependencyResolution.update(
_,
UpdateConfiguration(),
UnresolvedWarningConfiguration(),
util.Logger.Null
)
)
)
.flatMap(_.right.toOption)
.flatMap(_.allFiles)
.filter(_.name.endsWith("-sources.jar"))
.map(_.toPath())
} catch {
case ex: Throwable =>
log.warn(
s"Failed to resolved sources of classpath entry '$classpath', source level debuging might work incorrectly"
)
log.trace(ex)
Nil
.flatMap(_.right.toOption)
.flatMap(_.allFiles)
.filter(_.name.endsWith("-sources.jar"))
.map(_.toPath())
} catch {
case ex: Throwable =>
log.warn(
s"Failed to resolved sources of classpath entry '$classpath', source level debuging might work incorrectly"
)
log.trace(ex)
Nil
}
}
}.seq
.seq
.sorted
}

}
24 changes: 24 additions & 0 deletions tools/src/main/scala/scala/scalanative/build/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import scala.scalanative.util.Scope
import scala.scalanative.linker.ReachabilityAnalysis
import scala.util.Try
import java.nio.file.FileVisitOption
import java.nio.file.StandardOpenOption
import java.util.Optional
import java.nio.file.attribute.FileTime
import scala.concurrent._
Expand Down Expand Up @@ -123,6 +124,7 @@ object Build {
.map(objects => link(config, linkerResult, objects))
.map(artifact => postProcess(config, artifact))
)
.andThen { case Success(_) => dumpUserConfigHash(config) }
}
}

Expand Down Expand Up @@ -300,4 +302,26 @@ object Build {
.max(_.compareTo(_))
else Optional.empty()

private[scalanative] final val userConfigHashFile = "userConfigHash"

private[scalanative] def userConfigHasChanged(config: Config): Boolean = {
val hashFile = config.workDir.resolve(userConfigHashFile)
!Files.exists(hashFile) || {
val source = scala.io.Source.fromFile(hashFile.toFile())
try source.mkString.trim() != config.compilerConfig.##.toString()
finally source.close()
}
}

private[scalanative] def dumpUserConfigHash(config: Config): Unit = {
val hashFile = config.workDir.resolve(userConfigHashFile)
Files.createDirectories(hashFile.getParent())
Files.write(
hashFile,
config.compilerConfig.##.toString().getBytes(),
StandardOpenOption.CREATE,
StandardOpenOption.WRITE
)
}

}
2 changes: 2 additions & 0 deletions tools/src/main/scala/scala/scalanative/build/NativeLib.scala
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ private[scalanative] object NativeLib {
val workDir = config.workDir
val classpath = config.classPath
val nativeCodeDir = workDir.resolve("dependencies")
if (Build.userConfigHasChanged(config))
IO.deleteRecursive(nativeCodeDir)

val nativeLibPaths = classpath.flatMap { path =>
if (isJar(path)) readJar(path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import java.nio.file.{Path, Paths, Files}
import scala.collection.mutable
import scala.scalanative.build.Config
import scala.scalanative.build.ScalaNative.{dumpDefns, encodedMainClass}
import scala.scalanative.build.Build
import scala.scalanative.io.VirtualDirectory
import scala.scalanative.build
import scala.scalanative.build.IO
import scala.scalanative.linker.ReachabilityAnalysis
import scala.scalanative.util.{Scope, partitionBy, procs}
import java.nio.file.StandardCopyOption

import scala.scalanative.build.ScalaNative
import scala.scalanative.codegen.{Metadata => CodeGenMetadata}
import scala.concurrent._
import scala.util.Success
Expand Down Expand Up @@ -69,6 +70,8 @@ object CodeGen {
Scope { implicit in =>
val env = assembly.map(defn => defn.name -> defn).toMap
val outputDirPath = config.workDir.resolve("generated")
if (Build.userConfigHasChanged(config))
IO.deleteRecursive(outputDirPath)
Files.createDirectories(outputDirPath)
val outputDir = VirtualDirectory.real(outputDirPath)
val sourceCodeCache = new SourceCodeCache(config)
Expand Down

0 comments on commit 9b6a339

Please sign in to comment.