Skip to content

Commit

Permalink
Merge pull request #1368 from adpi2/2.x-compile-straight-to-jar
Browse files Browse the repository at this point in the history
[2.x] Minor improvements in straight-to-jar compilation
  • Loading branch information
adpi2 authored Jul 1, 2024
2 parents 6a5d274 + 54e9fba commit 405967a
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ package sbt.internal.inc

import sbt.io.IO
import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream
import java.io.File
import java.io.FileOutputStream
import java.util.UUID

import sbt.io.syntax.URL
Expand Down Expand Up @@ -237,6 +239,7 @@ object JarUtils {
cleanupPreviousJar(prevJar, outputJar)
case None =>
compile(Nil)
createOutputJarIfMissing(output)
}
}

Expand Down Expand Up @@ -331,6 +334,12 @@ object JarUtils {
}
}

def createOutputJarIfMissing(output: Output): Unit =
getOutputJar(output).filter(!Files.exists(_)).foreach { jar =>
val outputStream = new ZipOutputStream(new FileOutputStream(jar.toFile))
outputStream.close()
}

/**
* As some javac implementations do not support compiling directly to jar it is
* required to change its output to a directory that is temporary, as after compilation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ object ClassFileManager {
deleteImpl(classes0.toVector.map(toPath(_).toFile))
private def deleteImpl(classes: Vector[File]): Unit = {
val relClasses =
allFiles(classes).map(c => JarUtils.ClassInJar.fromFile(c).toClassFilePath.get)
allFiles(classes).flatMap(c => JarUtils.ClassInJar.fromFile(c).toClassFilePath)
outputJarContent.removeClasses(relClasses.toSet)
JarUtils.removeFromJar(outputJar, relClasses)
}
Expand Down Expand Up @@ -297,14 +297,14 @@ object ClassFileManager {
val classPaths = classes.toVector.map(_.toPath)
val filesInJar =
allPaths(classPaths)
.map(c => JarUtils.ClassInJar.fromPath(c).toClassFilePath.get)
.flatMap(c => JarUtils.ClassInJar.fromPath(c).toClassFilePath)
JarUtils.removeFromJar(outputJar, filesInJar)
outputJarContent.removeClasses(filesInJar.toSet)
}
override def delete(classes: Array[VirtualFile]): Unit = {
val classPaths = classes.toVector.map(toPath)
val filesInJar =
allPaths(classPaths).map(c => JarUtils.ClassInJar.fromPath(c).toClassFilePath.get)
allPaths(classPaths).flatMap(c => JarUtils.ClassInJar.fromPath(c).toClassFilePath)
JarUtils.removeFromJar(outputJar, filesInJar)
outputJarContent.removeClasses(filesInJar.toSet)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ final class ProtobufWriters(mapper: WriteMapper) {
val compilerVersion = miniSetup.compilerVersion()
val compileOrder = toCompileOrder(miniSetup.order())
val storeApis = miniSetup.storeApis()
val miniBuilder = setMiniSetupOutput(CompileOutput.empty, builder)
val miniBuilder = setMiniSetupOutput(miniSetup.output(), builder)
.setMiniOptions(miniOptions)
.setCompilerVersion(compilerVersion)
.setCompileOrder(compileOrder)
Expand Down
21 changes: 7 additions & 14 deletions zinc/src/main/scala/sbt/internal/inc/IncrementalCompilerImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ class IncrementalCompilerImpl extends IncrementalCompiler {
val equiv = equivCompileSetup(mixedCompiler.log, equivOpts)
previousSetup match {
// The dummy output needs to be changed to .jar for this to work again.
// case _ if compileToJarSwitchedOn(mixedCompiler.config) => Analysis.empty
case _ if compileToJarSwitchedOn(config) => Analysis.empty
case Some(prev) if equiv.equiv(prev, currentSetup) => previousAnalysis
case Some(prev) if !equivPairs.equiv(prev.extra, currentSetup.extra) =>
import sbt.internal.inc.ClassFileManager
Expand All @@ -555,19 +555,12 @@ class IncrementalCompilerImpl extends IncrementalCompiler {
}
}

// private def compileToJarSwitchedOn(config: CompileConfiguration): Boolean = {
// def isCompilingToJar = JarUtils.isCompilingToJar(config.output)
// def previousCompilationWasToJar = config.previousAnalysis match {
// case analysis: Analysis =>
// analysis.relations.allProducts.headOption match {
// case Some(product) => JarUtils.isClassInJar(product)
// case None => true // we can assume it was, as it doesn't matter if there were no products
// }
// case _ => true
// }
//
// isCompilingToJar && !previousCompilationWasToJar
// }
private def compileToJarSwitchedOn(config: CompileConfiguration): Boolean = {
def isCompilingToJar = JarUtils.isCompilingToJar(config.currentSetup.output)
def previousCompilationWasToJar =
config.previousSetup.exists(s => JarUtils.isCompilingToJar(s.output))
isCompilingToJar && !previousCompilationWasToJar
}

def setup(
lookup: PerClasspathEntryLookup,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@ final class MixedAnalyzingCompiler(
// We had this as lazy val, but that caused issues https://github.com/sbt/sbt/issues/5951
def ensureOutput = {
val output = config.currentSetup.output
val outputDirs = outputDirectories(output)
outputDirs.foreach { d =>
val dir =
if (d.toString.endsWith(".jar")) d.getParent
else d
Files.createDirectories(dir)
JarUtils.getOutputJar(output) match {
case Some(jar) =>
Files.createDirectories(jar.getParent)
Seq(jar)
case None =>
val dirs = outputDirectories(output)
dirs.foreach(Files.createDirectories(_))
dirs
}
outputDirs
}

/**
Expand Down

0 comments on commit 405967a

Please sign in to comment.