diff --git a/README.md b/README.md
index b06f722..1440211 100644
--- a/README.md
+++ b/README.md
@@ -11,4 +11,26 @@ Icom CS software for IC-F300 model is back from 1997, requires DOSbox and not mo
- [ ] Write file to radio (work in developers machine only, will be published soon)
- [x] Raw serial console
-Firmware format reverse engineering progress: https://git.dead.guru/ut3ums/IC-CS-X
\ No newline at end of file
+Firmware format reverse engineering progress: https://git.dead.guru/ut3ums/IC-CS-X
+
+
+
+## Build
+
+Only for JDK 20
+
+1) compiler:compile
+2) dependencies:copy-dependencies
+3) assembly:single
+
+### Linux
+
+1) `./build_linux.sh`
+
+### Windows
+
+TBA
+
+### MacOS
+
+TBA
diff --git a/build_linux.sh b/build_linux.sh
new file mode 100755
index 0000000..32de8d2
--- /dev/null
+++ b/build_linux.sh
@@ -0,0 +1,109 @@
+#!/bin/bash
+
+JAVA_VERSION=20
+MAIN_JAR="icf320-1.0-SNAPSHOT-jar-with-dependencies.jar"
+APP_VERSION=1.0.1
+
+echo "java home: $JAVA_HOME"
+echo "project version: $PROJECT_VERSION"
+echo "app version: $APP_VERSION"
+echo "main JAR file: $MAIN_JAR"
+
+# ------ SETUP DIRECTORIES AND FILES ----------------------------------------
+# Remove previously generated java runtime and installers. Copy all required
+# jar files into the input/libs folder.
+
+rm -rfd ./build/java-runtime/
+rm -rfd build/installer/
+
+mkdir -p build/installer/input/libs/
+
+cp target/lib*/*.jar build/installer/input/libs/
+cp target/${MAIN_JAR} build/installer/input/libs/
+
+# ------ REQUIRED MODULES ---------------------------------------------------
+# Use jlink to detect all modules that are required to run the application.
+# Starting point for the jdep analysis is the set of jars being used by the
+# application.
+
+echo "detecting required modules"
+detected_modules=`$JAVA_HOME/bin/jdeps \
+ --multi-release ${JAVA_VERSION} \
+ --ignore-missing-deps \
+ --print-module-deps \
+ --class-path "build/installer/input/libs/*" \
+ target/classes/guru/dead/icf320/MainApplication.class`
+echo "detected modules: ${detected_modules}"
+
+#/home/assada/IdeaProjects/icf300/src/main/java/guru/dead/icf320/Launcher.java
+# /home/assada/IdeaProjects/icf300/target/classes/guru/dead/icf320/MainApplication.class
+
+# ------ MANUAL MODULES -----------------------------------------------------
+# jdk.crypto.ec has to be added manually bound via --bind-services or
+# otherwise HTTPS does not work.
+#
+# See: https://bugs.openjdk.java.net/browse/JDK-8221674
+#
+# In addition we need jdk.localedata if the application is localized.
+# This can be reduced to the actually needed locales via a jlink paramter,
+# e.g., --include-locales=en,de.
+
+manual_modules=jdk.crypto.ec,jdk.localedata
+echo "manual modules: ${manual_modules}"
+
+# ------ RUNTIME IMAGE ------------------------------------------------------
+# Use the jlink tool to create a runtime image for our application. We are
+# doing this is a separate step instead of letting jlink do the work as part
+# of the jpackage tool. This approach allows for finer configuration and also
+# works with dependencies that are not fully modularized, yet.
+
+echo "creating java runtime image"
+$JAVA_HOME/bin/jlink \
+ --no-header-files \
+ --no-man-pages \
+ --compress=2 \
+ --strip-debug \
+ --add-modules "${detected_modules},${manual_modules}" \
+ --include-locales=en,de \
+ --output build/java-runtime
+
+# ------ PACKAGING ----------------------------------------------------------
+# A loop iterates over the various packaging types supported by jpackage. In
+# the end we will find all packages inside the build/installer directory.
+
+for type in "deb" "rpm"
+do
+ echo "Creating installer of type ... $type"
+
+ $JAVA_HOME/bin/jpackage \
+ --type $type \
+ --dest build/installer \
+ --input build/installer/input/libs \
+ --name icf300 \
+ --main-class guru.dead.icf320.Launcher \
+ --main-jar ${MAIN_JAR} \
+ --java-options -Xmx2048m \
+ --java-options '--enable-preview' \
+ --java-options '-Djdk.gtk.version=2' \
+ --runtime-image build/java-runtime \
+ --linux-shortcut \
+ --linux-menu-group "icf300" \
+ --app-version ${APP_VERSION} \
+ --icon src/main/resources/guru/dead/icf320/icon.png \
+ --vendor "Dead Guru" \
+ --copyright "Copyright © 2023 Dead Guru" \
+ --description "Your friendly JDK distribution updater" \
+
+done
+
+
+# ------ CHECKSUM FILE --------------------------------------------------------
+arch_name="$(uname -m)"
+
+if [ "${arch_name}" = "aarch64" ]; then
+ sha256sum "build/installer/icf300_$APP_VERSION_arm64.deb" > "build/installer/icf300_$APP_VERSION_arm64.deb.sha256"
+ sha256sum "build/installer/icf300-$APP_VERSION.aarch64.rpm" > "build/installer/icf300-$APP_VERSION.aarch64.rpm.sha256"
+else
+ sha256sum "build/installer/icf300_${APP_VERSION}_amd64.deb" > "build/installer/icf300_${APP_VERSION}_amd64.deb.sha256"
+ sha256sum "build/installer/icf300-${APP_VERSION}-1.x86_64.rpm" > "build/installer/icf300-${APP_VERSION}-1.x86_64.rpm.sha256"
+fi
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 43959a8..ab9fd9a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,7 +87,7 @@
- guru.dead.icf320.Main
+ guru.dead.icf320.Launcher
@@ -131,7 +131,7 @@
true
lib/
- guru.dead.icf320.Main
+ guru.dead.icf320.Launcher
@@ -146,7 +146,7 @@
guru.dead
target/dependency
target/dist
- guru.dead.icf320.Main
+ guru.dead.icf320.Launcher
../icf320-1.0-SNAPSHOT-jar-with-dependencies.jar
target/icf320
true
@@ -167,13 +167,15 @@
default-cli
- guru.dead.icf320.Main
+ guru.dead.icf320.Launcher
icf320
icf320
icf320
true
true
+ 2
true
+ -cp ../lib
diff --git a/src/main/java/guru/dead/icf320/Main.java b/src/main/java/guru/dead/icf320/Launcher.java
similarity index 82%
rename from src/main/java/guru/dead/icf320/Main.java
rename to src/main/java/guru/dead/icf320/Launcher.java
index 0ea3be4..6be952b 100644
--- a/src/main/java/guru/dead/icf320/Main.java
+++ b/src/main/java/guru/dead/icf320/Launcher.java
@@ -1,6 +1,6 @@
package guru.dead.icf320;
-public class Main {
+public class Launcher {
public static void main(String[] args) {
MainApplication.main(args);
}