Skip to content

Commit

Permalink
Setup cross platform builds of the CLI
Browse files Browse the repository at this point in the history
This commit adds support for cross platform builds of the CLI using
jlink via each support version of JDK 16 of Amazon Corretto (we'll bump
to JDK 17 when it's available). Each supported build target is built by
downloading the appropriate JDK from Corretto and running jlink.

The Dockerfile has been updated to now use the prebuilt binary for
linux-x86_64, and will now use application class data sharing to improve
CLI startup time in the Docker container.

A couple dependencies were updated, including Gradle, in order to build
on JDK 16. JDK 16 also complained about creating an explicitly boxed
value, so that was addressed too.

Future work should include building signed tar.gz and zip files, creating a
Mac pkg file via jpackage, and creating an msi via jpackage.
  • Loading branch information
mtdowling committed Jun 14, 2021
1 parent 0a3b325 commit 8548dc7
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 17 deletions.
15 changes: 9 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
FROM gradle:5.4.1-jdk12
USER root
ADD ./ /smithy
FROM amazonlinux:2
ADD smithy-cli/build/image/smithy-cli-linux-x86_64 /smithy
WORKDIR /smithy
RUN gradle :smithy-cli:runtime
WORKDIR /work

ENTRYPOINT [ "/smithy/smithy-cli/build/image/bin/smithy" ]
# Build application class data sharing archive using smithy validate as the baseline.
RUN SMITHY_OPTS="-XX:DumpLoadedClassList=/smithy/lib/smithy.lst" \
/smithy/bin/smithy validate
RUN SMITHY_OPTS="-Xshare:dump -XX:SharedArchiveFile=/smithy/lib/smithy.jsa -XX:SharedClassListFile=/smithy/lib/smithy.lst" \
/smithy/bin/smithy validate

ENTRYPOINT [ "/smithy/bin/smithy" ]
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ plugins {
id "signing"
id "checkstyle"
id "jacoco"
id "com.github.spotbugs" version "4.6.0"
id "com.github.spotbugs" version "4.6.1"
id "io.codearte.nexus-staging" version "0.21.0"
id "me.champeau.jmh" version "0.6.4"
}
Expand Down
6 changes: 4 additions & 2 deletions docs/source/implementations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ Build tooling

.. code-block:: none
cd smithy-cli/build/runtime/bin
./smithy-cli --help
smithy-cli/build/image/smithy-cli-osx-x86_64/bin/smithy --help
smithy-cli/build/image/smithy-cli-win64/bin/smithy --help
smithy-cli/build/image/smithy-cli-linux-x86_64/bin/smithy --help
smithy-cli/build/image/smithy-cli-linux-aarch_64/bin/smithy --help
---------------
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
71 changes: 65 additions & 6 deletions smithy-cli/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,40 @@
* permissions and limitations under the License.
*/

import org.apache.tools.ant.taskdefs.condition.Os

plugins {
id "application"
id "org.beryx.runtime" version "1.8.4"
id "org.beryx.runtime" version "1.12.5"
}

description = "This module implements the Smithy command line interface."

ext {
displayName = "Smithy :: CLI"
moduleName = "software.amazon.smithy.cli"
imageJreVersion = "16"
correttoRoot = "https://corretto.aws/downloads/latest/amazon-corretto-${imageJreVersion}"
}

// Detect which OS and arch is running to create an application class data sharing
// archive for the current platform.
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
ext.set("imageOs", "win64")
} else if (Os.isFamily(Os.FAMILY_MAC)) {
ext.set("imageOs", "osx-x86_64")
} else if (Os.isFamily(Os.FAMILY_UNIX)) {
if (Os.isArch("aarch")) {
ext.set("imageOs", "linux-aarch_64")
} else if (Os.isArch("x86_64")) {
ext.set("imageOs", "linux-x86_64")
} else {
println("No JDK for ${System.getProperty("os.arch")}")
ext.set("imageOs", "")
}
} else {
println("Unknown OS and arch: ${System.getProperty("os.name")}")
ext.set("imageOs", "")
}

dependencies {
Expand All @@ -35,16 +59,51 @@ dependencies {
application {
mainClass = "software.amazon.smithy.cli.SmithyCli"
applicationName = "smithy"
applicationDefaultJvmArgs = ["-Xshare:auto"]
}

runtime {
addOptions("--compress", "0", "--strip-debug", "--no-header-files", "--no-man-pages")
addModules("java.logging")
addModules("java.logging", "java.xml")

launcher {
jvmArgs = [
'-Xshare:auto',
'-XX:SharedArchiveFile={{BIN_DIR}}/../lib/smithy.jsa'
]
}

targetPlatform("linux-x86_64") {
jdkHome = jdkDownload("${correttoRoot}-x64-linux-jdk.tar.gz")
}

targetPlatform("linux-aarch_64") {
jdkHome = jdkDownload("${correttoRoot}-aarch64-linux-jdk.tar.gz")
}

targetPlatform("osx-x86_64") {
jdkHome = jdkDownload("${correttoRoot}-x64-macos-jdk.tar.gz")
}

targetPlatform("win64") {
jdkHome = jdkDownload("${correttoRoot}-x64-windows-jdk.zip")
}
}

tasks.register("optimizeCli", Exec) {
commandLine("${project.buildDir}/image/bin/java", "-Xshare:dump")
// First, call validate with no args and create a class list to use use application class data sharing.
tasks.register("createClassList", Exec) {
environment("SMITHY_OPTS", "-XX:DumpLoadedClassList=${project.buildDir}/image/smithy-cli-${imageOs}/lib/smithy.lst")
commandLine("${project.buildDir}/image/smithy-cli-${imageOs}/bin/smithy", "validate")
}

tasks["runtime"].finalizedBy("optimizeCli")
// Next, actually dump out the archive of the collected classes. This is platform specific,
// so it can only be done for the current OS+architecture.
tasks.register("dumpArchive", Exec) {
environment("SMITHY_OPTS", "-Xshare:dump -XX:SharedArchiveFile=${project.buildDir}/image/smithy-cli-${imageOs}/lib/smithy.jsa -XX:SharedClassListFile=${project.buildDir}/image/smithy-cli-${imageOs}/lib/smithy.lst")
commandLine("${project.buildDir}/image/smithy-cli-${imageOs}/bin/smithy", "validate")
}

// Can't do CDS if the OS and architecture is not one of our targets.
if (!imageOs.isEmpty()) {
tasks["dumpArchive"].dependsOn("createClassList")
tasks["runtime"].finalizedBy("dumpArchive")
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void getsAsBoolean() {

@Test
public void getsAsBoxedBoolean() {
LiteralExpression node = new LiteralExpression(new Boolean(true));
LiteralExpression node = new LiteralExpression(true);

node.expectBooleanValue();
assertThat(node.isBooleanValue(), is(true));
Expand Down

0 comments on commit 8548dc7

Please sign in to comment.