2019-01-02 18:55:26 +08:00
|
|
|
|
/*
|
2021-01-08 17:55:38 +01:00
|
|
|
|
* Copyright (C) 2009-2021 Lightbend Inc. <https://www.lightbend.com>
|
2011-11-25 11:01:03 +01:00
|
|
|
|
*/
|
|
|
|
|
|
|
2011-09-23 10:21:03 +02:00
|
|
|
|
package akka
|
|
|
|
|
|
|
2019-06-04 16:41:47 +02:00
|
|
|
|
import java.io.FileReader
|
2021-02-01 15:38:29 +00:00
|
|
|
|
import java.io.{ FileInputStream, InputStreamReader }
|
2012-12-18 12:10:59 +01:00
|
|
|
|
import java.util.Properties
|
2019-05-20 11:31:46 +02:00
|
|
|
|
import java.time.format.DateTimeFormatter
|
|
|
|
|
|
import java.time.ZonedDateTime
|
|
|
|
|
|
import java.time.ZoneOffset
|
2019-10-03 16:42:41 +02:00
|
|
|
|
import com.lightbend.paradox.projectinfo.ParadoxProjectInfoPluginKeys._
|
2019-10-24 16:31:28 -04:00
|
|
|
|
import com.typesafe.sbt.MultiJvmPlugin.autoImport.MultiJvm
|
|
|
|
|
|
import sbtassembly.AssemblyPlugin.autoImport._
|
2014-07-08 18:30:15 +02:00
|
|
|
|
|
2019-10-03 05:02:40 +02:00
|
|
|
|
import sbt.Keys._
|
2017-06-09 04:34:21 -07:00
|
|
|
|
import sbt._
|
2019-10-03 05:02:40 +02:00
|
|
|
|
import JdkOptions.autoImport._
|
2017-10-04 14:22:25 +02:00
|
|
|
|
import scala.collection.breakOut
|
2011-07-04 19:16:43 +12:00
|
|
|
|
|
2017-05-16 22:03:18 +02:00
|
|
|
|
object AkkaBuild {
|
2012-12-18 12:10:59 +01:00
|
|
|
|
|
2015-04-30 09:23:18 +02:00
|
|
|
|
val enableMiMa = true
|
2012-06-28 15:33:49 +02:00
|
|
|
|
|
2016-05-10 10:49:33 +02:00
|
|
|
|
val parallelExecutionByDefault = false // TODO: enable this once we're sure it does not break things
|
2015-05-05 19:39:56 +02:00
|
|
|
|
|
2021-02-01 15:38:29 +00:00
|
|
|
|
lazy val buildSettings = Def.settings(organization := "com.typesafe.akka", Dependencies.Versions)
|
2019-06-04 16:41:47 +02:00
|
|
|
|
|
2019-05-21 17:35:42 +01:00
|
|
|
|
lazy val rootSettings = Def.settings(
|
|
|
|
|
|
UnidocRoot.akkaSettings,
|
|
|
|
|
|
Protobuf.settings,
|
2021-05-25 12:50:51 +02:00
|
|
|
|
GlobalScope / parallelExecution := System
|
2021-02-01 15:38:29 +00:00
|
|
|
|
.getProperty("akka.parallelExecution", parallelExecutionByDefault.toString)
|
|
|
|
|
|
.toBoolean,
|
2019-10-03 16:42:41 +02:00
|
|
|
|
// used for linking to API docs (overwrites `project-info.version`)
|
2021-02-01 15:38:29 +00:00
|
|
|
|
ThisBuild / projectInfoVersion := { if (isSnapshot.value) "snapshot" else version.value })
|
2019-05-21 17:35:42 +01:00
|
|
|
|
|
2021-02-01 15:38:29 +00:00
|
|
|
|
lazy val mayChangeSettings = Seq(description := """|This module of Akka is marked as
|
2017-02-20 12:05:21 +01:00
|
|
|
|
|'may change', which means that it is in early
|
2012-09-27 15:57:46 +02:00
|
|
|
|
|access mode, which also means that it is not covered
|
2017-02-20 12:05:21 +01:00
|
|
|
|
|by commercial support. An module marked 'may change' doesn't
|
2012-09-27 15:57:46 +02:00
|
|
|
|
|have to obey the rule of staying binary compatible
|
|
|
|
|
|
|between minor releases. Breaking API changes may be
|
|
|
|
|
|
|introduced in minor releases without notice as we
|
2017-02-20 12:05:21 +01:00
|
|
|
|
|refine and simplify based on your feedback. Additionally
|
|
|
|
|
|
|such a module may be dropped in major releases
|
2012-09-27 15:57:46 +02:00
|
|
|
|
|without prior deprecation.
|
2017-10-06 10:30:28 +02:00
|
|
|
|
|""".stripMargin)
|
2012-09-27 15:57:46 +02:00
|
|
|
|
|
2014-02-06 08:56:08 +01:00
|
|
|
|
val (mavenLocalResolver, mavenLocalResolverSettings) =
|
|
|
|
|
|
System.getProperty("akka.build.M2Dir") match {
|
2019-02-09 15:25:39 +01:00
|
|
|
|
case null => (Resolver.mavenLocal, Seq.empty)
|
|
|
|
|
|
case path =>
|
2014-02-06 08:56:08 +01:00
|
|
|
|
// Maven resolver settings
|
2017-10-30 03:13:14 +02:00
|
|
|
|
def deliverPattern(outputPath: File): String =
|
|
|
|
|
|
(outputPath / "[artifact]-[revision](-[classifier]).[ext]").absolutePath
|
|
|
|
|
|
|
2014-02-06 08:56:08 +01:00
|
|
|
|
val resolver = Resolver.file("user-publish-m2-local", new File(path))
|
2021-02-01 15:38:29 +00:00
|
|
|
|
(
|
|
|
|
|
|
resolver,
|
|
|
|
|
|
Seq(
|
|
|
|
|
|
otherResolvers := resolver :: publishTo.value.toList,
|
|
|
|
|
|
publishM2Configuration := Classpaths.publishConfig(
|
|
|
|
|
|
publishMavenStyle.value,
|
|
|
|
|
|
deliverPattern(crossTarget.value),
|
|
|
|
|
|
if (isSnapshot.value) "integration" else "release",
|
|
|
|
|
|
ivyConfigurations.value.map(c => ConfigRef(c.name)).toVector,
|
|
|
|
|
|
artifacts = packagedArtifacts.value.toVector,
|
|
|
|
|
|
resolverName = resolver.name,
|
2021-05-25 12:50:51 +02:00
|
|
|
|
checksums = (publishM2 / checksums).value.toVector,
|
2021-02-01 15:38:29 +00:00
|
|
|
|
logging = ivyLoggingLevel.value,
|
|
|
|
|
|
overwrite = true)))
|
2014-02-06 08:56:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-21 17:35:42 +01:00
|
|
|
|
lazy val resolverSettings = Def.settings(
|
2013-12-03 09:18:26 +01:00
|
|
|
|
// should we be allowed to use artifacts published to the local maven repository
|
2017-10-06 10:30:28 +02:00
|
|
|
|
if (System.getProperty("akka.build.useLocalMavenResolver", "false").toBoolean)
|
2019-05-21 17:35:42 +01:00
|
|
|
|
resolvers += mavenLocalResolver
|
|
|
|
|
|
else Seq.empty,
|
2013-12-03 09:18:26 +01:00
|
|
|
|
// should we be allowed to use artifacts from sonatype snapshots
|
2017-10-06 10:30:28 +02:00
|
|
|
|
if (System.getProperty("akka.build.useSnapshotSonatypeResolver", "false").toBoolean)
|
2019-05-21 17:35:42 +01:00
|
|
|
|
resolvers += Resolver.sonatypeRepo("snapshots")
|
|
|
|
|
|
else Seq.empty,
|
2021-02-01 15:38:29 +00:00
|
|
|
|
pomIncludeRepository := (_ => false) // do not leak internal repositories during staging
|
2014-02-28 10:12:29 +01:00
|
|
|
|
)
|
2013-12-03 09:18:26 +01:00
|
|
|
|
|
2015-01-30 18:34:03 +01:00
|
|
|
|
private def allWarnings: Boolean = System.getProperty("akka.allwarnings", "false").toBoolean
|
2015-01-30 11:33:33 +01:00
|
|
|
|
|
2021-02-01 15:38:29 +00:00
|
|
|
|
final val DefaultScalacOptions = {
|
|
|
|
|
|
if (Dependencies.getScalaVersion().startsWith("3.0")) {
|
|
|
|
|
|
Seq(
|
|
|
|
|
|
"-encoding",
|
|
|
|
|
|
"UTF-8",
|
|
|
|
|
|
"-feature",
|
|
|
|
|
|
"-unchecked",
|
|
|
|
|
|
// 'blessed' since 2.13.1
|
|
|
|
|
|
"-language:higherKinds")
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Seq(
|
|
|
|
|
|
"-encoding",
|
|
|
|
|
|
"UTF-8",
|
|
|
|
|
|
"-feature",
|
|
|
|
|
|
"-unchecked",
|
|
|
|
|
|
"-Xlog-reflective-calls",
|
|
|
|
|
|
// 'blessed' since 2.13.1
|
|
|
|
|
|
"-language:higherKinds")
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-07-02 16:38:07 +02:00
|
|
|
|
|
|
|
|
|
|
// -XDignore.symbol.file suppresses sun.misc.Unsafe warnings
|
|
|
|
|
|
final val DefaultJavacOptions = Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-XDignore.symbol.file")
|
|
|
|
|
|
|
2019-05-21 17:35:42 +01:00
|
|
|
|
lazy val defaultSettings: Seq[Setting[_]] = Def.settings(
|
|
|
|
|
|
resolverSettings,
|
|
|
|
|
|
TestExtras.Filter.settings,
|
|
|
|
|
|
// compile options
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Compile / scalacOptions ++= DefaultScalacOptions,
|
|
|
|
|
|
Compile / scalacOptions ++=
|
2019-11-08 15:59:49 +01:00
|
|
|
|
JdkOptions.targetJdkScalacOptions(targetSystemJdk.value, optionalDir(jdk8home.value), fullJavaHomes.value),
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Compile / scalacOptions ++= (if (allWarnings) Seq("-deprecation") else Nil),
|
|
|
|
|
|
Test / scalacOptions := (Test / scalacOptions).value.filterNot(opt =>
|
2021-02-01 15:38:29 +00:00
|
|
|
|
opt == "-Xlog-reflective-calls" || opt.contains("genjavadoc")),
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Compile / javacOptions ++= {
|
2020-08-05 13:12:29 +01:00
|
|
|
|
DefaultJavacOptions ++
|
2021-02-01 15:38:29 +00:00
|
|
|
|
JdkOptions.targetJdkJavacOptions(targetSystemJdk.value, optionalDir(jdk8home.value), fullJavaHomes.value)
|
2020-08-05 13:12:29 +01:00
|
|
|
|
},
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Test / javacOptions ++= DefaultJavacOptions ++
|
2019-11-08 15:59:49 +01:00
|
|
|
|
JdkOptions.targetJdkJavacOptions(targetSystemJdk.value, optionalDir(jdk8home.value), fullJavaHomes.value),
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Compile / javacOptions ++= (if (allWarnings) Seq("-Xlint:deprecation") else Nil),
|
|
|
|
|
|
doc / javacOptions := Seq(),
|
2019-05-21 17:35:42 +01:00
|
|
|
|
crossVersion := CrossVersion.binary,
|
2021-07-12 18:32:01 +02:00
|
|
|
|
// Adds a `src/main/scala-2.13+` source directory for code shared
|
|
|
|
|
|
// between Scala 2.13 and Scala 3
|
2021-08-19 20:03:07 -04:00
|
|
|
|
Compile / unmanagedSourceDirectories ++= {
|
|
|
|
|
|
val sourceDir = (Compile / sourceDirectory).value
|
2021-07-12 18:32:01 +02:00
|
|
|
|
CrossVersion.partialVersion(scalaVersion.value) match {
|
|
|
|
|
|
case Some((3, n)) => Seq(sourceDir / "scala-2.13+")
|
|
|
|
|
|
case Some((2, n)) if n >= 13 => Seq(sourceDir / "scala-2.13+")
|
|
|
|
|
|
case _ => Nil
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2021-05-25 12:50:51 +02:00
|
|
|
|
ThisBuild / ivyLoggingLevel := UpdateLogging.Quiet,
|
2019-07-09 21:54:33 +10:00
|
|
|
|
licenses := Seq(("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0.html"))),
|
2019-05-21 17:35:42 +01:00
|
|
|
|
homepage := Some(url("https://akka.io/")),
|
2019-06-02 13:42:01 +02:00
|
|
|
|
description := "Akka is a toolkit for building highly concurrent, distributed, and resilient message-driven applications for Java and Scala.",
|
2021-02-01 15:38:29 +00:00
|
|
|
|
scmInfo := Some(
|
|
|
|
|
|
ScmInfo(
|
|
|
|
|
|
url("https://github.com/akka/akka"),
|
|
|
|
|
|
"scm:git:https://github.com/akka/akka.git",
|
|
|
|
|
|
"scm:git:git@github.com:akka/akka.git")),
|
2019-05-21 17:35:42 +01:00
|
|
|
|
apiURL := Some(url(s"https://doc.akka.io/api/akka/${version.value}")),
|
|
|
|
|
|
initialCommands :=
|
|
|
|
|
|
"""|import language.postfixOps
|
2013-03-06 09:44:34 +01:00
|
|
|
|
|import akka.actor._
|
|
|
|
|
|
|import scala.concurrent._
|
|
|
|
|
|
|import com.typesafe.config.ConfigFactory
|
|
|
|
|
|
|import scala.concurrent.duration._
|
|
|
|
|
|
|import akka.util.Timeout
|
2013-03-07 19:59:59 +01:00
|
|
|
|
|var config = ConfigFactory.parseString("akka.stdout-loglevel=INFO,akka.loglevel=DEBUG,pinned{type=PinnedDispatcher,executor=thread-pool-executor,throughput=1000}")
|
2019-05-01 08:12:09 +01:00
|
|
|
|
|var remoteConfig = ConfigFactory.parseString("akka.remote.classic.netty{port=0,use-dispatcher-for-io=akka.actor.default-dispatcher,execution-pool-size=0},akka.actor.provider=remote").withFallback(config)
|
2013-03-06 09:44:34 +01:00
|
|
|
|
|var system: ActorSystem = null
|
2021-08-13 13:56:38 +02:00
|
|
|
|
|implicit def _system: ActorSystem = system
|
|
|
|
|
|
|def startSystem(remoting: Boolean = false) = { system = ActorSystem("repl", if(remoting) remoteConfig else config); println("don’t forget to system.terminate()!") }
|
|
|
|
|
|
|implicit def ec: ExecutionContext = system.dispatcher
|
2020-04-06 15:01:10 +07:00
|
|
|
|
|implicit val timeout: Timeout = Timeout(5 seconds)
|
2013-03-06 09:44:34 +01:00
|
|
|
|
|""".stripMargin,
|
2019-05-21 17:35:42 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Test settings
|
|
|
|
|
|
*/
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Test / fork := true,
|
2019-05-21 17:35:42 +01:00
|
|
|
|
// default JVM config for tests
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Test / javaOptions ++= {
|
2019-05-21 17:35:42 +01:00
|
|
|
|
val defaults = Seq(
|
|
|
|
|
|
// ## core memory settings
|
|
|
|
|
|
"-XX:+UseG1GC",
|
|
|
|
|
|
// most tests actually don't really use _that_ much memory (>1g usually)
|
|
|
|
|
|
// twice used (and then some) keeps G1GC happy - very few or to no full gcs
|
2021-02-01 15:38:29 +00:00
|
|
|
|
"-Xms3g",
|
|
|
|
|
|
"-Xmx3g",
|
2019-05-21 17:35:42 +01:00
|
|
|
|
// increase stack size (todo why?)
|
|
|
|
|
|
"-Xss2m",
|
|
|
|
|
|
// ## extra memory/gc tuning
|
|
|
|
|
|
// this breaks jstat, but could avoid costly syncs to disc see http://www.evanjones.ca/jvm-mmap-pause.html
|
|
|
|
|
|
"-XX:+PerfDisableSharedMem",
|
|
|
|
|
|
// tell G1GC that we would be really happy if all GC pauses could be kept below this as higher would
|
|
|
|
|
|
// likely start causing test failures in timing tests
|
|
|
|
|
|
"-XX:MaxGCPauseMillis=300",
|
|
|
|
|
|
// nio direct memory limit for artery/aeron (probably)
|
|
|
|
|
|
"-XX:MaxDirectMemorySize=256m",
|
|
|
|
|
|
// faster random source
|
|
|
|
|
|
"-Djava.security.egd=file:/dev/./urandom")
|
|
|
|
|
|
|
|
|
|
|
|
if (sys.props.contains("akka.ci-server"))
|
|
|
|
|
|
defaults ++ Seq("-XX:+PrintGCTimeStamps", "-XX:+PrintGCDetails")
|
|
|
|
|
|
else
|
|
|
|
|
|
defaults
|
|
|
|
|
|
},
|
|
|
|
|
|
// all system properties passed to sbt prefixed with "akka." will be passed on to the forked jvms as is
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Test / javaOptions := {
|
|
|
|
|
|
val base = (Test / javaOptions).value
|
2019-05-21 17:35:42 +01:00
|
|
|
|
val akkaSysProps: Seq[String] =
|
2021-02-01 15:38:29 +00:00
|
|
|
|
sys.props.filter(_._1.startsWith("akka")).map { case (key, value) => s"-D$key=$value" }(breakOut)
|
2019-05-21 17:35:42 +01:00
|
|
|
|
|
|
|
|
|
|
base ++ akkaSysProps
|
|
|
|
|
|
},
|
|
|
|
|
|
// with forked tests the working directory is set to each module's home directory
|
|
|
|
|
|
// rather than the Akka root, some tests depend on Akka root being working dir, so reset
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Test / testGrouping := {
|
|
|
|
|
|
val original: Seq[Tests.Group] = (Test / testGrouping).value
|
2019-05-21 17:35:42 +01:00
|
|
|
|
|
|
|
|
|
|
original.map { group =>
|
|
|
|
|
|
group.runPolicy match {
|
|
|
|
|
|
case Tests.SubProcess(forkOptions) =>
|
2021-02-01 15:38:29 +00:00
|
|
|
|
// format: off
|
2021-08-19 20:03:07 -04:00
|
|
|
|
group.withRunPolicy(Tests.SubProcess(
|
2021-02-01 15:38:29 +00:00
|
|
|
|
forkOptions.withWorkingDirectory(workingDirectory = Some(new File(System.getProperty("user.dir"))))))
|
|
|
|
|
|
// format: on
|
2019-05-21 17:35:42 +01:00
|
|
|
|
case _ => group
|
2017-10-04 14:22:25 +02:00
|
|
|
|
}
|
2019-05-21 17:35:42 +01:00
|
|
|
|
}
|
|
|
|
|
|
},
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Test / parallelExecution := System
|
2021-02-01 15:38:29 +00:00
|
|
|
|
.getProperty("akka.parallelExecution", parallelExecutionByDefault.toString)
|
|
|
|
|
|
.toBoolean,
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Test / logBuffered := System.getProperty("akka.logBufferedTests", "false").toBoolean,
|
2019-05-21 17:35:42 +01:00
|
|
|
|
// show full stack traces and test case durations
|
2021-05-25 12:50:51 +02:00
|
|
|
|
Test / testOptions += Tests.Argument("-oDF"),
|
2019-05-21 17:35:42 +01:00
|
|
|
|
mavenLocalResolverSettings,
|
|
|
|
|
|
docLintingSettings,
|
2019-10-03 05:02:40 +02:00
|
|
|
|
JdkOptions.targetJdkSettings,
|
2019-10-24 16:31:28 -04:00
|
|
|
|
// a workaround for https://github.com/akka/akka/issues/27661
|
|
|
|
|
|
// see also project/Protobuf.scala that introduces /../ to make "intellij happy"
|
|
|
|
|
|
MultiJvm / assembly / fullClasspath := {
|
|
|
|
|
|
val old = (MultiJvm / assembly / fullClasspath).value.toVector
|
|
|
|
|
|
val files = old.map(_.data.getCanonicalFile).distinct
|
2021-02-01 15:38:29 +00:00
|
|
|
|
files.map { x =>
|
|
|
|
|
|
Attributed.blank(x)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2016-01-13 12:00:46 +01:00
|
|
|
|
|
2019-11-08 15:59:49 +01:00
|
|
|
|
private def optionalDir(path: String): Option[File] =
|
|
|
|
|
|
Option(path).filter(_.nonEmpty).map { path =>
|
|
|
|
|
|
val dir = new File(path)
|
|
|
|
|
|
if (!dir.exists)
|
|
|
|
|
|
throw new IllegalArgumentException(s"Path [$path] not found")
|
|
|
|
|
|
dir
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-01-13 12:00:46 +01:00
|
|
|
|
lazy val docLintingSettings = Seq(
|
2021-05-25 12:50:51 +02:00
|
|
|
|
compile / javacOptions ++= Seq("-Xdoclint:none"),
|
|
|
|
|
|
test / javacOptions ++= Seq("-Xdoclint:none"),
|
|
|
|
|
|
doc / javacOptions ++= {
|
2019-10-03 05:02:40 +02:00
|
|
|
|
if (JdkOptions.isJdk8) Seq("-Xdoclint:none")
|
2019-04-03 09:28:56 -04:00
|
|
|
|
else Seq("-Xdoclint:none", "--ignore-source-errors")
|
2021-02-01 15:38:29 +00:00
|
|
|
|
})
|
2019-02-21 15:47:09 +01:00
|
|
|
|
|
2012-12-18 12:10:59 +01:00
|
|
|
|
def loadSystemProperties(fileName: String): Unit = {
|
|
|
|
|
|
import scala.collection.JavaConverters._
|
|
|
|
|
|
val file = new File(fileName)
|
|
|
|
|
|
if (file.exists()) {
|
|
|
|
|
|
println("Loading system properties from file `" + fileName + "`")
|
|
|
|
|
|
val in = new InputStreamReader(new FileInputStream(file), "UTF-8")
|
|
|
|
|
|
val props = new Properties
|
|
|
|
|
|
props.load(in)
|
|
|
|
|
|
in.close()
|
|
|
|
|
|
sys.props ++ props.asScala
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-06 10:30:28 +02:00
|
|
|
|
def majorMinor(version: String): Option[String] = """\d+\.\d+""".r.findFirstIn(version)
|
2011-07-04 19:16:43 +12:00
|
|
|
|
}
|