summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2022-12-16 20:51:12 +0200
committerGitHub <noreply@github.com>2022-12-16 20:51:12 +0200
commit27bd499772483c620bc0eca219edf2707de3dee6 (patch)
treecae2d0ab1bf8a6cde791138194ab9fb800e2b2ca
parent6c26cb96b8a34a583fca023effd31a397c7f106e (diff)
parent35e230e48ca42f4ccb872d1d01f9280f8015b417 (diff)
downloadmeson-27bd499772483c620bc0eca219edf2707de3dee6.tar.gz
Merge pull request #11174 from bgilbert/jar-manifest
depfixer: silence `fix_jar()` and make it do something
-rw-r--r--mesonbuild/scripts/depfixer.py9
-rw-r--r--test cases/unit/110 classpath/com/mesonbuild/Simple.java7
-rw-r--r--test cases/unit/110 classpath/meson.build14
-rw-r--r--unittests/helpers.py17
-rw-r--r--unittests/machinefiletests.py18
5 files changed, 63 insertions, 2 deletions
diff --git a/mesonbuild/scripts/depfixer.py b/mesonbuild/scripts/depfixer.py
index 17432c189..8d9c90fe3 100644
--- a/mesonbuild/scripts/depfixer.py
+++ b/mesonbuild/scripts/depfixer.py
@@ -457,7 +457,7 @@ def fix_darwin(fname: str, new_rpath: str, final_path: str, install_name_mapping
raise SystemExit(err)
def fix_jar(fname: str) -> None:
- subprocess.check_call(['jar', 'xfv', fname, 'META-INF/MANIFEST.MF'])
+ subprocess.check_call(['jar', 'xf', fname, 'META-INF/MANIFEST.MF'])
with open('META-INF/MANIFEST.MF', 'r+', encoding='utf-8') as f:
lines = f.readlines()
f.seek(0)
@@ -465,7 +465,12 @@ def fix_jar(fname: str) -> None:
if not line.startswith('Class-Path:'):
f.write(line)
f.truncate()
- subprocess.check_call(['jar', 'ufm', fname, 'META-INF/MANIFEST.MF'])
+ # jar -um doesn't allow removing existing attributes. Use -uM instead,
+ # which a) removes the existing manifest from the jar and b) disables
+ # special-casing for the manifest file, so we can re-add it as a normal
+ # archive member. This puts the manifest at the end of the jar rather
+ # than the beginning, but the spec doesn't forbid that.
+ subprocess.check_call(['jar', 'ufM', fname, 'META-INF/MANIFEST.MF'])
def fix_rpath(fname: str, rpath_dirs_to_remove: T.Set[bytes], new_rpath: T.Union[str, bytes], final_path: str, install_name_mappings: T.Dict[str, str], verbose: bool = True) -> None:
global INSTALL_NAME_TOOL # pylint: disable=global-statement
diff --git a/test cases/unit/110 classpath/com/mesonbuild/Simple.java b/test cases/unit/110 classpath/com/mesonbuild/Simple.java
new file mode 100644
index 000000000..325a49a21
--- /dev/null
+++ b/test cases/unit/110 classpath/com/mesonbuild/Simple.java
@@ -0,0 +1,7 @@
+package com.mesonbuild;
+
+class Simple {
+ public static void main(String [] args) {
+ System.out.println("Java is working.\n");
+ }
+}
diff --git a/test cases/unit/110 classpath/meson.build b/test cases/unit/110 classpath/meson.build
new file mode 100644
index 000000000..e6b9b840a
--- /dev/null
+++ b/test cases/unit/110 classpath/meson.build
@@ -0,0 +1,14 @@
+project('simplejava', 'java')
+
+one = jar('one', 'com/mesonbuild/Simple.java',
+ main_class : 'com.mesonbuild.Simple',
+ install : true,
+ install_dir : get_option('bindir'),
+)
+
+two = jar('two', 'com/mesonbuild/Simple.java',
+ main_class : 'com.mesonbuild.Simple',
+ install : true,
+ install_dir : get_option('bindir'),
+ link_with : one,
+)
diff --git a/unittests/helpers.py b/unittests/helpers.py
index ac9d98073..d3d156056 100644
--- a/unittests/helpers.py
+++ b/unittests/helpers.py
@@ -5,6 +5,7 @@ import unittest
import functools
import re
import typing as T
+import zipfile
from pathlib import Path
from contextlib import contextmanager
@@ -176,6 +177,22 @@ def get_rpath(fname: str) -> T.Optional[str]:
return None
return final
+def get_classpath(fname: str) -> T.Optional[str]:
+ with zipfile.ZipFile(fname) as zip:
+ with zip.open('META-INF/MANIFEST.MF') as member:
+ contents = member.read().decode().strip()
+ lines = []
+ for line in contents.splitlines():
+ if line.startswith(' '):
+ # continuation line
+ lines[-1] += line[1:]
+ else:
+ lines.append(line)
+ manifest = {
+ k.lower(): v.strip() for k, v in [l.split(':', 1) for l in lines]
+ }
+ return manifest.get('class-path')
+
def get_path_without_cmd(cmd: str, path: str) -> str:
pathsep = os.pathsep
paths = OrderedSet([Path(p).resolve() for p in path.split(pathsep)])
diff --git a/unittests/machinefiletests.py b/unittests/machinefiletests.py
index 7d75ebc34..bf109b247 100644
--- a/unittests/machinefiletests.py
+++ b/unittests/machinefiletests.py
@@ -42,6 +42,7 @@ import mesonbuild.modules.pkgconfig
from run_tests import (
+ Backend,
get_fake_env
)
@@ -368,6 +369,23 @@ class NativeFileTests(BasePlatformTests):
self._single_implementation_compiler(
'java', 'javac', 'javac 9.99.77', '9.99.77')
+ @skip_if_not_language('java')
+ def test_java_classpath(self):
+ if self.backend is not Backend.ninja:
+ raise SkipTest('Jar is only supported with Ninja')
+ testdir = os.path.join(self.unit_test_dir, '110 classpath')
+ self.init(testdir)
+ self.build()
+ one_build_path = get_classpath(os.path.join(self.builddir, 'one.jar'))
+ self.assertIsNone(one_build_path)
+ two_build_path = get_classpath(os.path.join(self.builddir, 'two.jar'))
+ self.assertEqual(two_build_path, 'one.jar')
+ self.install()
+ one_install_path = get_classpath(os.path.join(self.installdir, 'usr/bin/one.jar'))
+ self.assertIsNone(one_install_path)
+ two_install_path = get_classpath(os.path.join(self.installdir, 'usr/bin/two.jar'))
+ self.assertIsNone(two_install_path)
+
@skip_if_not_language('swift')
def test_swift_compiler(self):
wrapper = self.helper_create_binary_wrapper(