From c885e59cfaeaab98bd05ec1ea54441d8e7c8268a Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Mon, 13 Jan 2025 12:25:10 +0000 Subject: [PATCH] 8346377: Properly support static builds for Windows Reviewed-by: erikj --- make/StaticLibs.gmk | 6 ++-- make/autoconf/flags-ldflags.m4 | 4 +-- src/hotspot/os/windows/os_windows.cpp | 28 ++++++++++++----- src/java.base/windows/native/libjli/java_md.c | 30 +++++++++++++++---- .../native/libawt/windows/awt_Mlib.cpp | 8 +++-- 5 files changed, 55 insertions(+), 21 deletions(-) diff --git a/make/StaticLibs.gmk b/make/StaticLibs.gmk index 900fbbbbad4..e4b8e422caf 100644 --- a/make/StaticLibs.gmk +++ b/make/StaticLibs.gmk @@ -67,10 +67,8 @@ else ifeq ($(call isTargetOs, windows), true) BROKEN_STATIC_LIBS += splashscreen # libsspi_bridge has name conflicts with sunmscapi BROKEN_STATIC_LIBS += sspi_bridge - # These libs define DllMain which conflict with Hotspot - BROKEN_STATIC_LIBS += awt dt_shmem dt_socket - # These libs are dependent on any of the above disabled libs - BROKEN_STATIC_LIBS += fontmanager jawt lcms net nio + # dt_shmem define jdwpTransport_OnLoad which conflict with dt_socket + BROKEN_STATIC_LIBS += dt_shmem endif $(foreach module, $(STATIC_LIB_MODULES), \ diff --git a/make/autoconf/flags-ldflags.m4 b/make/autoconf/flags-ldflags.m4 index ffb1f0d6e19..2e060a71d4d 100644 --- a/make/autoconf/flags-ldflags.m4 +++ b/make/autoconf/flags-ldflags.m4 @@ -197,8 +197,8 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_CPU_DEP], $2LDFLAGS_JDKEXE="$LDFLAGS_JDK_COMMON $EXECUTABLE_LDFLAGS \ ${$1_CPU_EXECUTABLE_LDFLAGS} $REPRODUCIBLE_LDFLAGS $FILE_MACRO_LDFLAGS" - $2LDFLAGS_STATIC_JDK="$BASIC_LDFLAGS $BASIC_LDFLAGS_JVM_ONLY \ - $OS_LDFLAGS ${$2EXTRA_LDFLAGS} $REPRODUCIBLE_LDFLAGS $FILE_MACRO_LDFLAGS" + $2LDFLAGS_STATIC_JDK="$BASIC_LDFLAGS $OS_LDFLAGS ${$2EXTRA_LDFLAGS} \ + $REPRODUCIBLE_LDFLAGS $FILE_MACRO_LDFLAGS" $2JVM_LDFLAGS="$BASIC_LDFLAGS $BASIC_LDFLAGS_JVM_ONLY $OS_LDFLAGS $OS_LDFLAGS_JVM_ONLY \ $DEBUGLEVEL_LDFLAGS $DEBUGLEVEL_LDFLAGS_JVM_ONLY \ diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index afd8fe01752..d2868275094 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -285,6 +285,8 @@ void os::run_periodic_checks(outputStream* st) { static LONG WINAPI Uncaught_Exception_Handler(struct _EXCEPTION_POINTERS* exceptionInfo); +#define JVM_LIB_NAME "jvm.dll" + void os::init_system_properties_values() { // sysclasspath, java_home, dll_dir { @@ -300,15 +302,27 @@ void os::init_system_properties_values() { home_dir[MAX_PATH] = '\0'; } else { os::jvm_path(home_dir, sizeof(home_dir)); - // Found the full path to jvm.dll. - // Now cut the path to /jre if we can. - *(strrchr(home_dir, '\\')) = '\0'; // get rid of \jvm.dll + // Found the full path to the binary. It is normally of this structure: + // /bin//jvm.dll + // but can also be like this for a statically linked binary: + // /bin/.exe pslash = strrchr(home_dir, '\\'); if (pslash != nullptr) { - *pslash = '\0'; // get rid of \{client|server} + if (strncmp(pslash + 1, JVM_LIB_NAME, strlen(JVM_LIB_NAME)) == 0) { + // Binary name is jvm.dll. Get rid of \jvm.dll. + *pslash = '\0'; + } + + // Get rid of \hotspot_variant>, if binary is jvm.dll, + // or cut off \, if it is a statically linked binary. pslash = strrchr(home_dir, '\\'); if (pslash != nullptr) { - *pslash = '\0'; // get rid of \bin + *pslash = '\0'; + // Get rid of \bin + pslash = strrchr(home_dir, '\\'); + if (pslash != nullptr) { + *pslash = '\0'; + } } } } @@ -1402,9 +1416,7 @@ void* os::dll_lookup(void *lib, const char *name) { } void* os::lookup_function(const char* name) { - // This is needed only for static builds which are not supported on Windows - ShouldNotReachHere(); - return nullptr; // Satisfy compiler + return ::GetProcAddress(nullptr, name); } // Directory routines copied from src/win32/native/java/io/dirent_md.c diff --git a/src/java.base/windows/native/libjli/java_md.c b/src/java.base/windows/native/libjli/java_md.c index c4d38a02831..77d48fecca0 100644 --- a/src/java.base/windows/native/libjli/java_md.c +++ b/src/java.base/windows/native/libjli/java_md.c @@ -155,6 +155,12 @@ CreateExecutionEnvironment(int *pargc, char ***pargv, char *jdkroot, jint so_jdkroot, char *jvmpath, jint so_jvmpath, char *jvmcfg, jint so_jvmcfg) { + if (JLI_IsStaticallyLinked()) { + // With static builds, all JDK and VM natives are statically linked + // with the launcher executable. The 'jrepath', 'jvmpath' and + // 'jvmcfg' are not used by the caller for static builds. Simply return. + return; + } char *jvmtype; int i = 0; @@ -222,6 +228,12 @@ LoadMSVCRT() char crtpath[MAXPATHLEN]; if (!loaded) { + if (JLI_IsStaticallyLinked()) { + // For statically linked builds, we rely on the system msvcrt dlls + loaded = 1; + return JNI_TRUE; + } + /* * The Microsoft C Runtime Library needs to be loaded first. A copy is * assumed to be present in the "bin" directory of the JDK installation root. @@ -365,10 +377,14 @@ LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn) */ LoadMSVCRT(); - /* Load the Java VM DLL */ - if ((handle = LoadLibrary(jvmpath)) == 0) { - JLI_ReportErrorMessage(DLL_ERROR4, (char *)jvmpath); - return JNI_FALSE; + if (JLI_IsStaticallyLinked()) { + handle = GetModuleHandle(NULL); + } else { + /* Load the Java VM DLL */ + if ((handle = LoadLibrary(jvmpath)) == 0) { + JLI_ReportErrorMessage(DLL_ERROR4, (char *)jvmpath); + return JNI_FALSE; + } } /* Now get the function addresses */ @@ -781,7 +797,11 @@ jclass FindBootStrapClass(JNIEnv *env, const char *classname) HMODULE hJvm; if (findBootClass == NULL) { - hJvm = GetModuleHandle(JVM_DLL); + if (JLI_IsStaticallyLinked()) { + hJvm = GetModuleHandle(NULL); + } else { + hJvm = GetModuleHandle(JVM_DLL); + } if (hJvm == NULL) return NULL; /* need to use the demangled entry point */ findBootClass = (FindClassFromBootLoader_t *)GetProcAddress(hJvm, diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Mlib.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Mlib.cpp index 15d39a5e4d4..5b189796ed1 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Mlib.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Mlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,11 @@ extern "C" * Here we just need to get handle to initialize the pointers to * required mlib routines. */ - hDLL = ::GetModuleHandle(TEXT("mlib_image.dll")); + if (JVM_IsStaticallyLinked()) { + hDLL = ::GetModuleHandle(NULL); + } else { + hDLL = ::GetModuleHandle(TEXT("mlib_image.dll")); + } if (hDLL == NULL) { return MLIB_FAILURE;