mirror of https://github.com/sbt/sbt.git
Merge pull request #2197 from Duhemm/fix-2196
Fixes #2196, Specify the compiler bridge module in a setting
This commit is contained in:
commit
5401a77b86
|
|
@ -15,7 +15,7 @@ object ComponentCompiler {
|
|||
val compilerInterfaceSrcID = compilerInterfaceID + srcExtension
|
||||
val javaVersion = System.getProperty("java.class.version")
|
||||
|
||||
@deprecated("Use `interfaceProvider(ComponentManager, IvyConfiguration, File)`.", "0.13.10")
|
||||
@deprecated("Use `interfaceProvider(ComponentManager, IvyConfiguration, ModuleID)`.", "0.13.10")
|
||||
def interfaceProvider(manager: ComponentManager): CompilerInterfaceProvider = new CompilerInterfaceProvider {
|
||||
def apply(scalaInstance: xsbti.compile.ScalaInstance, log: Logger): File =
|
||||
{
|
||||
|
|
@ -26,13 +26,13 @@ object ComponentCompiler {
|
|||
}
|
||||
}
|
||||
|
||||
def interfaceProvider(manager: ComponentManager, ivyConfiguration: IvyConfiguration, bootDirectory: File): CompilerInterfaceProvider = new CompilerInterfaceProvider {
|
||||
def interfaceProvider(manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID): CompilerInterfaceProvider = new CompilerInterfaceProvider {
|
||||
def apply(scalaInstance: xsbti.compile.ScalaInstance, log: Logger): File =
|
||||
{
|
||||
// this is the instance used to compile the interface component
|
||||
val componentCompiler = new IvyComponentCompiler(new RawCompiler(scalaInstance, ClasspathOptions.auto, log), manager, ivyConfiguration, bootDirectory, log)
|
||||
log.debug("Getting " + compilerInterfaceID + " from component compiler for Scala " + scalaInstance.version)
|
||||
componentCompiler(compilerInterfaceID)
|
||||
val componentCompiler = new IvyComponentCompiler(new RawCompiler(scalaInstance, ClasspathOptions.auto, log), manager, ivyConfiguration, sourcesModule, log)
|
||||
log.debug("Getting " + sourcesModule + " from component compiler for Scala " + scalaInstance.version)
|
||||
componentCompiler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -80,12 +80,12 @@ class ComponentCompiler(compiler: RawCompiler, manager: ComponentManager) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Component compiler which is able to find the most specific version available of
|
||||
* the compiler interface sources using Ivy.
|
||||
* Component compiler which is able to to retrieve the compiler bridge sources
|
||||
* `sourceModule` using Ivy.
|
||||
* The compiled classes are cached using the provided component manager according
|
||||
* to the actualVersion field of the RawCompiler.
|
||||
*/
|
||||
private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: ComponentManager, ivyConfiguration: IvyConfiguration, bootDirectory: File, log: Logger) {
|
||||
private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID, log: Logger) {
|
||||
import ComponentCompiler._
|
||||
|
||||
private val sbtOrg = xsbti.ArtifactInfo.SbtOrganization
|
||||
|
|
@ -94,11 +94,11 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com
|
|||
private val ivySbt: IvySbt = new IvySbt(ivyConfiguration)
|
||||
private val sbtVersion = ComponentManager.version
|
||||
private val buffered = new BufferedLogger(FullLogger(log))
|
||||
private val retrieveDirectory = new File(s"$bootDirectory/scala-${compiler.scalaInstance.version}/$sbtOrg/sbt/$sbtVersion/compiler-interface-srcs")
|
||||
|
||||
def apply(id: String): File = {
|
||||
val binID = binaryID(id)
|
||||
manager.file(binID)(new IfMissing.Define(true, compileAndInstall(id, binID)))
|
||||
def apply(): File = {
|
||||
// binID is of the form "org.example-compilerbridge-1.0.0-bin_2.11.7__50.0"
|
||||
val binID = binaryID(s"${sourcesModule.organization}-${sourcesModule.name}-${sourcesModule.revision}")
|
||||
manager.file(binID)(new IfMissing.Define(true, compileAndInstall(binID)))
|
||||
}
|
||||
|
||||
private def binaryID(id: String): String = {
|
||||
|
|
@ -106,53 +106,36 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com
|
|||
base + "__" + javaVersion
|
||||
}
|
||||
|
||||
private def compileAndInstall(id: String, binID: String): Unit = {
|
||||
def interfaceSources(moduleVersions: Vector[VersionNumber]): Iterable[File] =
|
||||
moduleVersions match {
|
||||
case Vector() =>
|
||||
def getAndDefineDefaultSources() =
|
||||
update(getModule(id))(_.getName endsWith "-sources.jar") map { sourcesJar =>
|
||||
manager.define(id, sourcesJar)
|
||||
sourcesJar
|
||||
} getOrElse (throw new InvalidComponent(s"Couldn't retrieve default sources: module '$id'"))
|
||||
|
||||
buffered.debug(s"Fetching default sources: module '$id'")
|
||||
manager.files(id)(new IfMissing.Fallback(getAndDefineDefaultSources()))
|
||||
|
||||
case version +: rest =>
|
||||
val moduleName = s"${id}_$version"
|
||||
def getAndDefineVersionSpecificSources() =
|
||||
update(getModule(moduleName))(_.getName endsWith "-sources.jar") map { sourcesJar =>
|
||||
manager.define(moduleName, sourcesJar)
|
||||
sourcesJar
|
||||
} getOrElse interfaceSources(rest)
|
||||
|
||||
buffered.debug(s"Fetching version-specific sources: module '$moduleName'")
|
||||
manager.files(moduleName)(new IfMissing.Fallback(getAndDefineVersionSpecificSources()))
|
||||
}
|
||||
private def compileAndInstall(binID: String): Unit =
|
||||
IO.withTemporaryDirectory { binaryDirectory =>
|
||||
|
||||
val targetJar = new File(binaryDirectory, s"$binID.jar")
|
||||
val xsbtiJars = manager.files(xsbtiID)(IfMissing.Fail)
|
||||
|
||||
val sourceModuleVersions = VersionNumber(compiler.scalaInstance.actualVersion).cascadingVersions
|
||||
val sources = buffered bufferQuietly interfaceSources(sourceModuleVersions)
|
||||
AnalyzingCompiler.compileSources(sources, targetJar, xsbtiJars, id, compiler, log)
|
||||
buffered bufferQuietly {
|
||||
|
||||
manager.define(binID, Seq(targetJar))
|
||||
IO.withTemporaryDirectory { retrieveDirectory =>
|
||||
(update(getModule(sourcesModule), retrieveDirectory)(_.getName endsWith "-sources.jar")) match {
|
||||
case Some(sources) =>
|
||||
AnalyzingCompiler.compileSources(sources, targetJar, xsbtiJars, sourcesModule.name, compiler, log)
|
||||
manager.define(binID, Seq(targetJar))
|
||||
|
||||
case None =>
|
||||
throw new InvalidComponent(s"Couldn't retrieve source module: $sourcesModule")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a dummy module that depends on "org.scala-sbt" % `id` % `sbtVersion`.
|
||||
* Returns a dummy module that depends on `moduleID`.
|
||||
* Note: Sbt's implementation of Ivy requires us to do this, because only the dependencies
|
||||
* of the specified module will be downloaded.
|
||||
*/
|
||||
private def getModule(id: String): ivySbt.Module = {
|
||||
val sha1 = Hash.toHex(Hash(id))
|
||||
val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, sbtVersion, Some("component"))
|
||||
val moduleID = ModuleID(sbtOrg, id, sbtVersion, Some("component")).sources()
|
||||
private def getModule(moduleID: ModuleID): ivySbt.Module = {
|
||||
val sha1 = Hash.toHex(Hash(moduleID.name))
|
||||
val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, moduleID.revision, moduleID.configurations)
|
||||
getModule(dummyID, Seq(moduleID))
|
||||
}
|
||||
|
||||
|
|
@ -179,7 +162,7 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com
|
|||
s"unknown"
|
||||
}
|
||||
|
||||
private def update(module: ivySbt.Module)(predicate: File => Boolean): Option[Seq[File]] = {
|
||||
private def update(module: ivySbt.Module, retrieveDirectory: File)(predicate: File => Boolean): Option[Seq[File]] = {
|
||||
|
||||
val retrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, Resolver.defaultRetrievePattern, false)
|
||||
val updateConfiguration = new UpdateConfiguration(Some(retrieveConfiguration), true, UpdateLogging.DownloadOnly)
|
||||
|
|
|
|||
|
|
@ -39,8 +39,6 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr
|
|||
d()
|
||||
if (d.cache) cache(id)
|
||||
getOrElse(notFound)
|
||||
case f: IfMissing.Fallback =>
|
||||
f()
|
||||
}
|
||||
|
||||
lockLocalCache { getOrElse(fromGlobal) }
|
||||
|
|
@ -75,7 +73,6 @@ sealed trait IfMissing extends NotNull
|
|||
object IfMissing {
|
||||
object Fail extends IfMissing
|
||||
final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define }
|
||||
final class Fallback(f: => Iterable[File]) extends IfMissing { def apply() = f }
|
||||
}
|
||||
object ComponentManager {
|
||||
lazy val (version, timestamp) =
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ object Compiler {
|
|||
def compilers(instance: ScalaInstance, cpOptions: ClasspathOptions)(implicit app: AppConfiguration, log: Logger): Compilers =
|
||||
compilers(instance, cpOptions, None)
|
||||
|
||||
@deprecated("Use `compilers(ScalaInstance, ClasspathOptions, Option[File], IvyConfiguration)`.", "0.13.10")
|
||||
@deprecated("Use `compilers(ScalaInstance, ClasspathOptions, Option[File], IvyConfiguration, ModuleID)`.", "0.13.10")
|
||||
def compilers(instance: ScalaInstance, cpOptions: ClasspathOptions, javaHome: Option[File])(implicit app: AppConfiguration, log: Logger): Compilers =
|
||||
{
|
||||
val javac =
|
||||
|
|
@ -69,7 +69,7 @@ object Compiler {
|
|||
}
|
||||
compilers(instance, cpOptions, CheaterJavaTool(javac2, javac))
|
||||
}
|
||||
def compilers(instance: ScalaInstance, cpOptions: ClasspathOptions, javaHome: Option[File], ivyConfiguration: IvyConfiguration)(implicit app: AppConfiguration, log: Logger): Compilers =
|
||||
def compilers(instance: ScalaInstance, cpOptions: ClasspathOptions, javaHome: Option[File], ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID)(implicit app: AppConfiguration, log: Logger): Compilers =
|
||||
{
|
||||
val javac =
|
||||
AggressiveCompile.directOrFork(instance, cpOptions, javaHome)
|
||||
|
|
@ -81,7 +81,7 @@ object Compiler {
|
|||
javac.compile(contract, sources, classpath, outputDirectory, options)(log)
|
||||
def onArgs(f: Seq[String] => Unit): JavaTool = CheaterJavaTool(newJavac, delegate.onArgs(f))
|
||||
}
|
||||
val scalac = scalaCompiler(instance, cpOptions, ivyConfiguration)
|
||||
val scalac = scalaCompiler(instance, cpOptions, ivyConfiguration, sourcesModule)
|
||||
new Compilers(scalac, CheaterJavaTool(javac2, javac))
|
||||
}
|
||||
@deprecated("Deprecated in favor of new sbt.compiler.javac package.", "0.13.8")
|
||||
|
|
@ -96,7 +96,7 @@ object Compiler {
|
|||
val scalac = scalaCompiler(instance, cpOptions)
|
||||
new Compilers(scalac, javac)
|
||||
}
|
||||
@deprecated("Use `scalaCompiler(ScalaInstance, ClasspathOptions, IvyConfiguration)`.", "0.13.10")
|
||||
@deprecated("Use `scalaCompiler(ScalaInstance, ClasspathOptions, IvyConfiguration, ModuleID)`.", "0.13.10")
|
||||
def scalaCompiler(instance: ScalaInstance, cpOptions: ClasspathOptions)(implicit app: AppConfiguration, log: Logger): AnalyzingCompiler =
|
||||
{
|
||||
val launcher = app.provider.scalaProvider.launcher
|
||||
|
|
@ -104,12 +104,11 @@ object Compiler {
|
|||
val provider = ComponentCompiler.interfaceProvider(componentManager)
|
||||
new AnalyzingCompiler(instance, provider, cpOptions)
|
||||
}
|
||||
def scalaCompiler(instance: ScalaInstance, cpOptions: ClasspathOptions, ivyConfiguration: IvyConfiguration)(implicit app: AppConfiguration, log: Logger): AnalyzingCompiler =
|
||||
def scalaCompiler(instance: ScalaInstance, cpOptions: ClasspathOptions, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID)(implicit app: AppConfiguration, log: Logger): AnalyzingCompiler =
|
||||
{
|
||||
val launcher = app.provider.scalaProvider.launcher
|
||||
val componentManager = new ComponentManager(launcher.globalLock, app.provider.components, Option(launcher.ivyHome), log)
|
||||
val bootDirectory = launcher.bootDirectory
|
||||
val provider = ComponentCompiler.interfaceProvider(componentManager, ivyConfiguration, bootDirectory)
|
||||
val provider = ComponentCompiler.interfaceProvider(componentManager, ivyConfiguration, sourcesModule)
|
||||
new AnalyzingCompiler(instance, provider, cpOptions)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -232,7 +232,8 @@ object Defaults extends BuildCommon {
|
|||
clean := {
|
||||
val _ = clean.value
|
||||
IvyActions.cleanCachedResolutionCache(ivyModule.value, streams.value.log)
|
||||
}
|
||||
},
|
||||
scalaCompilerBridgeSource := ModuleID(xsbti.ArtifactInfo.SbtOrganization, "compiler-interface", sbtVersion.value, Some("component")).sources()
|
||||
)
|
||||
// must be a val: duplication detected by object identity
|
||||
private[this] lazy val compileBaseGlobal: Seq[Setting[_]] = globalDefaults(Seq(
|
||||
|
|
@ -261,7 +262,7 @@ object Defaults extends BuildCommon {
|
|||
if (plugin) scalaBase / ("sbt-" + sbtv) else scalaBase
|
||||
}
|
||||
|
||||
def compilersSetting = compilers := Compiler.compilers(scalaInstance.value, classpathOptions.value, javaHome.value, ivyConfiguration.value)(appConfiguration.value, streams.value.log)
|
||||
def compilersSetting = compilers := Compiler.compilers(scalaInstance.value, classpathOptions.value, javaHome.value, ivyConfiguration.value, scalaCompilerBridgeSource.value)(appConfiguration.value, streams.value.log)
|
||||
|
||||
lazy val configTasks = docTaskSettings(doc) ++ inTask(compile)(compileInputsSettings) ++ configGlobal ++ compileAnalysisSettings ++ Seq(
|
||||
compile <<= compileTask,
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ object Keys {
|
|||
val sbtPlugin = SettingKey[Boolean]("sbt-plugin", "If true, enables adding sbt as a dependency and auto-generation of the plugin descriptor file.", BMinusSetting)
|
||||
val printWarnings = TaskKey[Unit]("print-warnings", "Shows warnings from compilation, including ones that weren't printed initially.", BPlusTask)
|
||||
val fileInputOptions = SettingKey[Seq[String]]("file-input-options", "Options that take file input, which may invalidate the cache.", CSetting)
|
||||
val scalaCompilerBridgeSource = SettingKey[ModuleID]("scala-compiler-bridge-source", "Configures the module ID of the sources of the compiler bridge.", CSetting)
|
||||
|
||||
val clean = TaskKey[Unit]("clean", "Deletes files produced by the build, such as generated sources, compiled classes, and task caches.", APlusTask)
|
||||
val console = TaskKey[Unit]("console", "Starts the Scala interpreter with the project classes on the classpath.", APlusTask)
|
||||
|
|
|
|||
Loading…
Reference in New Issue