openJdk1.8中的makefile,记录下java的执行文件编译过程及jvm编译过程。
目录说明
openjdk源码中有很多目录,根据功能做了模块化划分,每个目录实现其相应的功能。每个目录下的结构都差不多,分为src(源码)、make(makefile)、test(或没有)、其他特殊目录。
![f066e2f90f560fd2fd8a5e8bfaa359bf.png](https://img-blog.csdnimg.cn/img_convert/f066e2f90f560fd2fd8a5e8bfaa359bf.png)
- Jdk目录
![1a3cf4b241dc61f41bbad9173d740696.png](https://img-blog.csdnimg.cn/img_convert/1a3cf4b241dc61f41bbad9173d740696.png)
- langtools目录
该目录主要实现了jdk提供的基于jvm的工具,比如:java, javac, javah, javap等。
![b68c654817f1124d8d98a74e9c9c18db.png](https://img-blog.csdnimg.cn/img_convert/b68c654817f1124d8d98a74e9c9c18db.png)
Makefile目标生成
可执行文件编译Makefile
文件名为:/openjdk/jdk/make/CompileLaunchers.gmkjava中提供的bin目录下的java、javac、javap等都不是完全通过c/c++编写实现的,是通过c/c++入口,启动虚拟机加载class文件实现的相关功能。通过c/c++的main函数入口,创建jvm虚拟机后,通过执行相关功能的java代码实现其功能,所以java相关的功能如编译、运行、查看jvm信息等功能都是通过启动一个jvm虚拟机或者通过jvmti等实现的。
在makefile文件中可以查看到该部分定义。
![08339d55244d9353545f5d8b36bfe4be.png](https://img-blog.csdnimg.cn/img_convert/08339d55244d9353545f5d8b36bfe4be.png)
具体各个具体功能实现可以由makefile中找到相关的类文件查看实现。这些类在目录langtools目录中。
在linux上编译openjdk的时候,所有java提供的工具程序(bin目录下的可执行程序)入口都是jdk/src/bin/share/bin/main.c。但是具体的功能代码实现其实是在langtools下通过java代码实现的,到底是怎么是怎么实现的呢。1、在jdk/src/share/bin/defines.h中通过宏开关实现了jvm虚拟机执行参数的定义,如下:
![7d53f3421a0ba4a636ae49d08ee3f318.png](https://img-blog.csdnimg.cn/img_convert/7d53f3421a0ba4a636ae49d08ee3f318.png)
最终生成的elf程序常量区段会有程序名称及入口的class类名称。
当使用javac编译java文件时,入口参数1为java文件路径,然后启动一个java虚拟机vm,把com.sun.tools.javac.Main aaa.java传递给java虚拟机vm执行,传递给虚拟机参数如下:
![1f93d535829b095d38aa712ca3fb1f57.png](https://img-blog.csdnimg.cn/img_convert/1f93d535829b095d38aa712ca3fb1f57.png)
- 2.1 jar包生成
jdk编译后会生成很多jar包,除了jvm虚拟机提供的一些平台功能外,其他语言层面的功能都是由java开发的jar包对外提供的,所以现在有很多语言都基于jvm做了实现。
openjdk提供了由运行时rt.jar, 工具tools.jar,编码charset.jar等其他功能jar。
下面详细介绍几个重要的jar包是怎么生成的。
tools.jar包
tools.jar包在jdk的lib目录下,主要提供jdk/bin目录下java工具的虚拟机里面的实现代码,由java开发。生成tools.jar包的makefile文件是:文件名为:/openjdk/jdk/make/CreateJars.gmk,内容如下:
源码路径:langtools目录
![7b3bc8578b029f6bdeffc6dafd740ce3.png](https://img-blog.csdnimg.cn/img_convert/7b3bc8578b029f6bdeffc6dafd740ce3.png)
rt.jar包
rt.jar包在jdk的lib目录下,主要提供java语言层面的运行时库,由java开发。rt.jar包含的文件范围由:/openjdk/jdk/make/profile-rtjar-includes.txt定义,内容如下:
![ac0c6768dbeeb6c8e7c904366116431f.png](https://img-blog.csdnimg.cn/img_convert/ac0c6768dbeeb6c8e7c904366116431f.png)
生成tools.jar包的makefile文件是:文件名为:/openjdk/jdk/make/CreateJars.gmk,内容如下:
![e1292ab1a7a0c61bb0b4832c3ed708a5.png](https://img-blog.csdnimg.cn/img_convert/e1292ab1a7a0c61bb0b4832c3ed708a5.png)
jconsole.jar
jconsole.jar包在jdk的lib目录下,是一个Java监视和管理控制台的客户端程序,由javax swing开发。jsoncole可以附加本地java进程,通过api查询方式或者使用jms协议查询java虚拟机一些观测数据。jconsole.jar主要组成由jdk/src/share/classes/sun/tools/jconsole、jdk/src/share/classes/com/sun/tools/jconsole目录下文件组成。
jdk本身提供了2中方式,一种是bin目录下的jconsole程序,另外一种就是lib下的jconsole.jar包。bin下的jsoncole直接运行,启动打开jconsole的main入口, lib下的jsoncole.jar需要使用java -jar jsoncole.jar运行。
$(eval $(call SetupArchive,BUILD_JCONSOLE_JAR, ,
SRCS := $(JDK_OUTPUTDIR)/classes, SUFFIXES := .class .gif .png .properties, INCLUDES := sun/tools/jconsole com/sun/tools/jconsole, JARMAIN := sun.tools.jconsole.JConsole, JAR := $(IMAGES_OUTPUTDIR)/lib/jconsole.jar, SKIP_METAINF := true))