Skip to content

Commit

Permalink
Generate native binary
Browse files Browse the repository at this point in the history
Use GraalVM's `native-image` feature to generate a executable.
Run `./mvnw package -Dnative -DskipTests` in order to generate an
executable under `org.eclipse.lemminx/target`.

Also includes two CI/CD strategies for the native image:
 * Jenkinsfile
 * Github Action

Adopted from [PR 673](#673)
A part of #314.

Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed Nov 30, 2020
1 parent 3bf5229 commit a9c781b
Show file tree
Hide file tree
Showing 11 changed files with 1,907 additions and 8 deletions.
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = false
indent_size = 2
indent_style = space

[*.jenkins]
indent_size = 2
indent_style = space

[*.java]
indent_style = tab
indent_size = 4
42 changes: 42 additions & 0 deletions .github/workflows/native-image.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: native-image
on: [push, pull_request]
jobs:
build-binary-unix:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: [macos-latest, ubuntu-latest]
include:
- os: macos-latest
label: 'darwin'
- os: ubuntu-latest
label: 'linux'
steps:
- uses: actions/checkout@v2
- uses: DeLaGuardo/setup-graalvm@8bbfe44ef9c6f5c07e5af036a1bffd561c037d18
with:
graalvm-version: '20.2.0.java8'
- run: ./mvnw package -Dnative -DskipTests -Dcbi.jarsigner.skip=true
- run: mv org.eclipse.lemminx/target/lemminx-* lemminx-$(git rev-parse --short "$GITHUB_SHA")-${{ matrix.label }}
- uses: actions/upload-artifact@v2
with:
name: lemminx-${{ matrix.label }}
path: lemminx-*-${{ matrix.label }}
if-no-files-found: error
build-binary-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: ilammy/[email protected]
- uses: DeLaGuardo/setup-graalvm@8bbfe44ef9c6f5c07e5af036a1bffd561c037d18
with:
graalvm-version: '20.2.0.java11'
- run: Invoke-Expression -Command "$Env:JAVA_HOME/bin/gu install native-image"
- run: .\mvnw.cmd package -Dnative -DskipTests -D cbi.jarsigner.skip=true
- run: mv org.eclipse.lemminx\target\lemminx-*.exe lemminx-$(git rev-parse --short "$Env:GITHUB_SHA")-win32.exe
- uses: actions/upload-artifact@v2
with:
name: lemminx-win32
path: lemminx-*-win32.exe
if-no-files-found: error
10 changes: 5 additions & 5 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ pipeline{
}
stages{
stage("Maven Build"){
steps {
withMaven {
sh './mvnw clean verify -B -Pci,generate-p2 -Dcbi.jarsigner.skip=false'
}
steps {
withMaven {
sh './mvnw clean verify -B -Pci,generate-p2 -Dcbi.jarsigner.skip=false'
}
}
}
stage('Deploy to downloads.eclipse.org') {
when {
Expand Down Expand Up @@ -42,4 +42,4 @@ pipeline{
}
}
}
}
}
58 changes: 58 additions & 0 deletions NativeImage.jenkins
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
pipeline {
/* Uses https://plugins.jenkins.io/pipeline-utility-steps/ */
agent none
stages {
stage("native-image") {
parallel {
stage("Linux native-image") {
agent {
docker "oracle/graalvm-ce:latest"
}
environment {
MAVEN_HOME = "$WORKSPACE/.m2/"
MAVEN_USER_HOME = "$MAVEN_HOME"
}
steps {
sh "rm lemminx-linux.zip lemminx-linux-hash"
sh "./mvnw clean package -Dnative -DskipTests"
sh "sha256sum org.eclipse.lemminx/target/lemminx-linux* > lemminx-linux-hash"
archiveArtifacts artifacts: 'lemminx-linux-hash', fingerprint: false
zip zipFile: 'lemminx-linux.zip', glob: 'lemminx-linux*', archive: true, dir: 'org.eclipse.lemminx/target'
}
}
stage("Windows native-image") {
agent {
label "win10"
}
steps {
powershell "Remove-Item lemminx-windows.zip"
powershell "Remove-Item lemminx-windows-hash"
powershell "Invoke-WebRequest https:/graalvm/graalvm-ce-builds/releases/download/vm-20.2.0/graalvm-ce-java11-windows-amd64-20.2.0.zip -OutFile graalvm-windows.zip"
powershell "Expand-Archive graalvm-windows.zip"
powershell ".\\graalvm-windows\\graalvm-ce-java11-20.2.0\\bin\\gu install native-image"
bat "set JAVA_HOME=%WORKSPACE%\\graalvm-windows\\graalvm-ce-java11-20.2.0&& echo %JAVA_HOME% && \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat\" && .\\mvnw.cmd clean package -Dnative -DskipTests"
powershell "Get-FileHash org.eclipse.lemminx\\target\\*.exe | Select -ExpandProperty Hash > lemminx-windows-hash"
archiveArtifacts artifacts: 'lemminx-windows-hash', fingerprint: false
zip zipFile: 'lemminx-windows.zip', glob: 'lemminx-windows*.exe', archive: true, dir: 'org.eclipse.lemminx/target'
}
}
stage("macOS native-image") {
agent {
label "mac"
}
steps {
sh "rm lemminx-darwin.zip lemminx-darwin-hash"
sh "curl https:/graalvm/graalvm-ce-builds/releases/download/vm-20.2.0/graalvm-ce-java8-darwin-amd64-20.2.0.tar.gz --output graalvm-darwin.tar.gz"
sh "tar -xzf graalvm-darwin.tar.gz"
sh "./graalvm-darwin/graalvm-ce-java8-20.2.0/bin/gu install native-image"
sh "JAVA_HOME=./graalvm-darwin/graalvm-ce-java8-20.2.0 ./mvnw clean package -Dnative -DskipTests"
sh "sha256sum org.eclipse.lemminx/target/lemminx-darwin* > lemminx-darwin-hash"
archiveArtifacts artifacts: 'lemminx-darwin-hash', fingerprint: false
zip zipFile: 'lemminx-darwin.zip', glob: 'lemminx-darwin*', archive: true, dir: 'org.eclipse.lemminx/target'
}
}
}
}
}
}

32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,34 @@ this.forward(clientConnection, serverConnection)
socket.connect(socketPort)
```

Generating a native binary (WIP):
---------------------------------
To generate a native binary:
- [Install GraalVM 20.2.0](https://www.graalvm.org/docs/getting-started/#install-graalvm)
- In a terminal, run `gu install native-image`
- Execute a Maven build activating the `native` profile: `./mvnw clean package -Pnative -DskipTests`
- It will generate a native binary in `org.eclipse.lemminx/target/lemminx-{os.name}-{version}`

OS specific instructions:
- __Fedora__:
- Make sure that you have installed the static versions of the C++ standard library
- __Windows__:
- When installing native-image, please note that `gu` is an existing alias in PowerShell.
Remove the alias with `Remote-Item alias:gu -Force`, refer to `gu` with the absolute path, or use `gu` under `cmd.exe`.
- Make sure to run the Maven wrapper in the "Native Tools Command Prompt".
This command prompt can be obtained through installing the Windows SDK or Visual Studio, as
mentioned in the [GraalVM installation instructions](https://www.graalvm.org/docs/getting-started-with-graalvm/windows/).

`native-image` Development Instructions:
- Reflection:
- If you need to use reflection to access a private field/method, simply register the field/methods that you access in `reflect-config.json`
- If you need to parse some JSON using Gson, make sure to register the fields and methods of the class that you are parsing into in `reflect-config.json`
- Recursively, for all classes that it has, including `enum`s
- Settings are all deserialized, so whenever a setting is added, this must be done and tested
- Manually test the binary and check the logs for reflection errors/NPEs
- Snippets:
- If you are creating a new snippet file, make sure to register it under `org.eclipse.lemminx/src/main/resources/META-INF/resource-config.json`

Maven coordinates:
------------------

Expand Down Expand Up @@ -119,8 +147,8 @@ Here are some clients consuming this XML Language Server:
* [Spring Tools 4](https:/spring-projects/sts4) - re-using the XML parser for Spring-specific analysis and content-assist
* Vim/Neovim with [coc-xml](https:/fannheyward/coc-xml)
* Emacs with [lsp-mode](https:/emacs-lsp/lsp-mode)


Extensions
----------

Expand Down
100 changes: 99 additions & 1 deletion org.eclipse.lemminx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<maven.build.timestamp.format>yyyyMMdd-HHmm</maven.build.timestamp.format>
<dev.build.timestamp>${maven.build.timestamp}</dev.build.timestamp>
<cbi.jarsigner.skip>true</cbi.jarsigner.skip>
<graalvm.version>20.2.0</graalvm.version>
</properties>
<build>
<resources>
Expand Down Expand Up @@ -126,6 +127,104 @@
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.1</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>detect</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>native-image-maven-plugin</artifactId>
<version>${graalvm.version}</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<skip>false</skip>
<imageName>lemminx-${os.detected.classifier}-${project.version}</imageName>
<buildArgs>
--no-fallback
-H:EnableURLProtocols=https,http
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>staticNative</id>
<activation>
<property>
<name>native</name>
<value>true</value>
</property>
<os>
<name>Linux</name>
</os>
</activation>
<build>
<plugins>
<plugin>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.1</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>detect</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>native-image-maven-plugin</artifactId>
<version>${graalvm.version}</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<skip>false</skip>
<imageName>lemminx-${os.detected.classifier}-${project.version}</imageName>
<buildArgs>
--no-fallback
--static
-H:EnableURLProtocols=https,http
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>generate-p2</id>
<build>
Expand Down Expand Up @@ -217,5 +316,4 @@
<scope>test</scope>
</dependency>
</dependencies>

</project>
4 changes: 4 additions & 0 deletions org.eclipse.lemminx/src/main/resources/META-INF/extra.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name":"org.eclipse.lemminx.services.extensions.IXMLExtension",
"allDeclaredMethods":true
},
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
["org.eclipse.lemminx.customservice.XMLLanguageClientAPI","org.eclipse.lsp4j.jsonrpc.Endpoint"]
]
Loading

0 comments on commit a9c781b

Please sign in to comment.