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.
To test, install GraalVM and the native-image tool, then set JAVA_HOME
to the GraalVM installation.
Run `./mvnw package -Dnative -DskipTests` in order to generate an
executable under `org.eclipse.lemminx/target`.

Includes a GitHub Action in order to run builds of the binary on PRs for
testing purposes.

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

Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed Dec 10, 2020
1 parent 3bf5229 commit a8c54a2
Show file tree
Hide file tree
Showing 9 changed files with 1,785 additions and 8 deletions.
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 $([ $(uname -s) = Linux ] && echo "-Dgraalvm.static=--static") -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{
}
}
}
}
}
33 changes: 31 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,35 @@ this.forward(clientConnection, serverConnection)
socket.connect(socketPort)
```

Generating a native binary:
---------------------------------
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 that sets the flag `native`: `./mvnw clean package -Dnative -DskipTests`
- On Linux, compile with `./mvnw clean package -Dnative -DskipTests -Dgraalvm.static=--static`
in order to support distributions that don't use `glibc`, such as Alpine Linux
- It will generate a native binary in `org.eclipse.lemminx/target/lemminx-{os.name}-{architecture}-{version}`

OS specific instructions:
- __Linux__:
- Make sure that you have installed the static versions of the C++ standard library
- For instance, on Fedora Linux, install `glibc-static`, `libstdc++-static`, and `zlib-static`
- __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`
- This needs to be done recursively, for all classes that it has member variables of, including `enum`s
- Settings are all deserialized, so whenever a setting is added, make sure to register the classes
- Manually test the binary and check the logs for reflection errors/NPEs

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

Expand Down Expand Up @@ -119,8 +148,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
51 changes: 50 additions & 1 deletion org.eclipse.lemminx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<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>
<graalvm.static></graalvm.static>
</properties>
<build>
<resources>
Expand Down Expand Up @@ -126,6 +128,54 @@
</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
${graalvm.static}
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>generate-p2</id>
<build>
Expand Down Expand Up @@ -217,5 +267,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 a8c54a2

Please sign in to comment.