Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove logic from outside build - 0.5.0 only #2605

Merged
merged 24 commits into from
Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion docs/changelog/0.5.0.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# 0.5.0-SNAPSHOT (mmm dd, 2022)
# 0.5.0-SNAPSHOT (2022-mm-dd)

**WIP**

Expand All @@ -16,6 +16,7 @@ Check out the documentation at
## TL;DR
* **Not backward compatible with previous releases**,
* Removed `java.net.URL` and `java.net.URI.toURL` related stubs we don't plan to implement.
* Various changes to the build system. See "Build Integrator features" below.

## Breaking changes
### Broken backward compatibility
Expand All @@ -28,6 +29,7 @@ client so we don't plan to add the `URL` code to Scala Native.

Third-party libraries may add the removed code listed here into their projects
if they need it for linking.

```scala
package java.net

Expand Down Expand Up @@ -82,6 +84,7 @@ class URLConnection {
If we needed to support a third party library for URL we could follow our normal
extension method to add the following implementation in `java.net.URI` based on
Javadoc and JVM output:

```scala
@scalanative.annotation.stub
def toURL(): java.net.URL = if (this.isAbsolute()) {
Expand All @@ -91,11 +94,50 @@ Javadoc and JVM output:
}
```

### Build integrator features

There are a few features to be used by build tool integrators that have
changed.

- `config.artifactPath` The final artifact is now calculated for the integrator. No need to worry about the extension for Windows.
- Now the `basename` needs to be set if it is not set by the developer
- `config.withTestConfig(true)` for tests to allow a `-test` to be inserted as before. The default is `false` for normal projects.
- `config.withBasedir(crossTarget)` is a Path that needs to be set rather than `workdir`.
- `config.workdir` is now calculated from `basedir` but is available for integrators as needed.

```scala
val nativeConfig = build.NativeConfig.empty
.withBasename(moduleName) // projectName

val config = build.Config.empty
.withLogger(logger)
.withMainClass(mainClass)
.withClassPath(classpath)
.withBasedir(crossTarget) // Path
.withTestConfig(testConfig)
.withCompilerConfig(nativeConfig)
```

### Other breaking changes:
* xxxx

## New features

### User build settings

You can now specify the `basename` of your executable. Typically it will
default to the project name.

```scala
lazy val myproj = project
.in(file("."))
.settings(
nativeConfig ~= { c =>
c.withBasename("myapp")
}
)
```

### Supported Scala versions
We added ...

Expand Down
4 changes: 3 additions & 1 deletion project/BinaryIncompatibilities.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ object BinaryIncompatibilities {
exclude[Problem]("scala.scalanative.build.GC.this"),
exclude[ReversedMissingMethodProblem](
"scala.scalanative.build.NativeConfig*"
)
),
exclude[ReversedMissingMethodProblem]("scala.scalanative.build.Config*"),
exclude[Problem]("scala.scalanative.build.Config*Impl*")
)

final val NativeLib = Seq()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ private[sbtplugin] object NativeLinkCacheImplicits {
build.Config.empty
.withMainClass(mainClass)
.withClassPath(classPath)
.withWorkdir(workdir)
.withBasedir(workdir)
.withCompilerConfig(compilerConfig)
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ object ScalaNativePlugin extends AutoPlugin {
val nativeVersion = nir.Versions.current

val nativeConfig =
taskKey[build.NativeConfig]("Configuration of the Scala Native plugin")
taskKey[build.NativeConfig](
"User configuration for the native build, NativeConfig"
)

val nativeClang =
taskKey[File]("Location of the clang compiler.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import sbt._
import sbt.complete.DefaultParsers._
import scala.annotation.tailrec
import scala.scalanative.util.Scope
import scala.scalanative.build.{Build, BuildException, Discover}
import scala.scalanative.build.{Build, BuildException, Config, Discover}
import scala.scalanative.linker.LinkingException
import scala.scalanative.sbtplugin.ScalaNativePlugin.autoImport.{
ScalaNativeCrossVersion => _,
Expand All @@ -19,16 +19,13 @@ import scala.scalanative.testinterface.adapter.TestAdapter
import scala.sys.process.Process
import scala.util.Try
import scala.scalanative.build.Platform
import java.nio.file.Files
import java.nio.file.{Files, Path}

object ScalaNativePluginInternal {

val nativeWarnOldJVM =
taskKey[Unit]("Warn if JVM 7 or older is used.")

val nativeWorkdir =
taskKey[File]("Working directory for intermediate build files.")

private val nativeStandardLibraries =
Seq("nativelib", "clib", "posixlib", "windowslib", "javalib", "auxlib")

Expand Down Expand Up @@ -109,18 +106,7 @@ object ScalaNativePluginInternal {
}
)

def scalaNativeConfigSettings(nameSuffix: String): Seq[Setting[_]] = Seq(
nativeLink / artifactPath := {
val ext = if (Platform.isWindows) ".exe" else ""
crossTarget.value / s"${moduleName.value}$nameSuffix-out$ext"
},
nativeWorkdir := {
val workdir = crossTarget.value / s"native$nameSuffix"
if (!workdir.exists) {
IO.createDirectory(workdir)
}
workdir
},
def scalaNativeConfigSettings(testConfig: Boolean): Seq[Setting[_]] = Seq(
nativeConfig := {
nativeConfig.value
.withClang(nativeClang.value.toPath)
Expand All @@ -133,30 +119,28 @@ object ScalaNativePluginInternal {
.withLinkStubs(nativeLinkStubs.value)
.withCheck(nativeCheck.value)
.withDump(nativeDump.value)
.withBasename(moduleName.value)
},
nativeLink := {
val classpath = fullClasspath.value.map(_.data.toPath)
val outpath = (nativeLink / artifactPath).value

val config = {
val mainClass = selectMainClass.value.getOrElse {
throw new MessageOnlyException("No main class detected.")
}
val mainClass = selectMainClass.value.getOrElse {
throw new MessageOnlyException("No main class detected.")
}
val logger = streams.value.log.toLogger

val cwd = nativeWorkdir.value.toPath
val config = build.Config.empty
.withLogger(logger)
.withMainClass(mainClass)
.withClassPath(classpath)
.withBasedir(crossTarget.value.toPath())
.withTestConfig(testConfig)
.withCompilerConfig(nativeConfig.value)

val logger = streams.value.log.toLogger
build.Config.empty
.withLogger(logger)
.withMainClass(mainClass)
.withClassPath(classpath)
.withWorkdir(cwd)
.withCompilerConfig(nativeConfig.value)
}
val outfile = config.artifactPath.toFile()

def buildNew(): Unit = {
interceptBuildException {
Build.build(config, outpath.toPath)(sharedScope)
Build.build(config)(sharedScope)
}
}

Expand Down Expand Up @@ -189,16 +173,16 @@ object ScalaNativePluginInternal {
.lastOutput[Seq[HashFileInfo], HashFileInfo](
cacheFactory.make("outputFileInfo")
) { (_, prev) =>
val outputHashInfo = FileInfo.hash(outpath)
val outputHashInfo = FileInfo.hash(outfile)
if (changed || !prev.contains(outputHashInfo)) {
buildNew()
FileInfo.hash(outpath)
FileInfo.hash(outfile)
} else outputHashInfo
}
outputTracker(filesInfo)
}

val classpathFilesInfo = classpath
val classpathFilesInfo = config.classPath
.flatMap { classpath =>
if (Files.exists(classpath))
Files
Expand All @@ -215,7 +199,7 @@ object ScalaNativePluginInternal {
}

buildIfChanged()
outpath
outfile
},
run := {
val env = (run / envVars).value.toSeq
Expand Down Expand Up @@ -244,11 +228,12 @@ object ScalaNativePluginInternal {
}
)

lazy val scalaNativeCompileSettings: Seq[Setting[_]] =
scalaNativeConfigSettings(nameSuffix = "")
lazy val scalaNativeCompileSettings: Seq[Setting[_]] = {
scalaNativeConfigSettings(false)
}

lazy val scalaNativeTestSettings: Seq[Setting[_]] =
scalaNativeConfigSettings(nameSuffix = "-test") ++
scalaNativeConfigSettings(true) ++
Seq(
mainClass := Some("scala.scalanative.testinterface.TestMain"),
loadedTestFrameworks := {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class MainGenericRunner {
Defaults.links.map(_.name).map("-l" + _)
}
}
.withBasename("output")
}
.withClassPath {
val nativeClasspath = loadSetting("nativeCp", Seq.empty[Path]) {
Expand All @@ -70,9 +71,9 @@ class MainGenericRunner {
commandClasspath ++ nativeClasspath
}
.withMainClass(command.thingToRun)
.withWorkdir(dir)
.withBasedir(dir)

Scope { implicit s => Build.build(config, dir.resolve("output")) }
Scope { implicit s => Build.build(config) }
}

val res = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ case class PartestTask(taskDef: TaskDef, args: Array[String]) extends Task {
forkedClasspath: Seq[java.nio.file.Path]
): Seq[java.nio.file.Path] = {
val config = Defaults.config
.withWorkdir(Defaults.workdir())
.withBasedir(Defaults.workdir())
.withClassPath(options.nativeClasspath ++ forkedClasspath)
.withCompilerConfig {
_.withLTO(options.lto)
Expand Down
26 changes: 14 additions & 12 deletions tools/src/main/scala/scala/scalanative/build/Build.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package scala.scalanative
package build

import java.nio.file.{Path, Paths}
import java.nio.file.{Files, Path, Paths}
import scala.scalanative.util.Scope
import scala.scalanative.build.core.Filter
import scala.scalanative.build.core.NativeLib
Expand All @@ -18,16 +18,15 @@ object Build {
*
* {{{
* val classpath: Seq[Path] = ...
* val workdir: Path = ...
* val basedir: Path = ...
* val main: String = ...
* val logger: Logger = ...
*
* val clang = Discover.clang()
* val clangpp = Discover.clangpp()
* val linkopts = Discover.linkingOptions()
* val compopts = Discover.compileOptions()
*
* val outpath = workdir.resolve("out")
*
* val config =
* Config.empty
* .withCompilerConfig{
Expand All @@ -39,25 +38,28 @@ object Build {
* .withLinkingOptions(linkopts)
* .withCompileOptions(compopts)
* .withLinkStubs(true)
* .withBasename("myapp")
* }
* .withMainClass(main)
* .withClassPath(classpath)
* .withWorkdir(workdir)
* .withBasedir(basedir)
* .withTestConfig(false)
* .withLogger(logger)
*
* Build.build(config, outpath)
* Build.build(config)
* }}}
*
* @param config
* The configuration of the toolchain.
* @param outpath
* The path to the resulting native binary.
* @return
* `outpath`, the path to the resulting native binary.
*/
def build(config: Config, outpath: Path)(implicit
scope: Scope
): Path =
def build(config: Config)(implicit scope: Scope): Path =
config.logger.time("Total") {
// create workdir if needed
if (Files.notExists(config.workdir)) {
Files.createDirectories(config.workdir)
}
// validate classpath
val fconfig = {
val fclasspath = NativeLib.filterClasspath(config.classPath)
Expand Down Expand Up @@ -111,7 +113,7 @@ object Build {
if (config.compilerConfig.useIncrementalCompilation) {
incCompilationContext.clear()
}
LLVM.link(fconfig, linked, objectPaths, outpath)
LLVM.link(fconfig, linked, objectPaths)
}

def findAndCompileNativeSources(
Expand Down
Loading