Millet Porridge

English version of https://corvo.myseu.cn

0%

openjdk 7 Makefile

  • Build environment: Archlinux, 4.4.15-1-lts, x86_64 g++ 6.1.1, openjdk-7

hotspot: contains the source code and tools to build the openjdk hotspot virtual machine

langtools: contains the source code and tools to build javac and the language tools

corba: contains the build for openjdk corba

jaxws

jaxp

The top level builds the whole openjdk.

jaxp and jaxws do not contain source code; these tools can be obtained from the web. A complete jdk image needs JAXP and JAX-WS — they are part of the jdk.

After a successful build, the result is in the build/j2sdk-image folder by default.

ALT_BOOTDIR: directory of the Bootstrap JDK ALT_OUTPUTDIR: output path (absolute path) ALT_COMPILE_PATH: compiler path

I mainly studied hotspot; the hotspot directory structure looks like this:

The hotspot directory

1
2
3
4
5
6
7
8
9
10
.
├── agent
├── ASSEMBLY_EXCEPTION
├── build/ # output
├── make/ # build files
├── src/ # source code
├── test/
├── README
├── LICENSE
└── THIRD_PARTY_README

The entry Makefile

In the Makefile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
all:	all_product all_fastdebug

all_product: $(COMMON_VM_PRODUCT_TARGETS)
all_fastdebug: $(COMMON_VM_FASTDEBUG_TARGETS)
all_debug: $(COMMON_VM_DEBUG_TARGETS)

COMMON_VM_PRODUCT_TARGETS=product product1 docs export_product
COMMON_VM_FASTDEBUG_TARGETS=fastdebug fastdebug1 docs export_fastdebug
COMMON_VM_DEBUG_TARGETS=jvmg jvmg1 docs export_debug

C1_VM_TARGETS=product1 fastdebug1 optimized1 jvmg1
C2_VM_TARGETS=product fastdebug optimized jvmg
ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero
SHARK_VM_TARGETS=productshark fastdebugshark optimizedshark jvmgshark

From the targets above we can see that generating all_product and all_fastdebug just means generating product, product1, docs, export, fastdebug, fastdebug1 — so we have to prepare the builds one by one.

Then there are a few statements that basically express everything this Makefile does. First it gets $(GAMMADIR), which is the hotspot directory, and $(GAMMADIR)/make refers to the current folder. Things get much clearer now: these statements all call the Makefile they live in.

This also suggests a way of writing Makefiles: when you have some dependencies to build and don’t want to pass all variables down, you can use this approach to pass parameters selectively. (My own take — please point it out if it’s unreasonable.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$(C1_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
$(MAKE) BUILD_FLAVOR=$(@:%1=%) VM_TARGET=$@ generic_build1 $(ALT_OUT)

$(C2_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
$(MAKE) BUILD_FLAVOR=$@ VM_TARGET=$@ generic_build2 $(ALT_OUT)

$(ZERO_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
$(MAKE) BUILD_FLAVOR=$(@:%zero=%) VM_TARGET=$@ \
generic_buildzero $(ALT_OUT)

$(SHARK_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
$(MAKE) BUILD_FLAVOR=$(@:%shark=%) VM_TARGET=$@ \
generic_buildshark $(ALT_OUT)

generic_build2

Now we have a direction: the Makefile first calls generic_build2, probably because the product dependency comes first.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
generic_build2:
$(MKDIR) -p $(OUTPUTDIR)
ifeq ($(OSNAME),windows)
$(CD) $(OUTPUTDIR); \
$(NMAKE) -f $(ABS_OS_MAKEFILE) \
Variant=compiler2 \
WorkSpace=$(ABS_GAMMADIR) \
BootStrapDir=$(ABS_BOOTDIR) \
BuildUser=$(USERNAME) \
$(MAKE_ARGS) $(VM_TARGET)
else
# The first line is for debugging; it is not in the original file
echo -e "\033[32;1m In generic_build2 Line 208 ${MAKE_ARGS}\033[0m"; \
$(CD) $(OUTPUTDIR); \
$(MAKE) -f $(ABS_OS_MAKEFILE) \
$(MAKE_ARGS) $(VM_TARGET) \
endif

Since I mainly work on linux, this calls make/linux/Makefile and passes a number of parameters — there are many, so I won’t paste them here; you can print them yourself.