Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .github/workflows/verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,20 @@ jobs:
distribution: 'graalvm'
cache: maven
- run: ./mvnw clean verify
# TODO: check native-image can build ice

native-build:
name: Build and test native image
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'graalvm'
cache: maven
- name: Install musl for static linking
run: sudo apt-get update && sudo apt-get install -y musl-tools
- name: Build native image (amd64 static with musl)
run: ./build-native.sh
env:
ARCH: amd64
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,23 @@ Create/delete tables, insert data with `ice insert -p ns1.table1 file://example.

## Installation

Pre-built binaries\* (+ links to Docker images for [ice](https://hub.docker.com/r/altinity/ice) and [ice-rest-catalog](https://hub.docker.com/r/altinity/ice-rest-catalog)) are available form [GitHub Releases](https://github.com/Altinity/ice/releases) page.
> \* currently require `java` 21+ to run (available [here](https://adoptium.net/installation/)).
Pre-built binaries (+ links to Docker images for [ice](https://hub.docker.com/r/altinity/ice) and [ice-rest-catalog](https://hub.docker.com/r/altinity/ice-rest-catalog)) are available from [GitHub Releases](https://github.com/Altinity/ice/releases) page.

**Two types of binaries are available:**

1. **Java-based binaries** - Require Java 21+ to run (available [here](https://adoptium.net/installation/))
2. **Native binaries** - Standalone executables with no Java dependency
- `ice-native-amd64` - Static binary (musl) for x86_64 Linux (no dependencies)
- `ice-native-arm64` - Dynamic binary for ARM64 Linux (requires glibc)

## Usage

See [examples/](examples/).

## Development

### Standard Build (Java-based)

Install [sdkman](https://sdkman.io/install), then

```shell
Expand All @@ -35,6 +43,26 @@ sdk env
./mvnw
```

### Native Image Build (Standalone)

Build standalone native binaries with no Java dependency:

```shell
# Install prerequisites
sdk env # or ensure Java 21+ and GraalVM are available

# For amd64 (static with musl - no dependencies)
./build-native.sh
# Produces: ice/target/ice (static binary)

# Or use Maven directly
mvn -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true

# For ARM64 (dynamic with glibc)
ARCH=arm64 ./build-native.sh
# Or: mvn -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true


## License

Copyright (c) 2025, Altinity Inc and/or its affiliates. All rights reserved.
Expand Down
95 changes: 95 additions & 0 deletions build-native.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/bin/bash
# Build native images for ice CLI
# Supports: amd64 (static with musl), arm64 (dynamic)

set -e

VERSION="${VERSION:-0.0.0-SNAPSHOT}"
ARCH="${ARCH:-$(uname -m)}"

# Convert architecture names
case "$ARCH" in
x86_64|amd64)
ARCH="amd64"
PROFILE="native-amd64-static"
;;
aarch64|arm64)
ARCH="arm64"
PROFILE="native-arm64"
;;
*)
echo "Unsupported architecture: $ARCH"
echo "Supported: x86_64/amd64, aarch64/arm64"
exit 1
;;
esac

echo "============================================"
echo "Building native ice binary"
echo "Architecture: $ARCH"
echo "Profile: $PROFILE"
echo "Version: $VERSION"
echo "============================================"
echo ""

# Check for musl-gcc on amd64 builds
if [ "$ARCH" = "amd64" ]; then
if ! command -v x86_64-linux-musl-gcc &> /dev/null && ! command -v musl-gcc &> /dev/null; then
echo " WARNING: musl compiler not found!"
echo ""
echo "For static builds on amd64, you need musl-tools installed."
echo ""
echo "Install it with:"
echo " Ubuntu/Debian: sudo apt-get install musl-tools"
echo " Fedora/RHEL: sudo dnf install musl-gcc musl-libc-static"
echo " Alpine: apk add musl-dev gcc"
echo ""
echo "Or build without static linking using the 'native' profile:"
echo " mvn -Pnative -pl ice clean package -Dmaven.test.skip=true"
echo ""
read -p "Continue anyway? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
else
echo "✓ musl compiler found"
fi
fi
echo ""

# Set version
./mvnw -am -pl ice versions:set -DnewVersion=${VERSION}

# Build native image
echo "Building native image..."
./mvnw -Pno-check -P${PROFILE} -pl ice clean package -Dmaven.test.skip=true

echo ""
echo "============================================"
echo "✓ Native binary built successfully!"
echo "============================================"
echo ""
echo "Binary location: ice/target/ice"
echo ""
echo "Test the binary:"
echo " ./ice/target/ice --version"
echo " ./ice/target/ice check"
echo ""

# Show binary info
if [ -f "ice/target/ice" ]; then
ls -lh ice/target/ice
file ice/target/ice || true

if [ "$ARCH" = "amd64" ]; then
echo ""
echo "Static binary (no dependencies):"
ldd ice/target/ice 2>&1 || echo " ✓ Statically linked (expected for amd64)"
else
echo ""
echo "Dynamic binary dependencies:"
ldd ice/target/ice || true
fi
fi

103 changes: 103 additions & 0 deletions ice/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -618,5 +618,108 @@
</plugins>
</build>
</profile>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native.maven.plugin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>build-native</id>
<goals>
<goal>compile-no-fork</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<imageName>ice</imageName>
<mainClass>com.altinity.ice.cli.Main</mainClass>
<buildArgs>
<buildArg>-H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json</buildArg>
<buildArg>--initialize-at-run-time=io.netty.channel.ChannelHandlerMask</buildArg>
<buildArg>-H:+ReportExceptionStackTraces</buildArg>
</buildArgs>

</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>native-amd64-static</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native.maven.plugin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>build-native</id>
<goals>
<goal>compile-no-fork</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<imageName>ice</imageName>
<mainClass>com.altinity.ice.cli.Main</mainClass>
<buildArgs>
<!-- Base configuration -->
<buildArg>-H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json</buildArg>
<buildArg>--initialize-at-run-time=io.netty.channel.ChannelHandlerMask</buildArg>
<!-- Static linking with musl for truly standalone binary (amd64 only) -->
<buildArg>--static</buildArg>
<buildArg>--libc=musl</buildArg>
<!-- Additional optimizations -->
<buildArg>-H:+RemoveUnusedSymbols</buildArg>
<buildArg>-H:+ReportExceptionStackTraces</buildArg>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>native-arm64</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native.maven.plugin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>build-native</id>
<goals>
<goal>compile-no-fork</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<imageName>ice</imageName>
<mainClass>com.altinity.ice.cli.Main</mainClass>
<buildArgs>
<!-- Base configuration -->
<buildArg>-H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json</buildArg>
<buildArg>--initialize-at-run-time=io.netty.channel.ChannelHandlerMask</buildArg>
<!-- ARM64 optimizations (no static musl support yet) -->
<buildArg>-H:+RemoveUnusedSymbols</buildArg>
<buildArg>-H:+ReportExceptionStackTraces</buildArg>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Loading
Loading