diff options
author | Tristan Partin <tristan@partin.io> | 2022-03-01 12:05:28 -0600 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2022-03-22 13:21:26 +0200 |
commit | 39f1d52e4a82cc75a4a3a41c3cc17fe2dabdb30b (patch) | |
tree | ec8855a6f7ea0c937736f366258ae8ca2629ea9d | |
parent | a559dbe70d113ebaa9bab406e371e54251d66e71 (diff) | |
download | meson-39f1d52e4a82cc75a4a3a41c3cc17fe2dabdb30b.zip meson-39f1d52e4a82cc75a4a3a41c3cc17fe2dabdb30b.tar.gz meson-39f1d52e4a82cc75a4a3a41c3cc17fe2dabdb30b.tar.bz2 |
Add ability to add resources to jars
Previously Meson lacked the ability to add resources to jar files.
Fixes #9945
-rw-r--r-- | docs/markdown/snippets/jar-resources.md | 34 | ||||
-rw-r--r-- | docs/yaml/functions/jar.yaml | 4 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 14 | ||||
-rw-r--r-- | mesonbuild/build.py | 8 | ||||
-rw-r--r-- | test cases/java/10 resources/meson.build | 7 | ||||
-rw-r--r-- | test cases/java/10 resources/src/com/mesonbuild/Resources.java | 26 | ||||
-rw-r--r-- | test cases/java/10 resources/src/meson.build | 13 | ||||
-rw-r--r-- | test cases/java/10 resources/src/resources/resource1.txt | 1 | ||||
-rw-r--r-- | test cases/java/10 resources/src/resources/subdir/resource2.txt | 1 |
9 files changed, 101 insertions, 7 deletions
diff --git a/docs/markdown/snippets/jar-resources.md b/docs/markdown/snippets/jar-resources.md new file mode 100644 index 0000000..12b0c81 --- /dev/null +++ b/docs/markdown/snippets/jar-resources.md @@ -0,0 +1,34 @@ +## JAR Resources + +The ability to add resources to a JAR has been added. Use the `java_resources` +keyword argument. It takes a `sturctured_src` object. + +```meson +jar( + meson.project_name(), + sources, + main_class: 'com.mesonbuild.Resources', + java_resources: structured_sources( + files('resources/resource1.txt'), + { + 'subdir': files('resources/subdir/resource2.txt'), + } + ) +) +``` + +To access these resources in your Java application: + +```java +try (InputStreamReader reader = new InputStreamReader( + Resources.class.getResourceAsStream("/resource1.txt"), + StandardCharsets.UTF_8)) { + // ... +} + +try (InputStreamReader reader = new InputStreamReader( + Resources.class.getResourceAsStream("/subdir/resource2.txt"), + StandardCharsets.UTF_8)) { + // ... +} +``` diff --git a/docs/yaml/functions/jar.yaml b/docs/yaml/functions/jar.yaml index 6e8e5dd..52f66e5 100644 --- a/docs/yaml/functions/jar.yaml +++ b/docs/yaml/functions/jar.yaml @@ -14,3 +14,7 @@ kwargs: main_class: type: str description: Main class for running the built jar + java_resources: + type: structured_src + since: 0.62.0 + description: Resources to be added to the jar diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 614e864..c630cc3 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1231,10 +1231,11 @@ class NinjaBackend(backends.Backend): elem = NinjaBuildElement(self.all_outputs, 'PHONY', 'phony', '') self.add_build(elem) - def generate_jar_target(self, target): + def generate_jar_target(self, target: build.Jar): fname = target.get_filename() outname_rel = os.path.join(self.get_target_dir(target), fname) src_list = target.get_sources() + resources = target.get_java_resources() class_list = [] compiler = target.compilers['java'] c = 'c' @@ -1280,6 +1281,9 @@ class NinjaBackend(backends.Backend): commands += ['-C', self.get_target_private_dir(target), '.'] elem = NinjaBuildElement(self.all_outputs, outname_rel, jar_rule, []) elem.add_dep(class_dep_list) + if resources: + # Copy all resources into the root of the jar. + elem.add_orderdep(self.__generate_sources_structure(Path(self.get_target_private_dir(target)), resources)[0]) elem.add_item('ARGS', commands) self.add_build(elem) # Create introspection information @@ -1663,11 +1667,10 @@ class NinjaBackend(backends.Backend): elem.add_orderdep(instr) self.add_build(elem) - def __generate_compile_structure(self, target: build.BuildTarget) -> T.Tuple[T.List[str], T.Optional[str]]: + def __generate_sources_structure(self, root: Path, structured_sources: build.StructuredSources) -> T.Tuple[T.List[str], T.Optional[str]]: first_file: T.Optional[str] = None orderdeps: T.List[str] = [] - root = Path(self.get_target_private_dir(target)) / 'structured' - for path, files in target.structured_sources.sources.items(): + for path, files in structured_sources.sources.items(): for file in files: if isinstance(file, File): out = root / path / Path(file.fname).name @@ -1706,7 +1709,8 @@ class NinjaBackend(backends.Backend): main_rust_file = None if target.structured_sources: if target.structured_sources.needs_copy(): - _ods, main_rust_file = self.__generate_compile_structure(target) + _ods, main_rust_file = self.__generate_sources_structure(Path( + self.get_target_private_dir(target)) / 'structured', target.structured_sources) orderdeps.extend(_ods) else: # The only way to get here is to have only files in the "root" diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 4f569a6..2c841a6 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -36,7 +36,7 @@ from .mesonlib import ( extract_as_list, typeslistify, stringlistify, classify_unity_sources, get_filenames_templates_dict, substitute_values, has_path_sep, OptionKey, PerMachineDefaultable, - MesonBugException, + MesonBugException ) from .compilers import ( Compiler, is_object, clink_langs, sort_clink, lang_suffixes, @@ -122,7 +122,7 @@ known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs', 'darwin_versions'} known_shmod_kwargs = known_build_target_kwargs | {'vs_module_defs'} known_stlib_kwargs = known_build_target_kwargs | {'pic', 'prelink'} -known_jar_kwargs = known_exe_kwargs | {'main_class'} +known_jar_kwargs = known_exe_kwargs | {'main_class', 'java_resources'} @lru_cache(maxsize=None) def get_target_macos_dylib_install_name(ld) -> str: @@ -2712,6 +2712,7 @@ class Jar(BuildTarget): self.filename = self.name + '.jar' self.outputs = [self.filename] self.java_args = kwargs.get('java_args', []) + self.java_resources: T.Optional[StructuredSources] = kwargs.get('java_resources', None) def get_main_class(self): return self.main_class @@ -2722,6 +2723,9 @@ class Jar(BuildTarget): def get_java_args(self): return self.java_args + def get_java_resources(self) -> T.Optional[StructuredSources]: + return self.java_resources + def validate_install(self, environment): # All jar targets are installable. pass diff --git a/test cases/java/10 resources/meson.build b/test cases/java/10 resources/meson.build new file mode 100644 index 0000000..3b87219 --- /dev/null +++ b/test cases/java/10 resources/meson.build @@ -0,0 +1,7 @@ +project('resources', ['java']) + +if meson.backend() != 'ninja' + error('MESON_SKIP_TEST: only valid on backends which support jar()') +endif + +subdir('src') diff --git a/test cases/java/10 resources/src/com/mesonbuild/Resources.java b/test cases/java/10 resources/src/com/mesonbuild/Resources.java new file mode 100644 index 0000000..de1b7d6 --- /dev/null +++ b/test cases/java/10 resources/src/com/mesonbuild/Resources.java @@ -0,0 +1,26 @@ +package com.mesonbuild; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +public class Resources { + public static void main(String[] args) throws IOException { + try (InputStreamReader reader = new InputStreamReader( + Resources.class.getResourceAsStream("/resource1.txt"), + StandardCharsets.UTF_8)) { + final BufferedReader buffered = new BufferedReader(reader); + + assert buffered.readLine() == "1"; + } + + try (InputStreamReader reader = new InputStreamReader( + Resources.class.getResourceAsStream("/subdir/resource2.txt"), + StandardCharsets.UTF_8)) { + final BufferedReader buffered = new BufferedReader(reader); + + assert buffered.readLine() == "2"; + } + } +} diff --git a/test cases/java/10 resources/src/meson.build b/test cases/java/10 resources/src/meson.build new file mode 100644 index 0000000..51f7d75 --- /dev/null +++ b/test cases/java/10 resources/src/meson.build @@ -0,0 +1,13 @@ +sources = files('com/mesonbuild/Resources.java') + +resources = jar( + meson.project_name(), + sources, + main_class: 'com.mesonbuild.Resources', + java_resources: structured_sources( + files('resources/resource1.txt'), + { + 'subdir': files('resources/subdir/resource2.txt'), + } + ) +) diff --git a/test cases/java/10 resources/src/resources/resource1.txt b/test cases/java/10 resources/src/resources/resource1.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/test cases/java/10 resources/src/resources/resource1.txt @@ -0,0 +1 @@ +1 diff --git a/test cases/java/10 resources/src/resources/subdir/resource2.txt b/test cases/java/10 resources/src/resources/subdir/resource2.txt new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/test cases/java/10 resources/src/resources/subdir/resource2.txt @@ -0,0 +1 @@ +2 |