All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.scalanative.cli.ScalaNativeLd.scala Maven / Gradle / Ivy

The newest version!
package scala.scalanative.cli

import java.nio.file._
import scala.scalanative.build._
import scala.scalanative.util.Scope
import scala.scalanative.cli.utils.ConfigConverter
import scala.scalanative.cli.options._
import scala.concurrent._
import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext.Implicits.global

object ScalaNativeLd {

  def main(args: Array[String]): Unit = {
    val parser = new scopt.OptionParser[LinkerOptions]("scala-native-ld") {
      override def errorOnUnknownArgument = false
      head("scala-native-ld", BuildInfo.nativeVersion)
      arg[String]("classpath")
        .hidden()
        .optional()
        .unbounded()
        .action((x, c) => c.copy(classpath = c.classpath :+ x))

      ConfigOptions.set(this)
      NativeConfigOptions.set(this)
      OptimizerConfigOptions.set(this)
      SemanticsConfigOptions.set(this)
      SourceLevelDebuggingConfigOptions.set(this)

      note("Logger options:")
      opt[Unit]("verbose")
        .abbr("v")
        .optional()
        .unbounded()
        .action((x, c) => c.copy(verbose = c.verbose + 1))
        .text(
          "Increase verbosity of internal logger. Can be specified multiple times."
        )

      note("Help options:")
      help('h', "help")
        .text("Print this usage text and exit.")
      version("version")
        .text("Print scala-native-cli version and exit.")
    }
    parser.parse(args, LinkerOptions()) match {
      case Some(config) =>
        runLd(config)
        sys.exit(0)
      case _ =>
        // arguments are of bad format, scopt will have displayed errors automatically
        sys.exit(1)
    }
  }

  def runLd(options: LinkerOptions) = {
    val needsMain = options.nativeConfig.buildTarget match {
      case BuildTarget.Application => true
      case _: BuildTarget.Library  => false
    }
    if (needsMain && options.config.main.isEmpty) {
      System.err.println("Required option not specified: --main")
      sys.exit(1)
    } else {
      val (ignoredArgs, classpath) =
        options.classpath.partition(_.startsWith("-"))
      ignoredArgs.foreach { arg =>
        System.err.println(s"Unrecognised argument: ${arg}")
      }
      val main = options.config.main
      val buildOptionsMaybe = ConfigConverter.convert(options, main, classpath)

      buildOptionsMaybe match {
        case Left(thrown) =>
          System.err.println(thrown.getMessage())
          sys.exit(1)
        case Right(buildOptions) =>
          val build = Scope { implicit scope =>
            Build
              .build(buildOptions.config)
              .map { outputFile =>
                options.config.outpath.map(Paths.get(_)).foreach { outpath =>
                  Files.copy(
                    outputFile,
                    outpath,
                    StandardCopyOption.REPLACE_EXISTING,
                    StandardCopyOption.COPY_ATTRIBUTES
                  )
                }
              }
          }
          Await.result(build, Duration.Inf)

      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy