From a31f8eae76a7d0d1853634d8e41ec8b16ccae894 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Tue, 17 Mar 2026 14:40:16 +0100 Subject: [PATCH 1/4] sync common files --- ci/common.jsonnet | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/common.jsonnet b/ci/common.jsonnet index c3a15e6e..8e4d3c68 100644 --- a/ci/common.jsonnet +++ b/ci/common.jsonnet @@ -166,8 +166,8 @@ local common_json = import "../common.json"; "Graal diagnostic output saved in '(?P[^']+)'", # Keep in sync with jdk.graal.compiler.debug.DebugContext#DUMP_FILE_MESSAGE_REGEXP "Dumping debug output to '(?P[^']+)'", - # Keep in sync with com.oracle.svm.hosted.NativeImageOptions#DEFAULT_ERROR_FILE_NAME - " (?P.+/svm_err_b_\\d+T\\d+\\.\\d+_pid\\d+\\.md)", + # Keep in sync with com.oracle.svm.hosted.ProgressReporter#printErrorMessage + "Please inspect the generated error report at: '(?P[^']+)'", # Keep in sync with jdk.graal.compiler.test.SubprocessUtil#makeArgfile "@(?P.*SubprocessUtil-argfiles.*\\.argfile)", # Keep in sync with com.oracle.truffle.api.test.SubprocessTestUtils#makeArgfile From 07edf0e09ee50911d3c7eae274196f861eaea8cd Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 16 Mar 2026 21:53:41 +0100 Subject: [PATCH 2/4] added platform-specific ECLIPSE library --- .github/workflows/gate.yml | 10 +-------- ci.jsonnet | 18 +++------------- ci/common.jsonnet | 9 +------- mx.mx/suite.py | 39 ++++++++++++++++++++++++++++++++++ src/mx/_impl/mx_gate.py | 8 ++----- src/mx/_impl/mx_ide_eclipse.py | 35 ++++++++++++++++++++++++++---- src/mx/mx_version.py | 2 +- 7 files changed, 78 insertions(+), 43 deletions(-) diff --git a/.github/workflows/gate.yml b/.github/workflows/gate.yml index 08a8c7fd..fc95a58b 100644 --- a/.github/workflows/gate.yml +++ b/.github/workflows/gate.yml @@ -2,8 +2,6 @@ on: [push, pull_request] env: JDT: builtin - ECLIPSE_TAR: ${{ github.workspace }}/../eclipse.tar.gz - ECLIPSE_EXE: ${{ github.workspace }}/../eclipse/eclipse jobs: gate: @@ -22,19 +20,13 @@ jobs: architecture: x64 - uses: actions/setup-java@v1 with: - java-version: 17 + java-version: 25 - name: Style dependencies run: | cat common.json | jq -r '.pip | to_entries[] | .key + .value' | xargs pip install - run: pylint --version - - name: Download and set up Eclipse dependency - run: | - ECLIPSE_ORG_VERSION=$(cat common.json | jq -r '.eclipse.short_version') - ECLIPSE_ORG_TIMESTAMP=$(cat common.json | jq -r '.eclipse.timestamp') - wget --no-verbose https://archive.eclipse.org/eclipse/downloads/drops4/R-${ECLIPSE_ORG_VERSION}-${ECLIPSE_ORG_TIMESTAMP}/eclipse-SDK-${ECLIPSE_ORG_VERSION}-linux-gtk-x86_64.tar.gz -O $ECLIPSE_TAR - tar -C ${{ github.workspace }}/.. -xf $ECLIPSE_TAR - name: mx gate run: ./mx --strict-compliance gate --strict-mode - name: Test native build without vcs dir diff --git a/ci.jsonnet b/ci.jsonnet index a9ca2b65..e5ad9886 100644 --- a/ci.jsonnet +++ b/ci.jsonnet @@ -29,15 +29,8 @@ local with(platform, java_release, timelimit="15:00") = { local mx_copy_dir = path("${PWD}/../path with a space"), local mx = path("./mx"), local jdk = common.jdks["labsjdk-ee-%s" % java_release], - local eclipse_dep = if arch == "amd64" then common.deps.eclipse + { - environment+: { - ECLIPSE_EXE: if os == "darwin" then "$ECLIPSE/Contents/MacOS/eclipse" else exe("$ECLIPSE/eclipse") - } - } else { - # No CI Eclipse packages available on AArch64 - }, - local base = platform + jdk + eclipse_dep + common.deps.pylint + common.deps.sulong + common.deps.svm + { + local base = platform + jdk + common.deps.pylint + common.deps.sulong + common.deps.svm + { # Creates a builder name in "top down" order: first "what it is" (e.g. gate) then Java version followed by OS and arch name: "%s-jdk-%s-%s-%s" % [self.prefix, java_release, os, arch], targets: ["gate"], @@ -48,11 +41,7 @@ local with(platform, java_release, timelimit="15:00") = { # mx can work in that context. copydir("$PWD", mx_copy_dir), ["cd", mx_copy_dir], - ] + if os == "darwin" && eclipse_dep != {} then [ - # Need to remove the com.apple.quarantine attribute from Eclipse otherwise - # it will fail to start on later macOS versions. - ["xattr", "-d", "-r", "com.apple.quarantine", "${ECLIPSE}"], - ] else [], + ], java_home_in_env(suite_dir, suite_name):: [ # Set JAVA_HOME *only* in /mx./env @@ -78,8 +67,7 @@ local with(platform, java_release, timelimit="15:00") = { JDT: "builtin", }, run: self.java_home_in_env(".", "mx") + [ - [mx, "--strict-compliance", "gate"] - + (if eclipse_dep != {} then ["--strict-mode"] else []) + [mx, "--strict-compliance", "gate", "--strict-mode"] + (if os == "windows" then ["--tags", "fullbuild"] else []), ], }, diff --git a/ci/common.jsonnet b/ci/common.jsonnet index 8e4d3c68..f5b86364 100644 --- a/ci/common.jsonnet +++ b/ci/common.jsonnet @@ -193,15 +193,8 @@ local common_json = import "../common.json"; }, eclipse: { - downloads+: { - ECLIPSE: { - name: "eclipse", - version: common_json.eclipse.version, - platformspecific: true, - } - }, environment+: { - ECLIPSE_EXE: "$ECLIPSE/eclipse", + ECLIPSE_EXE: "builtin", }, }, diff --git a/mx.mx/suite.py b/mx.mx/suite.py index 2d620027..717daf4e 100644 --- a/mx.mx/suite.py +++ b/mx.mx/suite.py @@ -1002,6 +1002,45 @@ "license": "Apache-2.0", }, + "ECLIPSE": { + "packedResource": True, + "os_arch": { + "linux": { + "amd64": { + "urls": ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/eclipse-4.26.0-linux-amd64.tar.gz"], + "digest": "sha512:ef59976152d59f20e36196c918129cd1a0cfabcb1b4f195565142aec6952503bf67eca0d616620a987caed14840f9ca86ac09fb371d462bed0a304402893a77d", + }, + "aarch64": { + "urls": ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/eclipse-4.26.0-linux-aarch64.tar.gz"], + "digest": "sha512:28e43a059b9025e5696cc415c45ebb33717f2973260e199940136ad3258cfbff3e7740e205193026da8f62c9d3aab6b1f054ae9e7db2cbe0b395fc874a836fa6", + }, + "": { + "optional": True, + }, + }, + "darwin": { + "amd64": { + "urls": ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/eclipse-4.26.0-darwin-amd64.tar.gz"], + "digest": "sha512:3dc0ff8b3b6a608822194800d7ff5fae4a5fc4628160f9a9d5f6872358676c3beee87bc4d054f601cc6bf3773788ca85f689fb5e86c77f18ee09d7ad9cd6ef44", + }, + "aarch64": { + "urls": ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/eclipse-4.26.0-darwin-aarch64.tar.gz"], + "digest": "sha512:2e331e0a53319fccac434d3fbae133be60f1848ce475b744761645e588ede4635ad757051b5da804ea8488608c8e99d76cf495a3b48f06ef0d241194d6aa5931", + }, + "": { + "optional": True, + }, + }, + "windows": { + "amd64": { + "urls": ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/eclipse-4.26.0-windows-amd64.tar.gz"], + "digest": "sha512:a725741fee075df56688e1aa474a49ae1437f81cf03c2810074856ac2d8c16efddef8d977a926f77fe123ce613758b407f5676d502d69e69c2b075771dcc13f2", + }, + }, + }, + "license": "EPL-2.0", + }, + # last compatible version for JDK 8 - do not upgrade or remove "ECJ_3.26": { "digest": "sha512:ab441acf5551a7dc81c353eaccb3b3df9e89a48987294d19e39acdb83a5b640fcdff7414cee29f5b96eaa8826647f1d5323e185018fe33a64c402d69c73c9158", diff --git a/src/mx/_impl/mx_gate.py b/src/mx/_impl/mx_gate.py index 4f3562f1..4b1c936d 100644 --- a/src/mx/_impl/mx_gate.py +++ b/src/mx/_impl/mx_gate.py @@ -805,12 +805,8 @@ def _run_gate(cleanArgs, args, tasks): with Task('CodeFormatCheck', tasks, tags=[Tags.style], _common=True) as t: if t: - eclipse_exe = mx.get_env('ECLIPSE_EXE') - if eclipse_exe is not None: - if mx.command_function('eclipseformat')(['-e', eclipse_exe, '--primary']) != 0: - t.abort('Formatter modified files - run "mx eclipseformat", check in changes and repush') - else: - mx.abort_or_warn('ECLIPSE_EXE environment variable not set. Cannot execute CodeFormatCheck task.', args.strict_mode) + if mx.command_function('eclipseformat')(['--primary']) != 0: + t.abort('Formatter modified files - run "mx eclipseformat", check in changes and repush') with Task('Checkstyle', tasks, tags=[Tags.style], _common=True) as t: if t and mx.command_function('checkstyle')(['--primary']) != 0: diff --git a/src/mx/_impl/mx_ide_eclipse.py b/src/mx/_impl/mx_ide_eclipse.py index 110c0096..6265f645 100644 --- a/src/mx/_impl/mx_ide_eclipse.py +++ b/src/mx/_impl/mx_ide_eclipse.py @@ -148,7 +148,8 @@ def eclipseformat(args): The exit code 1 denotes that at least one file was modified.""" parser = ArgumentParser(prog='mx eclipseformat') - parser.add_argument('-e', '--eclipse-exe', help='location of the Eclipse executable') + parser.add_argument('-e', '--eclipse-exe', help='location of the Eclipse executable. Default is the ECLIPSE_EXE environment variable, ' + 'falling back to the ECLIPSE library. The special value of "builtin" will also select the ECLIPSE library.') parser.add_argument('-C', '--no-backup', action='store_false', dest='backup', help='do not save backup of modified files') parser.add_argument('--projects', action='store', help='comma separated projects to process (omit to process all projects)') parser.add_argument('--primary', action='store_true', help='limit checks to primary suite') @@ -296,18 +297,44 @@ def locate_eclipse_exe(eclipse_exe): """ Tries to locate an Eclipse executable starting with the given path. If the path is None, checks the ECLIPSE_EXE environment variable. + If the path is still None, downloads and uses the ECLIPSE library. If the path is a directory, tries to locate the eclipse executable below the directory. If the path is a file, ensures that the file is executable. Returns a path to the Eclipse executable if one could be found, None otherwise. """ + def find_eclipse_exe_in_dir(eclipse_dir): + eclipse_name = mx.exe_suffix('eclipse') + candidates = [ + join(eclipse_dir, eclipse_name), + join(eclipse_dir, 'eclipse', eclipse_name), + join(eclipse_dir, 'Eclipse.app', 'Contents', 'MacOS', 'eclipse'), + ] + for candidate in candidates: + if os.path.isfile(candidate): + return candidate + + fallback = None + for root, _, files in os.walk(eclipse_dir): + if eclipse_name in files: + candidate = join(root, eclipse_name) + if candidate.endswith(join('Contents', 'MacOS', 'eclipse')): + return candidate + if fallback is None: + fallback = candidate + return fallback + if eclipse_exe is None: eclipse_exe = os.environ.get('ECLIPSE_EXE') - if eclipse_exe is None: - return None + if eclipse_exe is None or eclipse_exe == "builtin": + eclipse_lib = mx.library('ECLIPSE') + eclipse_exe = eclipse_lib.get_path(resolve=True) # Maybe an Eclipse installation dir was specified - look for the executable in it if isdir(eclipse_exe): - eclipse_exe = join(eclipse_exe, mx.exe_suffix('eclipse')) + resolved_exe = find_eclipse_exe_in_dir(eclipse_exe) + if resolved_exe is None: + mx.abort('Could not find an Eclipse executable under directory: ' + eclipse_exe) + eclipse_exe = resolved_exe mx.warn("The eclipse-exe was a directory, now using " + eclipse_exe) if not os.path.isfile(eclipse_exe): mx.abort('File does not exist: ' + eclipse_exe) diff --git a/src/mx/mx_version.py b/src/mx/mx_version.py index 751ca02a..1181bce4 100644 --- a/src/mx/mx_version.py +++ b/src/mx/mx_version.py @@ -1,2 +1,2 @@ # The version must be updated for every PR (checked in CI) and the comment should reflect the PR's issue -version = "7.74.5" # [GR-73993] extra args passed to "lookup:" JAVA_HOME were ignored +version = "7.75.0" # [GR-73928] add platform-specific ECLIPSE library From ff5fdc8d68a923a9305d7ff50e9ee8dfa5508293 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Tue, 17 Mar 2026 10:25:34 +0100 Subject: [PATCH 3/4] revert changes to common files --- ci/common.jsonnet | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ci/common.jsonnet b/ci/common.jsonnet index f5b86364..8e4d3c68 100644 --- a/ci/common.jsonnet +++ b/ci/common.jsonnet @@ -193,8 +193,15 @@ local common_json = import "../common.json"; }, eclipse: { + downloads+: { + ECLIPSE: { + name: "eclipse", + version: common_json.eclipse.version, + platformspecific: true, + } + }, environment+: { - ECLIPSE_EXE: "builtin", + ECLIPSE_EXE: "$ECLIPSE/eclipse", }, }, From 660415744fcdb6af7f0b6ea7aae36c8759db9334 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Tue, 17 Mar 2026 20:42:33 +0100 Subject: [PATCH 4/4] run_in_mx must undo changes it mades to global options --- tests/code_owners_tests.py | 48 ++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/tests/code_owners_tests.py b/tests/code_owners_tests.py index 937413a5..8e21777f 100644 --- a/tests/code_owners_tests.py +++ b/tests/code_owners_tests.py @@ -568,23 +568,37 @@ def get_mx_binary(): def run_in_mx(args, cwd): # Ensure attribute existence for test - setattr(mx._opts, "verbose", False) - setattr(mx._opts, "warn", True) - setattr(mx._opts, "quiet", True) - setattr(mx._opts, "exec_log", None) - setattr(mx._opts, "ptimeout", 0) - - dev_null = mx.TeeOutputCapture(mx.OutputCapture()) - mx_bin = get_mx_binary() - mx_command = [mx_bin] + args - - # print("[debug] Will run {} in {}".format(mx_command, args)) - rc = mx.run( - mx_command, - out=dev_null, - cwd=cwd, - ) - assert rc == 0 + sentinel = object() + option_overrides = { + "verbose": False, + "warn": True, + "quiet": True, + "exec_log": None, + "ptimeout": 0, + } + original_values = {} + try: + for option, value in option_overrides.items(): + original_values[option] = getattr(mx._opts, option, sentinel) + setattr(mx._opts, option, value) + + dev_null = mx.TeeOutputCapture(mx.OutputCapture()) + mx_bin = get_mx_binary() + mx_command = [mx_bin] + args + + # print("[debug] Will run {} in {}".format(mx_command, args)) + rc = mx.run( + mx_command, + out=dev_null, + cwd=cwd, + ) + assert rc == 0 + finally: + for option, original_value in original_values.items(): + if original_value is sentinel: + delattr(mx._opts, option) + else: + setattr(mx._opts, option, original_value) def test_codeowners_json_output_generate_cases():