Merge pull request #3763 from noverby/wip/noverby/jar-linking-manifest
java: support for linking jar files (using manifest)
This commit is contained in:
commit
4dc97a910e
|
@ -970,7 +970,7 @@ int dummy;
|
|||
class_list = []
|
||||
compiler = target.compilers['java']
|
||||
c = 'c'
|
||||
m = ''
|
||||
m = 'm'
|
||||
e = ''
|
||||
f = 'f'
|
||||
main_class = target.get_main_class()
|
||||
|
@ -980,8 +980,18 @@ int dummy;
|
|||
plain_class_path = self.generate_single_java_compile(src, target, compiler, outfile)
|
||||
class_list.append(plain_class_path)
|
||||
class_dep_list = [os.path.join(self.get_target_private_dir(target), i) for i in class_list]
|
||||
manifest_path = os.path.join(self.get_target_private_dir(target), 'META-INF', 'MANIFEST.MF')
|
||||
manifest_fullpath = os.path.join(self.environment.get_build_dir(), manifest_path)
|
||||
os.makedirs(os.path.dirname(manifest_fullpath), exist_ok=True)
|
||||
with open(manifest_fullpath, 'w') as manifest:
|
||||
if any(target.link_targets):
|
||||
manifest.write('Class-Path: ')
|
||||
cp_paths = [os.path.join(self.get_target_dir(l), l.get_filename()) for l in target.link_targets]
|
||||
manifest.write(' '.join(cp_paths))
|
||||
manifest.write('\n')
|
||||
jar_rule = 'java_LINKER'
|
||||
commands = [c + m + e + f]
|
||||
commands.append(manifest_path)
|
||||
if e != '':
|
||||
commands.append(main_class)
|
||||
commands.append(self.get_target_filename(target))
|
||||
|
@ -1063,12 +1073,14 @@ int dummy;
|
|||
self.generate_generator_list_rules(target, outfile)
|
||||
|
||||
def generate_single_java_compile(self, src, target, compiler, outfile):
|
||||
deps = [os.path.join(self.get_target_dir(l), l.get_filename()) for l in target.link_targets]
|
||||
args = []
|
||||
args += compiler.get_buildtype_args(self.get_option_for_target('buildtype', target))
|
||||
args += self.build.get_global_args(compiler)
|
||||
args += self.build.get_project_args(compiler, target.subproject)
|
||||
args += target.get_java_args()
|
||||
args += compiler.get_output_args(self.get_target_private_dir(target))
|
||||
args += target.get_classpath_args()
|
||||
curdir = target.get_subdir()
|
||||
sourcepath = os.path.join(self.build_to_src, curdir) + os.pathsep
|
||||
sourcepath += os.path.normpath(curdir) + os.pathsep
|
||||
|
@ -1080,6 +1092,7 @@ int dummy;
|
|||
plain_class_path = src.fname[:-4] + 'class'
|
||||
rel_obj = os.path.join(self.get_target_private_dir(target), plain_class_path)
|
||||
element = NinjaBuildElement(self.all_outputs, rel_obj, compiler.get_language() + '_COMPILER', rel_src)
|
||||
element.add_dep(deps)
|
||||
element.add_item('ARGS', args)
|
||||
element.write(outfile)
|
||||
return plain_class_path
|
||||
|
|
|
@ -1911,6 +1911,9 @@ class Jar(BuildTarget):
|
|||
for s in self.sources:
|
||||
if not s.endswith('.java'):
|
||||
raise InvalidArguments('Jar source %s is not a java file.' % s)
|
||||
for t in self.link_targets:
|
||||
if not isinstance(t, Jar):
|
||||
raise InvalidArguments('Link target %s is not a jar target.' % t)
|
||||
self.filename = self.name + '.jar'
|
||||
self.outputs = [self.filename]
|
||||
self.java_args = kwargs.get('java_args', [])
|
||||
|
@ -1928,6 +1931,13 @@ class Jar(BuildTarget):
|
|||
# All jar targets are installable.
|
||||
pass
|
||||
|
||||
def is_linkable_target(self):
|
||||
return True
|
||||
|
||||
def get_classpath_args(self):
|
||||
cp_paths = [os.path.join(l.get_subdir(), l.get_filename()) for l in self.link_targets]
|
||||
return ['-cp', os.pathsep.join(cp_paths)]
|
||||
|
||||
class CustomTargetIndex:
|
||||
|
||||
"""A special opaque object returned by indexing a CustomTarget. This object
|
||||
|
@ -1950,7 +1960,6 @@ class CustomTargetIndex:
|
|||
def get_subdir(self):
|
||||
return self.target.get_subdir()
|
||||
|
||||
|
||||
class ConfigureFile:
|
||||
|
||||
def __init__(self, subdir, sourcename, targetname, configuration_data):
|
||||
|
|
|
@ -396,11 +396,25 @@ def fix_darwin(fname, new_rpath, final_path, install_name_mappings):
|
|||
raise
|
||||
sys.exit(0)
|
||||
|
||||
def fix_jar(fname):
|
||||
subprocess.check_call(['jar', 'xfv', fname, 'META-INF/MANIFEST.MF'])
|
||||
with open('META-INF/MANIFEST.MF', 'r+') as f:
|
||||
lines = f.readlines()
|
||||
f.seek(0)
|
||||
for line in lines:
|
||||
if not line.startswith('Class-Path:'):
|
||||
f.write(line)
|
||||
f.truncate()
|
||||
subprocess.check_call(['jar', 'ufm', fname, 'META-INF/MANIFEST.MF'])
|
||||
|
||||
def fix_rpath(fname, new_rpath, final_path, install_name_mappings, verbose=True):
|
||||
# Static libraries never have rpaths
|
||||
if fname.endswith('.a'):
|
||||
return
|
||||
try:
|
||||
if fname.endswith('.jar'):
|
||||
fix_jar(fname)
|
||||
return
|
||||
fix_elf(fname, new_rpath, verbose)
|
||||
return
|
||||
except SystemExit as e:
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package com.mesonbuild;
|
||||
|
||||
import com.mesonbuild.SimpleLib;
|
||||
|
||||
class Linking {
|
||||
public static void main(String [] args) {
|
||||
SimpleLib.func();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
project('linkingjava', 'java')
|
||||
|
||||
subdir('sub')
|
||||
|
||||
javaprog = jar('myprog', 'com/mesonbuild/Linking.java',
|
||||
main_class : 'com.mesonbuild.Linking',
|
||||
link_with : simplelib)
|
||||
test('mytest', javaprog)
|
|
@ -0,0 +1,7 @@
|
|||
package com.mesonbuild;
|
||||
|
||||
public class SimpleLib {
|
||||
public static void func() {
|
||||
System.out.println("Java linking is working.\n");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
simplelib = jar('simplelib',
|
||||
'com/mesonbuild/SimpleLib.java')
|
Loading…
Reference in New Issue