diff --git a/.github/workflows/binary.yml b/.github/workflows/binary.yml new file mode 100644 index 000000000..a228cad1a --- /dev/null +++ b/.github/workflows/binary.yml @@ -0,0 +1,65 @@ +name: "Publish binary aqua" + +on: + workflow_dispatch: + inputs: + runs-on: + type: string + required: true + arch: + type: string + required: true + os: + type: string + required: true + static: + type: boolean + required: true + workflow_call: + inputs: + runs-on: + type: string + required: true + arch: + type: string + required: true + os: + type: string + required: true + static: + type: boolean + required: true + +jobs: + build: + name: "Publish aqua-native" + runs-on: ${{ inputs.runs-on }} + timeout-minutes: 10 + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - uses: graalvm/setup-graalvm@v1 + with: + version: '22.3.1' + java-version: '17' + set-java-home: true + components: 'native-image' + github-token: ${{ secrets.GITHUB_TOKEN }} + + - uses: coursier/cache-action@v6 + + - uses: coursier/setup-action@v1 + with: + apps: sbt + + - name: build + run: sbt "cli/GraalVMNativeImage/packageBin" + env: + COMPILE_STATIC: ${{ inputs.static }} + + - uses: actions/upload-artifact@v3 + with: + name: aqua-${{ inputs.os }}-${{ inputs.arch }} + path: cli/cli/.jvm/target/graalvm-native-image/cli diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 455bcb9f8..cc2151f92 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -224,3 +224,25 @@ jobs: - name: Publish to NPM registry run: npm publish --access public --tag unstable working-directory: language-server/language-server-npm + + aqua-native: + name: "Publish aqua-native" + strategy: + matrix: + runner: + - runs-on: ubuntu-latest + arch: amd64 + os: linux + static: true + - runs-on: macos-latest + arch: amd64 + os: macos + static: false + needs: + - compile + uses: ./.github/workflows/binary.yml + with: + runs-on: ${{ matrix.runner.runs-on }} + arch: ${{ matrix.runner.arch }} + os: ${{ matrix.runner.os }} + static: ${{ matrix.runner.static }} diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 0bdf96b3b..4d6b12088 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -284,3 +284,19 @@ jobs: with: working-directory: language-server/language-server-npm id: ${{ steps.version.outputs.id }} + aqua-native: + strategy: + matrix: + runner: + - runs-on: ubuntu-latest + arch: amd64 + os: linux + static: true + needs: + - compile + uses: ./.github/workflows/binary.yml + with: + runs-on: ${{ matrix.runner.runs-on }} + arch: ${{ matrix.runner.arch }} + os: ${{ matrix.runner.os }} + static: ${{ matrix.runner.static }} diff --git a/build.sbt b/build.sbt index 744a4604a..76bed161b 100644 --- a/build.sbt +++ b/build.sbt @@ -45,8 +45,23 @@ lazy val cli = crossProject(JSPlatform, JVMPlatform) .withoutSuffixFor(JVMPlatform) .crossType(CrossType.Pure) .in(file("cli/cli")) + .enablePlugins(GraalVMNativeImagePlugin) .settings(commons: _*) .settings( + Compile / mainClass := Some("aqua.AquaCli"), + graalVMNativeImageOptions ++= Seq( + "--no-fallback", + "--diagnostics-mode", + "--initialize-at-build-time", + "--initialize-at-run-time=scala.util.Random$", + "-H:-DeleteLocalSymbols", + "-H:+PreserveFramePointer", + "-H:+ReportExceptionStackTraces", + "-H:+DashboardHeap", + "-H:+DashboardCode", + "-H:+DashboardPointsTo", + "-H:+DashboardAll" + ) ++ sys.env.get("COMPILE_STATIC").filter(_.trim.toLowerCase() == "true").map(_ => Seq("--static")).getOrElse(Seq.empty), libraryDependencies ++= Seq( "com.monovore" %%% "decline" % declineV, "com.monovore" %%% "decline-effect" % declineV diff --git a/cli/cli/src/main/resources/META-INF/native-image/jni-config.json b/cli/cli/src/main/resources/META-INF/native-image/jni-config.json new file mode 100644 index 000000000..084aebda1 --- /dev/null +++ b/cli/cli/src/main/resources/META-INF/native-image/jni-config.json @@ -0,0 +1,32 @@ +[ + { + "name":"aqua.AquaCli", + "methods":[{"name":"main","parameterTypes":["java.lang.String[]"] }] + }, + { + "name":"java.lang.Boolean", + "methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }] + }, + { + "name":"java.lang.InternalError", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] + }, + { + "name":"java.lang.String", + "methods":[ + {"name":"lastIndexOf","parameterTypes":["int"] }, + {"name":"substring","parameterTypes":["int"] } + ] + }, + { + "name":"java.lang.System", + "methods":[ + {"name":"getProperty","parameterTypes":["java.lang.String"] }, + {"name":"setProperty","parameterTypes":["java.lang.String","java.lang.String"] } + ] + }, + { + "name":"java.util.Arrays", + "methods":[{"name":"asList","parameterTypes":["java.lang.Object[]"] }] + } +] diff --git a/cli/cli/src/main/resources/META-INF/native-image/proxy-config.json b/cli/cli/src/main/resources/META-INF/native-image/proxy-config.json new file mode 100644 index 000000000..4a9716c16 --- /dev/null +++ b/cli/cli/src/main/resources/META-INF/native-image/proxy-config.json @@ -0,0 +1,5 @@ +[ + { + "interfaces":["sun.misc.SignalHandler"] + } +] diff --git a/cli/cli/src/main/resources/META-INF/native-image/reflect-config.json b/cli/cli/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 000000000..6547e634a --- /dev/null +++ b/cli/cli/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,380 @@ +[ +{ + "name":"aqua.AppOpts$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.AquaCli$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.backend.Version$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.io.Prelude$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.logging.LogLevels$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.model.AquaContext", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.model.AquaContext$Cache", + "fields":[{"name":"0bitmap$2"}] +}, +{ + "name":"aqua.model.ArgsCall", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.model.CallServiceModel", + "fields":[{"name":"0bitmap$14"}] +}, +{ + "name":"aqua.model.DetachModel$", + "fields":[{"name":"0bitmap$4"}] +}, +{ + "name":"aqua.model.EmptyModel$", + "fields":[{"name":"0bitmap$19"}] +}, +{ + "name":"aqua.model.FuncArrow", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.model.OnModel", + "fields":[{"name":"0bitmap$6"}] +}, +{ + "name":"aqua.model.OpModel$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.model.ParModel$", + "fields":[{"name":"0bitmap$3"}] +}, +{ + "name":"aqua.model.SeqModel$", + "fields":[{"name":"0bitmap$2"}] +}, +{ + "name":"aqua.model.VarModel", + "fields":[{"name":"0bitmap$2"}] +}, +{ + "name":"aqua.model.XorModel$", + "fields":[{"name":"0bitmap$5"}] +}, +{ + "name":"aqua.model.inline.state.InliningState$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.model.transform.cursor.ChainCursor", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.model.transform.topology.OpModelTreeCursor", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.model.transform.topology.Topology", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.parser.Expr", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.parser.Expr$$anon$1", + "fields":[{"name":"0bitmap$2"}] +}, +{ + "name":"aqua.parser.Expr$AndIndented", + "fields":[{"name":"0bitmap$3"}] +}, +{ + "name":"aqua.parser.Parser$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.parser.expr.RootExpr$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.parser.lift.Span$Focus", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.raw.RawContext", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.raw.ops.AssignmentTag", + "fields":[{"name":"0bitmap$16"}] +}, +{ + "name":"aqua.raw.ops.CallArrowRawTag", + "fields":[{"name":"0bitmap$14"}] +}, +{ + "name":"aqua.raw.ops.EmptyTag$", + "fields":[{"name":"0bitmap$19"}] +}, +{ + "name":"aqua.raw.ops.OnTag", + "fields":[{"name":"0bitmap$9"}] +}, +{ + "name":"aqua.raw.ops.ParTag$", + "fields":[{"name":"0bitmap$5"}] +}, +{ + "name":"aqua.raw.ops.ParTag$Detach$", + "fields":[{"name":"0bitmap$4"}] +}, +{ + "name":"aqua.raw.ops.RawTag$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.raw.ops.ReturnTag", + "fields":[{"name":"0bitmap$18"}] +}, +{ + "name":"aqua.raw.ops.SeqTag$", + "fields":[{"name":"0bitmap$3"}] +}, +{ + "name":"aqua.raw.ops.XorTag$", + "fields":[{"name":"0bitmap$7"}] +}, +{ + "name":"aqua.raw.ops.XorTag$LeftBiased$", + "fields":[{"name":"0bitmap$6"}] +}, +{ + "name":"aqua.res.CallServiceRes", + "fields":[{"name":"0bitmap$9"}] +}, +{ + "name":"aqua.res.ParRes$", + "fields":[{"name":"0bitmap$3"}] +}, +{ + "name":"aqua.res.SeqRes$", + "fields":[{"name":"0bitmap$2"}] +}, +{ + "name":"aqua.res.XorRes$", + "fields":[{"name":"0bitmap$4"}] +}, +{ + "name":"aqua.semantics.CompilerState", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.types.ArrowType", + "fields":[{"name":"0bitmap$4"}] +}, +{ + "name":"aqua.types.LabeledConsType", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"aqua.types.NilType$", + "fields":[{"name":"0bitmap$3"}] +}, +{ + "name":"aqua.types.Type$", + "fields":[{"name":"0bitmap$5"}] +}, +{ + "name":"aqua.types.UnlabeledConsType", + "fields":[{"name":"0bitmap$2"}] +}, +{ + "name":"cats.Later", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"cats.effect.unsafe.IORuntimeCompanionPlatform", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"cats.effect.unsafe.metrics.ComputePoolSampler", + "queryAllPublicConstructors":true +}, +{ + "name":"cats.effect.unsafe.metrics.LiveFiberSnapshotTrigger", + "queryAllPublicConstructors":true +}, +{ + "name":"cats.effect.unsafe.metrics.LocalQueueSampler", + "queryAllPublicConstructors":true +}, +{ + "name":"cats.parse.Parser$State", + "fields":[{"name":"0bitmap$2"}] +}, +{ + "name":"cats.parse.Parser0", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"fs2.Chunk$", + "fields":[{"name":"0bitmap$2"}] +}, +{ + "name":"fs2.Chunk$Queue", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"fs2.internal.ScopedResource$$anon$1", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"fs2.io.file.Files$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"fs2.io.file.Path$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"io.circe.Encoder$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"java.lang.Boolean", + "fields":[{"name":"TYPE"}] +}, +{ + "name":"java.lang.Byte", + "fields":[{"name":"TYPE"}] +}, +{ + "name":"java.lang.Character", + "fields":[{"name":"TYPE"}] +}, +{ + "name":"java.lang.ClassValue" +}, +{ + "name":"java.lang.Deprecated", + "queryAllPublicMethods":true +}, +{ + "name":"java.lang.Double", + "fields":[{"name":"TYPE"}] +}, +{ + "name":"java.lang.Float", + "fields":[{"name":"TYPE"}] +}, +{ + "name":"java.lang.Integer", + "fields":[{"name":"TYPE"}] +}, +{ + "name":"java.lang.Long", + "fields":[{"name":"TYPE"}] +}, +{ + "name":"java.lang.Short", + "fields":[{"name":"TYPE"}] +}, +{ + "name":"java.lang.StackTraceElement", + "queryAllPublicMethods":true +}, +{ + "name":"java.lang.String" +}, +{ + "name":"java.lang.Void", + "fields":[{"name":"TYPE"}] +}, +{ + "name":"java.lang.invoke.VarHandle", + "methods":[{"name":"releaseFence","parameterTypes":[] }] +}, +{ + "name":"java.math.BigDecimal" +}, +{ + "name":"java.math.BigInteger" +}, +{ + "name":"java.util.Date" +}, +{ + "name":"java.util.PropertyPermission", + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "name":"scodec.bits.ByteVector", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"scribe.Logger", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"scribe.Logger$", + "fields":[{"name":"0bitmap$2"}] +}, +{ + "name":"scribe.Platform$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"scribe.Priority$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"scribe.format.FormatBlock$Date$Standard$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"scribe.format.Formatter$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"scribe.format.package$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"scribe.message.LazyMessage", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"scribe.modify.LevelFilter$", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"scribe.output.Color$Cyan$", + "fields":[{"name":"0bitmap$7"}] +}, +{ + "name":"scribe.output.Color$Green$", + "fields":[{"name":"0bitmap$8"}] +}, +{ + "name":"scribe.record.SimpleLogRecord", + "fields":[{"name":"0bitmap$1"}] +}, +{ + "name":"sun.misc.SignalHandler" +}, +{ + "name":"sun.misc.Unsafe", + "allDeclaredFields":true +} +] diff --git a/project/plugins.sbt b/project/plugins.sbt index 532de444a..8c8c32a50 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,3 +2,4 @@ addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.1") addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.13.0") addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0") +addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.16")