|
| 1 | +NAME = http-server |
| 2 | +VERSION = 1.0-SNAPSHOT |
| 3 | +MODULE_ID = http.server |
1 | 4 |
|
2 |
| -BUILD_DIR=build |
3 |
| -CLASSES_DIR=$(BUILD_DIR)/classes/main |
4 |
| -JMODS_DIR=$(BUILD_DIR)/jmods |
5 |
| -DOCKER_DIR=$(BUILD_DIR)/docker |
6 |
| -JRE_DIR=$(BUILD_DIR)/jre |
| 5 | +MAIN_CLASS = fi.linuxbox.http.Main |
7 | 6 |
|
8 |
| -SRC_DIR=src |
9 |
| -JAVA_SRC_DIR=$(SRC_DIR)/main/java |
| 7 | +OTHER_CLASSES = module-info |
10 | 8 |
|
11 |
| -ALPINE_JMODS=/Users/vmj/linux/alpine/jdk-9/jmods |
12 |
| -LINUX_JMODS=/usr/lib/jvm/java-9-openjdk-amd64/jmods |
13 |
| -MACOS_JMODS=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/jmods |
| 9 | +DOCKER_TAG = vmj0/http-server-$(TARGET):$(VERSION) |
14 | 10 |
|
15 |
| -assemble: $(JMODS_DIR)/http-server-1.0-SNAPSHOT.jar |
| 11 | +# |
| 12 | +# Use TARGET env var to switch custom runtime target. |
| 13 | +# Possible targets are native (default), alpine, and linux. |
| 14 | +# |
| 15 | +# E.g. make dockerImage TARGET=alpine |
| 16 | +# |
| 17 | +TARGET ?= native |
16 | 18 |
|
17 |
| -$(JMODS_DIR)/http-server-1.0-SNAPSHOT.jar: $(CLASSES_DIR)/module-info.class $(CLASSES_DIR)/fi/linuxbox/http/Main.class |
18 |
| - rm -rf $(JMODS_DIR) |
19 |
| - mkdir -p $(JMODS_DIR) |
20 |
| - jar --create --file $(JMODS_DIR)/http-server-1.0-SNAPSHOT.jar --main-class fi.linuxbox.http.Main -C $(CLASSES_DIR) . |
| 19 | +# |
| 20 | +# Download and extract the target JDKs, |
| 21 | +# then export following env vars with the correct directories. |
| 22 | +# |
| 23 | +NATIVE_JMODS ?= /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/jmods |
| 24 | +ALPINE_JMODS ?= /Users/vmj/jdks/x64-musl/jdk-9/jmods |
| 25 | +LINUX_JMODS ?= /Users/vmj/jdks/x64-linux/jdk-9/jmods |
21 | 26 |
|
22 |
| -$(CLASSES_DIR)/module-info.class: $(JAVA_SRC_DIR)/module-info.java |
23 |
| - mkdir -p $(BUILD_DIR) |
24 |
| - javac -d $(CLASSES_DIR) $(JAVA_SRC_DIR)/module-info.java $(JAVA_SRC_DIR)/fi/linuxbox/http/Main.java |
| 27 | +ifeq ($(TARGET),native) |
| 28 | +# |
| 29 | +# This is for building a custom runtime and running it directly |
| 30 | +# (not in Docker). |
| 31 | +# |
| 32 | +TARGET_JMODS ?= $(NATIVE_JMODS) |
25 | 33 |
|
26 |
| -$(CLASSES_DIR)/fi/linuxbox/http/Main.class: $(JAVA_SRC_DIR)/fi/linuxbox/http/Main.java |
27 |
| - mkdir -p $(BUILD_DIR) |
28 |
| - javac -d $(CLASSES_DIR) $(JAVA_SRC_DIR)/module-info.java $(JAVA_SRC_DIR)/fi/linuxbox/http/Main.java |
| 34 | +else |
| 35 | +ifeq ($(TARGET),alpine) |
| 36 | +# |
| 37 | +# This is for building a custom runtime for Alpine Linux and running it |
| 38 | +# in Docker. |
| 39 | +# |
| 40 | +BASE_IMAGE = alpine:3.5 |
| 41 | +TARGET_JMODS ?= $(ALPINE_JMODS) |
29 | 42 |
|
30 |
| -.PHONY=dockerImage |
31 |
| -dockerImage: Dockerfile $(JRE_DIR)/alpine |
32 |
| - rm -rf $(DOCKER_DIR) |
33 |
| - mkdir -p $(DOCKER_DIR) |
34 |
| - cp -a Dockerfile $(JRE_DIR)/alpine $(DOCKER_DIR) |
35 |
| - (cd $(DOCKER_DIR) && docker build --tag vmj0/http-server:java9 .) |
| 43 | +else |
| 44 | +ifeq ($(TARGET),linux) |
| 45 | +# |
| 46 | +# This is for building a custom runtime for pretty much any glibc based |
| 47 | +# Linux distro. E.g. Debian would do, too: debian:stretch-slim |
| 48 | +# |
| 49 | +BASE_IMAGE = vbatts/slackware:14.2 |
| 50 | +TARGET_JMODS ?= $(LINUX_JMODS) |
36 | 51 |
|
| 52 | +else |
| 53 | +$(error Unsupported TARGET: $(TARGET); Use one of 'native', 'alpine', or 'linux') |
| 54 | +endif |
| 55 | +endif |
| 56 | +endif |
37 | 57 |
|
38 |
| -dockerRun: dockerImage |
39 |
| - docker run --rm -it -p9000:9000 vmj0/http-server:java9 |
| 58 | +# |
| 59 | +# Build directories |
| 60 | +# |
| 61 | +BUILD_DIR = build |
| 62 | +CLASSES_DIR = $(BUILD_DIR)/classes/main |
| 63 | +JMODS_DIR = $(BUILD_DIR)/jmods |
| 64 | +DOCKERFILE_DIR = $(BUILD_DIR)/dockerfile |
| 65 | +DOCKER_DIR = $(BUILD_DIR)/docker |
| 66 | +JRE_DIR = $(BUILD_DIR)/jre |
| 67 | + |
| 68 | +# |
| 69 | +# Source directories |
| 70 | +# |
| 71 | +SRC_DIR = src |
| 72 | +JAVA_SRC_DIR = $(SRC_DIR)/main/java |
| 73 | + |
| 74 | +# The output Java module |
| 75 | +ARTIFACT_FILE = $(JMODS_DIR)/$(NAME)-$(VERSION).jar |
| 76 | +# The output custom runtime |
| 77 | +CUSTOM_RUNTIME_DIR = $(JRE_DIR)/$(TARGET) |
| 78 | +# The output Dockerfile |
| 79 | +DOCKERFILE = $(DOCKERFILE_DIR)/$(TARGET) |
| 80 | + |
| 81 | +# Turn the class names to paths |
| 82 | +SRC_FILES = $(subst .,/,$(MAIN_CLASS) $(OTHER_CLASSES)) |
| 83 | + |
| 84 | +# Turn the paths to .class and .java file names (with full path) |
| 85 | +CLASS_FILES = $(patsubst %,$(CLASSES_DIR)/%.class,$(SRC_FILES)) |
| 86 | +JAVA_FILES = $(patsubst %,$(JAVA_SRC_DIR)/%.java,$(SRC_FILES)) |
| 87 | + |
| 88 | +.PHONY: classes classesRun jar jarRun jre jreRun dockerfile dockerImage dockerRun |
| 89 | + |
| 90 | +help: |
| 91 | + @echo USAGE: make action [TARGET=target] |
| 92 | + @echo |
| 93 | + @echo Actions: |
| 94 | + @echo |
| 95 | + @echo " classes " |
| 96 | + @echo " Compiles the Java source files to class files. " |
| 97 | + @echo " classesRun " |
| 98 | + @echo " Runs the application from the class files. " |
| 99 | + @echo " jar " |
| 100 | + @echo " Builds the modular JAR from the class files. " |
| 101 | + @echo " jarRun " |
| 102 | + @echo " Runs the application from the modular JAR. " |
| 103 | + @echo " jre [TARGET=native|alpine|linux] " |
| 104 | + @echo " Builds custom runtime for TARGET. " |
| 105 | + @echo " jreRun [TARGET=native] " |
| 106 | + @echo " Runs the application from the custom runtime. " |
| 107 | + @echo " dockerfile [TARGET=alpine|linux] " |
| 108 | + @echo " Creates the Dockerfile for TARGET. " |
| 109 | + @echo " dockerImage [TARGET=alpine|linux] " |
| 110 | + @echo " Creates the Docker image for TARGET. " |
| 111 | + @echo " dockerRun [TARGET=alpine|linux] " |
| 112 | + @echo " Runs the application in the TARGET specific container." |
| 113 | + @echo |
| 114 | + @echo Influential environment variables: |
| 115 | + @echo |
| 116 | + @echo " NATIVE_JMODS " |
| 117 | + @echo " Full path the the jmods directory of native target. " |
| 118 | + @echo " ALPINE_JMODS " |
| 119 | + @echo " Full path the the jmods directory of alpine target. " |
| 120 | + @echo " LINUX_JMODS " |
| 121 | + @echo " Full path the the jmods directory of linux target. " |
| 122 | + |
| 123 | +classes: $(CLASS_FILES) |
| 124 | +jar: $(ARTIFACT_FILE) |
| 125 | +jre: $(CUSTOM_RUNTIME_DIR) |
| 126 | +dockerfile: $(DOCKERFILE) |
40 | 127 |
|
41 |
| -$(JRE_DIR)/linux: $(JMODS_DIR)/http-server-1.0-SNAPSHOT.jar |
42 |
| - rm -rf $(JRE_DIR)/linux |
43 |
| - jlink --module-path $(JMODS_DIR):$(LINUX_JMODS) --strip-debug --vm server --compress 2 --class-for-name --no-header-files --no-man-pages --add-modules http.server --output $(JRE_DIR)/linux |
| 128 | +classesRun: classes |
| 129 | + -java --module-path $(CLASSES_DIR) -m $(MODULE_ID)/$(MAIN_CLASS) |
44 | 130 |
|
45 |
| -$(JRE_DIR)/macos: $(JMODS_DIR)/http-server-1.0-SNAPSHOT.jar |
46 |
| - rm -rf $(JRE_DIR)/macos |
47 |
| - jlink --module-path $(JMODS_DIR):$(MACOS_JMODS) --strip-debug --vm server --compress 2 --class-for-name --no-header-files --no-man-pages --add-modules http.server --output $(JRE_DIR)/macos |
| 131 | +jarRun: jar |
| 132 | + -java --module-path $(JMODS_DIR) -m $(MODULE_ID) |
48 | 133 |
|
49 |
| -$(JRE_DIR)/alpine: $(JMODS_DIR)/http-server-1.0-SNAPSHOT.jar |
50 |
| - rm -rf $(JRE_DIR)/alpine |
51 |
| - jlink --module-path $(JMODS_DIR):$(ALPINE_JMODS) --strip-debug --vm server --compress 2 --class-for-name --no-header-files --no-man-pages --add-modules http.server --output $(JRE_DIR)/alpine |
| 134 | +jreRun: jre |
| 135 | +ifneq ($(TARGET),native) |
| 136 | + $(error only native target makes sense for running the custom runtime outside Docker) |
| 137 | +endif |
| 138 | + -$(CUSTOM_RUNTIME_DIR)/bin/java -m $(MODULE_ID) |
| 139 | + |
| 140 | +$(CLASSES_DIR)/%.class: $(JAVA_SRC_DIR)/%.java |
| 141 | + @rm -rf $(CLASSES_DIR) |
| 142 | + @mkdir -p $(CLASSES_DIR) |
| 143 | + javac -d $(CLASSES_DIR) $(JAVA_FILES) |
| 144 | + |
| 145 | +$(ARTIFACT_FILE): $(CLASS_FILES) |
| 146 | + @rm -rf $(JMODS_DIR) |
| 147 | + @mkdir -p $(JMODS_DIR) |
| 148 | + jar --create --file $@ --main-class $(MAIN_CLASS) -C $(CLASSES_DIR) . |
| 149 | + |
| 150 | +$(CUSTOM_RUNTIME_DIR): $(ARTIFACT_FILE) $(TARGET_JMODS) |
| 151 | + @rm -rf $(CUSTOM_RUNTIME_DIR) |
| 152 | + jlink --module-path $(JMODS_DIR):$(TARGET_JMODS) \ |
| 153 | + --strip-debug --vm server --compress 2 \ |
| 154 | + --class-for-name --no-header-files --no-man-pages \ |
| 155 | + --dedup-legal-notices=error-if-not-same-content \ |
| 156 | + --add-modules $(MODULE_ID) \ |
| 157 | + --output $@ |
| 158 | + |
| 159 | +$(DOCKERFILE): Dockerfile.in |
| 160 | +ifeq ($(TARGET),native) |
| 161 | + $(error only alpine and linux targets make sense for Docker) |
| 162 | +endif |
| 163 | + @mkdir -p $(DOCKERFILE_DIR) |
| 164 | + sed -e 's BASE_IMAGE $(BASE_IMAGE) ' Dockerfile.in >$(DOCKERFILE) |
| 165 | + |
| 166 | +dockerImage: dockerfile jre |
| 167 | +ifeq ($(TARGET),native) |
| 168 | + $(error only alpine and linux targets make sense for Docker) |
| 169 | +endif |
| 170 | + @rm -rf $(DOCKER_DIR) |
| 171 | + @mkdir -p $(DOCKER_DIR) |
| 172 | + cp -a $(CUSTOM_RUNTIME_DIR) $(DOCKER_DIR)/jre |
| 173 | + cp $(DOCKERFILE) $(DOCKER_DIR)/Dockerfile |
| 174 | + (cd $(DOCKER_DIR) && docker build --tag $(DOCKER_TAG) .) |
| 175 | + |
| 176 | +dockerRun: dockerImage |
| 177 | + docker run --rm -it -p9000:9000 $(DOCKER_TAG) |
0 commit comments