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