diff --git a/.gitignore b/.gitignore index e1327be2..4bba564b 100644 --- a/.gitignore +++ b/.gitignore @@ -101,6 +101,12 @@ fabric.properties *.tar.gz *.rar +# local build output +/build/ + +# local JDK installs (bootstrapped) +/.jdk/ + # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..e00fee3d --- /dev/null +++ b/Makefile @@ -0,0 +1,111 @@ +SHELL := bash + +SRC_DIR ?= client/src +BUILD_DIR ?= build +CLASSES_DIR ?= $(BUILD_DIR)/classes +SOURCES_FILE ?= $(BUILD_DIR)/sources.txt + +LIBS ?= libs/clientlibs.jar +MAIN_CLASS ?= Loader +OUT_JAR ?= $(BUILD_DIR)/void-client.jar +CLASSES_STAMP ?= $(CLASSES_DIR)/.compiled.stamp +JAVA_ARGS ?= + +# Requested JDK major version. Used to validate JAVA_HOME and auto-select a bootstrapped JDK under ./.jdk/. +JDK ?= 8 +BOOTSTRAP_JAVA_HOME ?= $(CURDIR)/.jdk/temurin$(JDK) + +# If JAVA_HOME isn't set (or doesn't match JDK), fall back to a repo-local bootstrapped JDK if present. +JAVA_HOME_BIN_JAVA := $(JAVA_HOME)/bin/java +JAVA_HOME_BIN_JAVAC := $(JAVA_HOME)/bin/javac + +ifdef JAVA_HOME + ifeq ($(wildcard $(JAVA_HOME_BIN_JAVA)),) + ifneq ($(wildcard $(BOOTSTRAP_JAVA_HOME)/bin/java),) + $(warning JAVA_HOME is set but invalid ($(JAVA_HOME_BIN_JAVA) missing); using $(BOOTSTRAP_JAVA_HOME)) + JAVA_HOME := $(BOOTSTRAP_JAVA_HOME) + else + $(warning JAVA_HOME is set but invalid ($(JAVA_HOME_BIN_JAVA) missing); falling back to PATH) + endif + else + JAVA_HOME_MAJOR := $(shell "$(JAVA_HOME_BIN_JAVA)" -version 2>&1 | sed -n '1{s/.*version \"1\.\([0-9][0-9]*\).*/\1/p; s/.*version \"\([0-9][0-9]*\).*/\1/p;}') + ifneq ($(JAVA_HOME_MAJOR),$(JDK)) + ifneq ($(wildcard $(BOOTSTRAP_JAVA_HOME)/bin/java),) + $(warning JAVA_HOME is Java $(JAVA_HOME_MAJOR) but JDK=$(JDK); using $(BOOTSTRAP_JAVA_HOME)) + JAVA_HOME := $(BOOTSTRAP_JAVA_HOME) + else + $(warning JAVA_HOME is Java $(JAVA_HOME_MAJOR) but JDK=$(JDK); continuing with JAVA_HOME) + endif + endif + endif +else + ifneq ($(wildcard $(BOOTSTRAP_JAVA_HOME)/bin/java),) + JAVA_HOME := $(BOOTSTRAP_JAVA_HOME) + endif +endif + +ifdef JAVA_HOME +JAVA := $(JAVA_HOME)/bin/java +JAVAC := $(JAVA_HOME)/bin/javac +JAR := $(JAVA_HOME)/bin/jar +else +JAVA ?= java +JAVAC ?= javac +JAR ?= jar +endif + +.PHONY: help bootstrap sources compile jar run clean + +help: + @echo "Targets:" + @echo " make bootstrap - download repo-local JDK (./.jdk/temurin\$$JDK)" + @echo " make sources - write $(SOURCES_FILE)" + @echo " make compile - compile $(SRC_DIR) into $(CLASSES_DIR)" + @echo " make jar - build runnable jar at $(OUT_JAR) (Main-Class: $(MAIN_CLASS))" + @echo " make run - run $(MAIN_CLASS) using $(OUT_JAR) + $(LIBS)" + @echo " make clean - remove $(BUILD_DIR)" + @echo "" + @echo "Vars:" + @echo " JDK=8 (requested major version; default 8)" + @echo " JAVA_HOME=/path/to/jdk (used if compatible with JDK; otherwise ./.jdk/temurin\$$JDK is preferred)" + @echo " LIBS=libs/clientlibs.jar (classpath deps)" + @echo "" + @echo "Tip:" + @echo " tools/bootstrap-jdk.sh \$$JDK (downloads a repo-local JDK into .jdk/)" + +bootstrap: + @echo "Bootstrapping Temurin JDK $(JDK) into $(BOOTSTRAP_JAVA_HOME)" + @bash tools/bootstrap-jdk.sh "$(JDK)" + +JAVA_SOURCES := $(wildcard $(SRC_DIR)/*.java) +LIB_JARS := $(subst :, ,$(LIBS)) + +$(BUILD_DIR): + @mkdir -p "$@" + +$(CLASSES_DIR): + @mkdir -p "$@" + +sources: $(BUILD_DIR) + @find "$(SRC_DIR)" -maxdepth 1 -name '*.java' -print | sort > "$(SOURCES_FILE)" + @echo "Wrote $(SOURCES_FILE) ($$(wc -l < "$(SOURCES_FILE)") files)" + +$(CLASSES_STAMP): $(JAVA_SOURCES) $(LIB_JARS) | $(CLASSES_DIR) $(BUILD_DIR) + @echo "Compiling with: $(JAVAC)" + @find "$(SRC_DIR)" -maxdepth 1 -name '*.java' -print | sort > "$(SOURCES_FILE)" + @"$(JAVAC)" -Xlint:none -cp "$(LIBS)" -d "$(CLASSES_DIR)" @"$(SOURCES_FILE)" + @touch "$(CLASSES_STAMP)" + +compile: $(CLASSES_STAMP) + +$(OUT_JAR): $(CLASSES_STAMP) | $(BUILD_DIR) + @echo "Jarring to: $(OUT_JAR)" + @"$(JAR)" cfe "$(OUT_JAR)" "$(MAIN_CLASS)" -C "$(CLASSES_DIR)" . + +jar: $(OUT_JAR) + +run: $(OUT_JAR) + @"$(JAVA)" $(JAVA_ARGS) -cp "$(OUT_JAR):$(LIBS)" "$(MAIN_CLASS)" + +clean: + rm -rf "$(BUILD_DIR)" diff --git a/tools/bootstrap-jdk.sh b/tools/bootstrap-jdk.sh new file mode 100644 index 00000000..ced530cb --- /dev/null +++ b/tools/bootstrap-jdk.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +JDK_MAJOR="${1:-8}" + +case "${JDK_MAJOR}" in + 8|11|17|21) ;; + *) + echo "Usage: tools/bootstrap-jdk.sh {8|11|17|21}" + echo "Downloads an Eclipse Temurin JDK into $ROOT_DIR/.jdk/temurin (no Gradle, no system install)." + exit 2 + ;; +esac + +OS="linux" +ARCH_RAW="$(uname -m)" +case "$ARCH_RAW" in + x86_64|amd64) ARCH="x64" ;; + aarch64|arm64) ARCH="aarch64" ;; + *) + echo "Unsupported arch: $ARCH_RAW" + exit 2 + ;; +esac + +DEST_DIR="$ROOT_DIR/.jdk/temurin${JDK_MAJOR}" +TMP_DIR="${DEST_DIR}.tmp.$$" +ARCHIVE="/tmp/temurin${JDK_MAJOR}-${OS}-${ARCH}-jdk.tar.gz" + +URL="https://api.adoptium.net/v3/binary/latest/${JDK_MAJOR}/ga/${OS}/${ARCH}/jdk/hotspot/normal/eclipse" + +echo "Downloading Temurin JDK ${JDK_MAJOR} for ${OS}/${ARCH}..." +echo " $URL" +curl -fsSL -o "$ARCHIVE" "$URL" + +rm -rf "$TMP_DIR" +mkdir -p "$TMP_DIR" + +echo "Extracting to $DEST_DIR ..." +tar -xzf "$ARCHIVE" -C "$TMP_DIR" --strip-components=1 + +rm -rf "$DEST_DIR" +mv "$TMP_DIR" "$DEST_DIR" + +cat < "$SOURCES_FILE" +if [[ -n "$EXCLUDE_REGEX" ]]; then + grep -Ev "$EXCLUDE_REGEX" "$SOURCES_FILE" > "$SOURCES_FILE.tmp" + mv "$SOURCES_FILE.tmp" "$SOURCES_FILE" +fi + +echo "Sources: $(wc -l < "$SOURCES_FILE") ($SOURCES_FILE)" +echo "JAVAC: $JAVAC_BIN" + +"$JAVAC_BIN" -Xlint:none -cp "$LIBS" -d "$CLASSES_DIR" @"$SOURCES_FILE" + +echo "JAR: $OUT_JAR" +"$JAR_BIN" cfe "$OUT_JAR" "$MAIN_CLASS" -C "$CLASSES_DIR" . + +echo "Done. Run with:" +echo " $JAVA_BIN -cp $OUT_JAR:$LIBS $MAIN_CLASS" + diff --git a/tools/run.sh b/tools/run.sh new file mode 100644 index 00000000..42cf0b82 --- /dev/null +++ b/tools/run.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +BUILD_DIR="${BUILD_DIR:-"$ROOT_DIR/build"}" +LIBS="${LIBS:-"$ROOT_DIR/libs/clientlibs.jar"}" +MAIN_CLASS="${MAIN_CLASS:-Loader}" +OUT_JAR="${OUT_JAR:-"$BUILD_DIR/void-client.jar"}" + +JAVA_BIN="${JAVA_HOME:+$JAVA_HOME/bin/}java" +JAVA_ARGS="${JAVA_ARGS:-}" + +read -r -a JAVA_ARGS_ARR <<<"$JAVA_ARGS" + +if [[ ! -f "$OUT_JAR" ]]; then + echo "Missing $OUT_JAR. Build first with:" + echo " make jar" + echo "or" + echo " tools/build.sh" + exit 1 +fi + +exec "$JAVA_BIN" "${JAVA_ARGS_ARR[@]}" -cp "$OUT_JAR:$LIBS" "$MAIN_CLASS" "$@"