RFR: 8303796: Optionally build fully statically linked JDK image

Erik Joelsson erikj at openjdk.org
Fri Apr 28 19:52:54 UTC 2023


On Fri, 28 Apr 2023 01:03:28 GMT, Jiangli Zhou <jiangli at openjdk.org> wrote:

> Initial implementation for supporting building a fully statically linked (with a desired set of JDK native libraries and libjvm) Java launcher executable, which is named as 'javastatic'.
> 
> In this PR, the support is only added for the linux platform. Both gcc and clang can be supported. For current demo/testing purpose, the bin/javastatic is statically linked with awt headless and other common JDK native libraries. The current PR doesn't fully handle creating the bundle for a static JDK image, which can be supported later.
> 
> To build the statically linked executable:
> 
> 1. Configure the JDK build with --with-static-java=yes
> 2. Build static-java-image, e.g. 'make jdk-image static-java-image'
> 
>  The 'javastatic' binary created by the static-java-image target is not runnable. The runtime issues will be handled separately.
> 
> Following is a summary of the changes in this PR:
> 
> - Add make/autoconf/static-java.m4 for defining STATIC_JAVA_SETUP. Add STATIC_JAVA_SETUP to make/autoconf/configure.ac.
> 
> - Changes in make/Main.gmk
>   - Add HOTSPOT_VARIANT_STATIC_LIBS_TARGETS and DeclareHotspotStaticLibsRecipe for building libjvm static library.
>   - Add static-java-image for creating the fully statically linked standard Java launcher binary, bin/javastatic. The build process also places libjvm.a into the 'static-libs' image lib/ directory.
> 
> - Add make/StaticLink.gmk, which contains the main support for creating the fully statically linked Java launcher binary.
> 
> - Setup LDFLAGS_CXX_STATIC_JDK based on $TOOLCHAIN_TYPE in make/autoconf/flags-ldflags.m4.
> 
> - Always use bundled libraries for zlib, freetype, etc for static build support. The related changes are in make/autoconf/lib-bundled.m4 and make/autoconf/lib-freetype.m4. Building the bundled zlib, freetype and etc libraries ensures those libraries are included in the JDK binary bundle. It decouples the assumptions/requirements of the static Java image build process from the assumptions/requirements of the JDK build process. A post process that builds the static Java image can use those bundled libraries provided by JDK binary if needed.
> 
> - When building a fully statically linked java launcher executable, the --whole-archive linker option is used for the JDK/VM static libraries to make sure it links every object (.o) file provided by those static libraries. As a result, we need to remove any duplicate object files from the different JDK/VM static libraries. To do that, STATIC_LIB_EXCLUDE_OBJS is added and used in make/common/NativeCompilation.gmk. STATIC_LIB_EXCLUDE_OBJS contains the list of object files that need to be filtered out when creating a specific static library. STATIC_LIB_EXCLUDE_OBJS is defined for JDK/VM static libraries that may contain object files from other libraries (those are needed when building shared libraries), and those object files are added to the STATIC_LIB_EXCLUDE_OBJS. See make/hotspot/lib/CompileJvm.gmk, make/modules/java.base/lib/CoreLibraries.gmk and make/modules/java.desktop/lib/Awt2dLibraries.gmk.
> 
> - In make/common/NativeCompilation.gmk, move the code handling long arguments so that it can be used for the static build support as well.
> 
> - In make/hotspot/lib/CompileJvm.gmk, it specifies to exclude operator_new.o from the libjvm static library. See details in the comment added in CompileJvm.gmk.
> 
> Thanks manc for a bug fix for JAVASTATIC_OBJECT_DIR in StaticLink.gmk.

I agree with the other comments here saying that this looks like something that would need a JEP. Especially since this isn't the full feature, but just the first step, and is essentially putting in dead code. It also seems like a higher level discussion about the solution may be needed.

Independent of the above, I have done a brief review of the code as it is.

make/Main.gmk line 1067:

> 1065:   static-libs-image: $(STATIC_LIBS_TARGETS)
> 1066: 
> 1067:   static-java-image: jdk-image hotspot-server-static-libs static-libs-image

You shouldn't need to repeat this. The DEPS parameter to SetupTarget should have handled it.

make/StaticLink.gmk line 83:

> 81:         else
> 82: 	  $(error Not supported on non-linux platform currently)
> 83:         endif

I think it would be rather beneficial if this linking step could be performed by some variant of SetupNativeCompilation. We don't want to have to maintain logic for dealing with different platforms and linkers outside of the common files if it can be helped. SetupNativeCompilation would need to be tweaked to run without SRC and just a set of `.a` files. 

The error about platform support should be handled in configure. We shouldn't be able to get here unless the configuration is expected to be supported.

make/autoconf/static-java.m4 line 31:

> 29: AC_DEFUN_ONCE([STATIC_JAVA_SETUP],
> 30: [
> 31:   AC_ARG_WITH(static-java, [AS_HELP_STRING([--with-static-java],

If this is all the setup for static-java in configure, I don't think it warrants having its own file. I would put this in jdk-options.m4 for now.

make/modules/java.base/lib/CoreLibraries.gmk line 172:

> 170:   # errors due to duplicate symbols.
> 171:   LIBJLI_STATIC_EXCLUDE_OBJS := \
> 172:       inflate.o inftrees.o inffast.o zadler32.o zcrc32.o zutil.o

This is the same list as the LIBJLI_EXTRA_FILES above. Would be good to avoid the duplication.

make/modules/java.desktop/lib/Awt2dLibraries.gmk line 228:

> 226:     # static libraries cause linking errors due to duplicate symbols.
> 227:     LIBAWT_XAWT_STATIC_EXCLUDE_OBJS := \
> 228:       debug_assert.o debug_util.o debug_trace.o debug_mem.o systemScale.o

Can this list be derived dynamically in some way? If they are all in the same directory, maybe we could base it on that instead of having to maintain an explicit list?

-------------

PR Review: https://git.openjdk.org/jdk/pull/13709#pullrequestreview-1406410191
PR Review Comment: https://git.openjdk.org/jdk/pull/13709#discussion_r1180697547
PR Review Comment: https://git.openjdk.org/jdk/pull/13709#discussion_r1180755742
PR Review Comment: https://git.openjdk.org/jdk/pull/13709#discussion_r1180747567
PR Review Comment: https://git.openjdk.org/jdk/pull/13709#discussion_r1180750185
PR Review Comment: https://git.openjdk.org/jdk/pull/13709#discussion_r1180751543



More information about the client-libs-dev mailing list