From d5e42fab917a59e81319bec84a425d7674828a27 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Mon, 5 May 2025 11:23:59 +0200 Subject: [PATCH 1/7] [GR-63253] Add tools on module path, like Truffle and language distributions * That way in unchained standalones all jars are in imagemp and none in imagecp. --- tools/mx.tools/mx_tools.py | 21 +++++++++++++++++++++ tools/mx.tools/suite.py | 8 ++++++++ 2 files changed, 29 insertions(+) diff --git a/tools/mx.tools/mx_tools.py b/tools/mx.tools/mx_tools.py index 17672b4e449d..e9ee56539190 100644 --- a/tools/mx.tools/mx_tools.py +++ b/tools/mx.tools/mx_tools.py @@ -198,6 +198,27 @@ def apply(self, config): # in turn allows us to dynamically open fields/methods to reflection. vmArgs = vmArgs + ['--add-exports=java.base/jdk.internal.module=ALL-UNNAMED'] vmArgs = vmArgs + ['--add-modules=ALL-MODULE-PATH'] + # The tools unittests use internals + vmArgs = vmArgs + [ + '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.chromeinspector=ALL-UNNAMED', + '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.chromeinspector.objects=ALL-UNNAMED', + '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.chromeinspector.server=ALL-UNNAMED', + '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.chromeinspector.types=ALL-UNNAMED', + '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.chromeinspector.util=ALL-UNNAMED', + '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.utils.java_websocket.client=ALL-UNNAMED', + '--add-exports=com.oracle.truffle.tools.coverage/com.oracle.truffle.tools.coverage=ALL-UNNAMED', + '--add-exports=com.oracle.truffle.tools.coverage/com.oracle.truffle.tools.coverage.impl=ALL-UNNAMED', + '--add-exports=com.oracle.truffle.tools.dap/com.oracle.truffle.tools.dap.server=ALL-UNNAMED', + '--add-exports=com.oracle.truffle.tools.dap/com.oracle.truffle.tools.dap.types=ALL-UNNAMED', + '--add-exports=org.graalvm.tools.insight.heap/org.graalvm.tools.insight.heap=ALL-UNNAMED', + '--add-exports=org.graalvm.tools.insight.heap/org.graalvm.tools.insight.heap.instrument=ALL-UNNAMED', + '--add-exports=org.graalvm.tools.lsp/org.graalvm.tools.lsp.exceptions=ALL-UNNAMED', + '--add-exports=org.graalvm.tools.lsp/org.graalvm.tools.lsp.instrument=ALL-UNNAMED', + '--add-exports=org.graalvm.tools.lsp/org.graalvm.tools.lsp.server=ALL-UNNAMED', + '--add-exports=org.graalvm.tools.lsp/org.graalvm.tools.lsp.server.types=ALL-UNNAMED', + '--add-exports=org.graalvm.tools.lsp/org.graalvm.tools.lsp.server.utils=ALL-UNNAMED', + '--add-opens=org.graalvm.tools.insight/com.oracle.truffle.tools.agentscript.impl=ALL-UNNAMED', + ] return (vmArgs, mainClass, mainClassArgs) mx_unittest.register_unittest_config(ToolsUnittestConfig()) diff --git a/tools/mx.tools/suite.py b/tools/mx.tools/suite.py index 7bfc339581d6..43a9479b508a 100644 --- a/tools/mx.tools/suite.py +++ b/tools/mx.tools/suite.py @@ -370,6 +370,7 @@ "org.graalvm.polyglot", ], }, + "useModulePath" : True, "dependencies": ["com.oracle.truffle.tools.chromeinspector"], "distDependencies" : [ "truffle:TRUFFLE_API", @@ -431,6 +432,7 @@ "org.graalvm.collections", ], }, + "useModulePath" : True, "dependencies": [ "org.graalvm.tools.insight", "com.oracle.truffle.tools.agentscript" @@ -467,6 +469,7 @@ "org.graalvm.polyglot", ], }, + "useModulePath" : True, "dependencies": [ "org.graalvm.tools.insight.heap" ], @@ -538,6 +541,7 @@ "org.graalvm.polyglot", ], }, + "useModulePath" : True, "dependencies": [ "com.oracle.truffle.tools.profiler", ], @@ -597,6 +601,7 @@ "org.graalvm.polyglot", ], }, + "useModulePath" : True, "dependencies": [ "com.oracle.truffle.tools.coverage", ], @@ -658,6 +663,7 @@ "org.graalvm.polyglot", ], }, + "useModulePath" : True, "dependencies": [ "com.oracle.truffle.tools.dap", ], @@ -724,6 +730,7 @@ "subDir": "src", # This distribution defines a module. "moduleName" : "org.graalvm.tools.api.lsp", + "useModulePath" : True, "dependencies": ["org.graalvm.tools.api.lsp"], "distDependencies" : [ "truffle:TRUFFLE_API", @@ -746,6 +753,7 @@ "org.graalvm.truffle", ], }, + "useModulePath" : True, "dependencies": [ "org.graalvm.tools.api.lsp", "org.graalvm.tools.lsp" From d70e72eca7a0d3a971b31e6bac17cc1e5f7f2763 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Tue, 6 May 2025 18:21:21 +0200 Subject: [PATCH 2/7] Use JUnitOpenPackages to be more maintainable --- tools/mx.tools/mx_tools.py | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/tools/mx.tools/mx_tools.py b/tools/mx.tools/mx_tools.py index e9ee56539190..6bdf7a59fb4b 100644 --- a/tools/mx.tools/mx_tools.py +++ b/tools/mx.tools/mx_tools.py @@ -199,26 +199,12 @@ def apply(self, config): vmArgs = vmArgs + ['--add-exports=java.base/jdk.internal.module=ALL-UNNAMED'] vmArgs = vmArgs + ['--add-modules=ALL-MODULE-PATH'] # The tools unittests use internals - vmArgs = vmArgs + [ - '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.chromeinspector=ALL-UNNAMED', - '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.chromeinspector.objects=ALL-UNNAMED', - '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.chromeinspector.server=ALL-UNNAMED', - '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.chromeinspector.types=ALL-UNNAMED', - '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.chromeinspector.util=ALL-UNNAMED', - '--add-exports=com.oracle.truffle.tools.chromeinspector/com.oracle.truffle.tools.utils.java_websocket.client=ALL-UNNAMED', - '--add-exports=com.oracle.truffle.tools.coverage/com.oracle.truffle.tools.coverage=ALL-UNNAMED', - '--add-exports=com.oracle.truffle.tools.coverage/com.oracle.truffle.tools.coverage.impl=ALL-UNNAMED', - '--add-exports=com.oracle.truffle.tools.dap/com.oracle.truffle.tools.dap.server=ALL-UNNAMED', - '--add-exports=com.oracle.truffle.tools.dap/com.oracle.truffle.tools.dap.types=ALL-UNNAMED', - '--add-exports=org.graalvm.tools.insight.heap/org.graalvm.tools.insight.heap=ALL-UNNAMED', - '--add-exports=org.graalvm.tools.insight.heap/org.graalvm.tools.insight.heap.instrument=ALL-UNNAMED', - '--add-exports=org.graalvm.tools.lsp/org.graalvm.tools.lsp.exceptions=ALL-UNNAMED', - '--add-exports=org.graalvm.tools.lsp/org.graalvm.tools.lsp.instrument=ALL-UNNAMED', - '--add-exports=org.graalvm.tools.lsp/org.graalvm.tools.lsp.server=ALL-UNNAMED', - '--add-exports=org.graalvm.tools.lsp/org.graalvm.tools.lsp.server.types=ALL-UNNAMED', - '--add-exports=org.graalvm.tools.lsp/org.graalvm.tools.lsp.server.utils=ALL-UNNAMED', - '--add-opens=org.graalvm.tools.insight/com.oracle.truffle.tools.agentscript.impl=ALL-UNNAMED', - ] + mainClassArgs.extend(['-JUnitOpenPackages', 'com.oracle.truffle.tools.chromeinspector/*=ALL-UNNAMED']) + mainClassArgs.extend(['-JUnitOpenPackages', 'com.oracle.truffle.tools.coverage/*=ALL-UNNAMED']) + mainClassArgs.extend(['-JUnitOpenPackages', 'com.oracle.truffle.tools.dap/*=ALL-UNNAMED']) + mainClassArgs.extend(['-JUnitOpenPackages', 'org.graalvm.tools.insight/*=ALL-UNNAMED']) + mainClassArgs.extend(['-JUnitOpenPackages', 'org.graalvm.tools.insight.heap/*=ALL-UNNAMED']) + mainClassArgs.extend(['-JUnitOpenPackages', 'org.graalvm.tools.lsp/*=ALL-UNNAMED']) return (vmArgs, mainClass, mainClassArgs) mx_unittest.register_unittest_config(ToolsUnittestConfig()) From 40d150c6f20e675d2e8b58cd29bbb36f7b2ffdab Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Mon, 5 May 2025 11:41:53 +0200 Subject: [PATCH 3/7] Implement JavaHomeDependency#get_output_root() * Necessary when somesuite._output_root_includes_config() == False, used in graalpython. --- sdk/mx.sdk/mx_sdk_vm_ng.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sdk/mx.sdk/mx_sdk_vm_ng.py b/sdk/mx.sdk/mx_sdk_vm_ng.py index 3698291e978a..4fd936951763 100644 --- a/sdk/mx.sdk/mx_sdk_vm_ng.py +++ b/sdk/mx.sdk/mx_sdk_vm_ng.py @@ -753,6 +753,10 @@ def archived_deps(self): def isJDKDependent(self): return False + # Needed when somesuite._output_root_includes_config() == False + def get_output_root(self): + return join(self.get_output_base(), self.name) + class JavaHomeBuildTask(mx.BuildTask): subject: JavaHomeDependency From 996d85bf9011255d1ba5d765ae66b684d1889f17 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Mon, 5 May 2025 12:00:34 +0200 Subject: [PATCH 4/7] Refine the notion of enterprise in mx_sdk_vm_ng.py * Also make those 3 predicates public so they can be used in languages. --- sdk/mx.sdk/mx_sdk_vm_ng.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/sdk/mx.sdk/mx_sdk_vm_ng.py b/sdk/mx.sdk/mx_sdk_vm_ng.py index 4fd936951763..84fd36ee54cf 100644 --- a/sdk/mx.sdk/mx_sdk_vm_ng.py +++ b/sdk/mx.sdk/mx_sdk_vm_ng.py @@ -126,10 +126,16 @@ def _get_dyn_attribute(dep, attr_name, default): raise mx.abort(f"Could not resolve {attr_name} '{attr}' in {suite.extensions.__file__}", context=dep) return func(), attr -def _is_enterprise(): - return mx.suite('graal-enterprise', fatalIfMissing=False) or mx.suite('truffle-enterprise', fatalIfMissing=False) or mx.suite('substratevm-enterprise', fatalIfMissing=False) -def _is_nativeimage_ee(): +def _has_suite(name): + return mx.suite(name, fatalIfMissing=False) + +# Whether any of truffle-enterprise, graal-enterprise or substratevm-enterprise are imported. +def uses_enterprise_sources(): + # Technically testing for truffle-enterprise might be enough currently, but unclear if graal-enterprise will always depend on truffle-enterprise. + return _has_suite('truffle-enterprise') or _has_suite('graal-enterprise') or _has_suite('substratevm-enterprise') + +def is_nativeimage_ee(): global _is_nativeimage_ee_cache if _is_nativeimage_ee_cache is None: if not _external_bootstrap_graalvm: @@ -138,12 +144,16 @@ def _is_nativeimage_ee(): _is_nativeimage_ee_cache = exists(join(_external_bootstrap_graalvm, 'lib', 'svm', 'builder', 'svm-enterprise.jar')) return _is_nativeimage_ee_cache +# Whether the produced standalone uses anything enterprise, either from source or prebuilt (i.e., a boostrap Oracle GraalVM) +def is_enterprise(): + return uses_enterprise_sources() or is_nativeimage_ee() + class StandaloneLicenses(mx.Project): def __init__(self, suite, name, deps, workingSets, theLicense=None, **kw_args): self.community_license_file = _require(kw_args, 'community_license_file', suite, name) self.community_3rd_party_license_file = _require(kw_args, 'community_3rd_party_license_file', suite, name) - self.enterprise = _is_enterprise() + self.enterprise = is_enterprise() if self.enterprise: deps.append('lium:LICENSE_INFORMATION_USER_MANUAL') super().__init__(suite, name, subDir=None, srcDirs=[], deps=deps, workingSets=workingSets, d=suite.dir, theLicense=theLicense, **kw_args) @@ -156,8 +166,8 @@ def getArchivableResults(self, use_relpath=True, single=False): raise ValueError('single not supported') if self.enterprise: - truffle_enterprise = mx.suite('truffle-enterprise', fatalIfMissing=True, context=self) - vm_enterprise_dir = join(dirname(truffle_enterprise.dir), 'vm-enterprise') + lium_suite = mx.suite('lium', fatalIfMissing=True, context=self) + vm_enterprise_dir = join(dirname(lium_suite.dir), 'vm-enterprise') yield join(vm_enterprise_dir, 'GraalVM_GFTC_License.txt'), 'LICENSE.txt' yield from mx.distribution('lium:LICENSE_INFORMATION_USER_MANUAL').getArchivableResults(use_relpath, single=True) if not mx.suite('sdk').is_release(): @@ -338,7 +348,7 @@ def name_suffix(self): def get_build_args(self): extra_build_args = ['--shared'] - if _is_nativeimage_ee(): + if is_nativeimage_ee(): # PGO is supported extra_build_args += mx_sdk_vm_impl.svm_experimental_options(['-H:+ProfilingEnableProfileDumpHooks']) return super().get_build_args() + extra_build_args @@ -397,7 +407,7 @@ def get_build_args(self): canonical_name = self.subject.base_file_name() profiles = mx_sdk_vm_impl._image_profiles(canonical_name) if profiles: - if not _is_nativeimage_ee(): + if not is_nativeimage_ee(): raise mx.abort("Image profiles can not be used if PGO is not supported.") basenames = [basename(p) for p in profiles] if len(set(basenames)) != len(profiles): @@ -955,7 +965,7 @@ def __init__(self, suite, name=None, deps=None, excludedLibs=None, platformDepen path_substitutions.register_no_arg('graalvm_os', mx_sdk_vm_impl.get_graalvm_os()) string_substitutions = mx_subst.SubstitutionEngine(path_substitutions) - if _is_enterprise(): + if is_enterprise(): dir_name = enterprise_dir_name or f'{enterprise_archive_name}---' dist_name = 'STANDALONE_' + enterprise_archive_name.upper().replace('-', '_') else: From f3912f07c239084b43f224b1983a2c7330606b61 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Mon, 5 May 2025 12:47:41 +0200 Subject: [PATCH 5/7] Use the license from the bootstrap Oracle GraalVM if no enterprise sources --- sdk/mx.sdk/mx_sdk_vm_ng.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/sdk/mx.sdk/mx_sdk_vm_ng.py b/sdk/mx.sdk/mx_sdk_vm_ng.py index 84fd36ee54cf..ad53c8939e45 100644 --- a/sdk/mx.sdk/mx_sdk_vm_ng.py +++ b/sdk/mx.sdk/mx_sdk_vm_ng.py @@ -153,8 +153,9 @@ def __init__(self, suite, name, deps, workingSets, theLicense=None, **kw_args): self.community_license_file = _require(kw_args, 'community_license_file', suite, name) self.community_3rd_party_license_file = _require(kw_args, 'community_3rd_party_license_file', suite, name) + self.uses_enterprise_sources = uses_enterprise_sources() self.enterprise = is_enterprise() - if self.enterprise: + if self.uses_enterprise_sources: deps.append('lium:LICENSE_INFORMATION_USER_MANUAL') super().__init__(suite, name, subDir=None, srcDirs=[], deps=deps, workingSets=workingSets, d=suite.dir, theLicense=theLicense, **kw_args) @@ -166,12 +167,19 @@ def getArchivableResults(self, use_relpath=True, single=False): raise ValueError('single not supported') if self.enterprise: - lium_suite = mx.suite('lium', fatalIfMissing=True, context=self) - vm_enterprise_dir = join(dirname(lium_suite.dir), 'vm-enterprise') - yield join(vm_enterprise_dir, 'GraalVM_GFTC_License.txt'), 'LICENSE.txt' - yield from mx.distribution('lium:LICENSE_INFORMATION_USER_MANUAL').getArchivableResults(use_relpath, single=True) - if not mx.suite('sdk').is_release(): - yield join(vm_enterprise_dir, 'DISCLAIMER_FOR_SNAPSHOT_ARTIFACTS.txt'), 'DISCLAIMER.txt' + if self.uses_enterprise_sources: + lium_suite = mx.suite('lium', fatalIfMissing=True, context=self) + vm_enterprise_dir = join(dirname(lium_suite.dir), 'vm-enterprise') + yield join(vm_enterprise_dir, 'GraalVM_GFTC_License.txt'), 'LICENSE.txt' + yield from mx.distribution('lium:LICENSE_INFORMATION_USER_MANUAL').getArchivableResults(use_relpath, single=True) + if not mx.suite('sdk').is_release(): + yield join(vm_enterprise_dir, 'DISCLAIMER_FOR_SNAPSHOT_ARTIFACTS.txt'), 'DISCLAIMER.txt' + else: + # If the only enterprise input is a bootstrap Oracle GraalVM then copy the license from there + yield join(_external_bootstrap_graalvm, 'LICENSE.txt'), 'LICENSE.txt' + yield join(_external_bootstrap_graalvm, 'license-information-user-manual.zip'), 'license-information-user-manual.zip' + if not mx.suite('sdk').is_release(): + mx.warn('Cannot find DISCLAIMER_FOR_SNAPSHOT_ARTIFACTS.txt, you should copy it yourself in the result') else: yield join(self.suite.dir, self.community_license_file), 'LICENSE.txt' yield join(self.suite.dir, self.community_3rd_party_license_file), '3rd_party_licenses.txt' @@ -192,14 +200,19 @@ def needsBuild(self, newestInput): else: contents = None if contents != self.witness_contents(): - return True, 'CE<=>EE' + return True, f"{contents} => {self.witness_contents()}" return False, 'Files are already on disk' def witness_file(self): return join(self.subject.get_output_root(), 'witness') def witness_contents(self): - return 'ee' if self.subject.enterprise else 'ce' + if self.subject.uses_enterprise_sources: + return 'ee sources' + elif self.subject.enterprise: + return _external_bootstrap_graalvm + else: + return 'ce' def build(self): witness_file = self.witness_file() From db74bf2278faef65a9ae8f542656e820141793ce Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Mon, 5 May 2025 13:48:42 +0200 Subject: [PATCH 6/7] [GR-63253] Move DISCLAIMER_FOR_SNAPSHOT_ARTIFACTS to sdk for correctness and simplification --- ...DISCLAIMER_FOR_GFTC_SNAPSHOT_ARTIFACTS.txt | 20 +++++++++++++++++++ sdk/mx.sdk/mx_sdk_vm_ng.py | 6 ++---- 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 sdk/mx.sdk/DISCLAIMER_FOR_GFTC_SNAPSHOT_ARTIFACTS.txt diff --git a/sdk/mx.sdk/DISCLAIMER_FOR_GFTC_SNAPSHOT_ARTIFACTS.txt b/sdk/mx.sdk/DISCLAIMER_FOR_GFTC_SNAPSHOT_ARTIFACTS.txt new file mode 100644 index 000000000000..144feb960925 --- /dev/null +++ b/sdk/mx.sdk/DISCLAIMER_FOR_GFTC_SNAPSHOT_ARTIFACTS.txt @@ -0,0 +1,20 @@ +This is a daily development build of the Oracle product and is offered to you +as part of the development and testing process. Oracle does not recommend +bundling this build with your products or otherwise using for any production +purpose. This build is offered to and received by you solely under the GraalVM +Free Terms and Conditions (GFTC), and is not governed by any other license +between you and Oracle, including without limitation the Oracle Master +Agreement. The features and functionality of the product are subject to change +at any time and the existence of any features or functionality in this build +should not be relied upon in making purchasing decisions. The existence of +particular features or functionality in this build is not a commitment to +deliver any hardware, software or other material, or code, or functionality, +and you should not rely on the future availability of any feature or +functionality in the product. The development, release, and timing of any +features or functionality for this product remain at the sole discretion of +Oracle. In the event you decide to provide any input to Oracle regarding the +product, you acknowledge that Oracle may use that input for any purpose, +including but not limited to incorporation or implementation of the input in +any Oracle product or service, and the display, marketing, sublicensing and +distribution of the input as incorporated or embedded in any product or service +distributed or offered by Oracle. diff --git a/sdk/mx.sdk/mx_sdk_vm_ng.py b/sdk/mx.sdk/mx_sdk_vm_ng.py index ad53c8939e45..7ca58972c8d7 100644 --- a/sdk/mx.sdk/mx_sdk_vm_ng.py +++ b/sdk/mx.sdk/mx_sdk_vm_ng.py @@ -167,19 +167,17 @@ def getArchivableResults(self, use_relpath=True, single=False): raise ValueError('single not supported') if self.enterprise: + if not _suite.is_release(): + yield join(_suite.mxDir, 'DISCLAIMER_FOR_GFTC_SNAPSHOT_ARTIFACTS.txt'), 'DISCLAIMER.txt' if self.uses_enterprise_sources: lium_suite = mx.suite('lium', fatalIfMissing=True, context=self) vm_enterprise_dir = join(dirname(lium_suite.dir), 'vm-enterprise') yield join(vm_enterprise_dir, 'GraalVM_GFTC_License.txt'), 'LICENSE.txt' yield from mx.distribution('lium:LICENSE_INFORMATION_USER_MANUAL').getArchivableResults(use_relpath, single=True) - if not mx.suite('sdk').is_release(): - yield join(vm_enterprise_dir, 'DISCLAIMER_FOR_SNAPSHOT_ARTIFACTS.txt'), 'DISCLAIMER.txt' else: # If the only enterprise input is a bootstrap Oracle GraalVM then copy the license from there yield join(_external_bootstrap_graalvm, 'LICENSE.txt'), 'LICENSE.txt' yield join(_external_bootstrap_graalvm, 'license-information-user-manual.zip'), 'license-information-user-manual.zip' - if not mx.suite('sdk').is_release(): - mx.warn('Cannot find DISCLAIMER_FOR_SNAPSHOT_ARTIFACTS.txt, you should copy it yourself in the result') else: yield join(self.suite.dir, self.community_license_file), 'LICENSE.txt' yield join(self.suite.dir, self.community_3rd_party_license_file), '3rd_party_licenses.txt' From 84df9cbcd467fb7f3e35cecd8109ce29db3c8552 Mon Sep 17 00:00:00 2001 From: Roland Schatz Date: Tue, 8 Apr 2025 14:52:27 +0200 Subject: [PATCH 7/7] Add missing implementation of NativeImageBuildTask.newestOutput. --- sdk/mx.sdk/mx_sdk_vm_ng.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk/mx.sdk/mx_sdk_vm_ng.py b/sdk/mx.sdk/mx_sdk_vm_ng.py index 7ca58972c8d7..29ae28f6de6c 100644 --- a/sdk/mx.sdk/mx_sdk_vm_ng.py +++ b/sdk/mx.sdk/mx_sdk_vm_ng.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -402,6 +402,9 @@ def __init__(self, args, project: NativeImageProject): max_parallelism = 12 super().__init__(project, args, min(max_parallelism, mx.cpu_count())) + def newestOutput(self): + return mx.TimeStampFile.newest([_path for _path, _ in self.subject.getArchivableResults()]) + def get_build_args(self): experimental_build_args = [ '-H:+GenerateBuildArtifactsFile', # generate 'build-artifacts.json'