Can extract objects from targets and use them in other targets.
This commit is contained in:
parent
337b14e602
commit
8f5d93b4d4
13
backends.py
13
backends.py
|
@ -174,13 +174,24 @@ class Backend():
|
||||||
for obj in target.get_objects():
|
for obj in target.get_objects():
|
||||||
if isinstance(obj, str):
|
if isinstance(obj, str):
|
||||||
o = os.path.join(self.build_to_src, target.get_subdir(), obj)
|
o = os.path.join(self.build_to_src, target.get_subdir(), obj)
|
||||||
|
obj_list.append(o)
|
||||||
|
elif isinstance(obj, build.ExtractedObjects):
|
||||||
|
obj_list += self.determine_ext_objs(obj)
|
||||||
else:
|
else:
|
||||||
raise MesonException('Unknown data type in object list.')
|
raise MesonException('Unknown data type in object list.')
|
||||||
obj_list.append(o)
|
|
||||||
elem = self.generate_link(target, outfile, outname, obj_list)
|
elem = self.generate_link(target, outfile, outname, obj_list)
|
||||||
self.generate_shlib_aliases(target, self.get_target_dir(target), outfile, elem)
|
self.generate_shlib_aliases(target, self.get_target_dir(target), outfile, elem)
|
||||||
self.processed_targets[name] = True
|
self.processed_targets[name] = True
|
||||||
|
|
||||||
|
def determine_ext_objs(self, extobj):
|
||||||
|
result = []
|
||||||
|
targetdir = self.get_target_private_dir(extobj.target)
|
||||||
|
suffix = '.' + self.environment.get_object_suffix()
|
||||||
|
for osrc in extobj.srclist:
|
||||||
|
objname = os.path.join(targetdir, os.path.basename(osrc) + suffix)
|
||||||
|
result.append(objname)
|
||||||
|
return result
|
||||||
|
|
||||||
def process_target_dependencies(self, target, outfile):
|
def process_target_dependencies(self, target, outfile):
|
||||||
for t in target.get_dependencies():
|
for t in target.get_dependencies():
|
||||||
tname = t.get_basename()
|
tname = t.get_basename()
|
||||||
|
|
55
build.py
55
build.py
|
@ -90,6 +90,11 @@ class IncludeDirs():
|
||||||
def get_incdirs(self):
|
def get_incdirs(self):
|
||||||
return self.incdirs
|
return self.incdirs
|
||||||
|
|
||||||
|
class ExtractedObjects():
|
||||||
|
def __init__(self, target, srclist):
|
||||||
|
self.target = target
|
||||||
|
self.srclist = srclist
|
||||||
|
|
||||||
class BuildTarget():
|
class BuildTarget():
|
||||||
def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs):
|
def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -114,8 +119,12 @@ class BuildTarget():
|
||||||
def process_objectlist(self, objects):
|
def process_objectlist(self, objects):
|
||||||
assert(isinstance(objects, list))
|
assert(isinstance(objects, list))
|
||||||
for s in objects:
|
for s in objects:
|
||||||
|
if hasattr(s, 'held_object'):
|
||||||
|
s = s.held_object
|
||||||
if isinstance(s, str):
|
if isinstance(s, str):
|
||||||
self.objects.append(s)
|
self.objects.append(s)
|
||||||
|
elif isinstance(s, ExtractedObjects):
|
||||||
|
self.objects.append(s)
|
||||||
else:
|
else:
|
||||||
raise InvalidArguments('Bad object in target %s.' % self.name)
|
raise InvalidArguments('Bad object in target %s.' % self.name)
|
||||||
|
|
||||||
|
@ -136,22 +145,38 @@ class BuildTarget():
|
||||||
def get_original_kwargs(self):
|
def get_original_kwargs(self):
|
||||||
return self.kwargs
|
return self.kwargs
|
||||||
|
|
||||||
|
def unpack_holder(self, d):
|
||||||
|
if not isinstance(d, list):
|
||||||
|
d = [d]
|
||||||
|
newd = []
|
||||||
|
for i in d:
|
||||||
|
if hasattr(i, 'el'):
|
||||||
|
newd.append(i.el)
|
||||||
|
elif hasattr(i, 'held_object'):
|
||||||
|
newd.append(i.held_object)
|
||||||
|
else:
|
||||||
|
newd.append(i)
|
||||||
|
return newd
|
||||||
|
|
||||||
def copy_kwargs(self, kwargs):
|
def copy_kwargs(self, kwargs):
|
||||||
self.kwargs = copy.copy(kwargs)
|
self.kwargs = copy.copy(kwargs)
|
||||||
# This sucks quite badly. Arguments
|
# This sucks quite badly. Arguments
|
||||||
# are holders but they can't be pickled
|
# are holders but they can't be pickled
|
||||||
# so unpack those known.
|
# so unpack those known.
|
||||||
if 'deps' in self.kwargs:
|
if 'deps' in self.kwargs:
|
||||||
d = self.kwargs['deps']
|
self.kwargs['deps'] = self.unpack_holder(self.kwargs['deps'])
|
||||||
if not isinstance(d, list):
|
if 'link_with' in self.kwargs:
|
||||||
d = [d]
|
self.kwargs['link_with'] = self.unpack_holder(self.kwargs['link_with'])
|
||||||
newd = []
|
|
||||||
for i in d:
|
def extract_objects(self, srclist):
|
||||||
if hasattr(i, 'el'):
|
obj_src = []
|
||||||
newd.append(i.el)
|
for src in srclist:
|
||||||
else:
|
if not isinstance(src, str):
|
||||||
newd.append(i)
|
raise coredata.MesonException('Extraction arguments must be strings.')
|
||||||
self.kwargs['deps'] = newd
|
if src not in self.sources:
|
||||||
|
raise coredata.MesonException('Tried to extract unknown source %s.' % src)
|
||||||
|
obj_src.append(src)
|
||||||
|
return ExtractedObjects(self, obj_src)
|
||||||
|
|
||||||
def get_rpaths(self):
|
def get_rpaths(self):
|
||||||
return self.get_transitive_rpaths()
|
return self.get_transitive_rpaths()
|
||||||
|
@ -172,8 +197,8 @@ class BuildTarget():
|
||||||
for linktarget in llist:
|
for linktarget in llist:
|
||||||
# Sorry for this hack. Keyword targets are kept in holders
|
# Sorry for this hack. Keyword targets are kept in holders
|
||||||
# in kwargs. Unpack here without looking at the exact type.
|
# in kwargs. Unpack here without looking at the exact type.
|
||||||
if hasattr(linktarget, "target"):
|
if hasattr(linktarget, "held_object"):
|
||||||
linktarget = linktarget.target
|
linktarget = linktarget.held_object
|
||||||
self.link(linktarget)
|
self.link(linktarget)
|
||||||
c_pchlist = kwargs.get('c_pch', [])
|
c_pchlist = kwargs.get('c_pch', [])
|
||||||
if not isinstance(c_pchlist, list):
|
if not isinstance(c_pchlist, list):
|
||||||
|
@ -263,6 +288,8 @@ class BuildTarget():
|
||||||
[self.add_external_dep(dep) for dep in args]
|
[self.add_external_dep(dep) for dep in args]
|
||||||
|
|
||||||
def link(self, target):
|
def link(self, target):
|
||||||
|
if hasattr(target, 'held_object'):
|
||||||
|
target = target.held_object
|
||||||
if not isinstance(target, StaticLibrary) and \
|
if not isinstance(target, StaticLibrary) and \
|
||||||
not isinstance(target, SharedLibrary):
|
not isinstance(target, SharedLibrary):
|
||||||
print(target)
|
print(target)
|
||||||
|
@ -321,8 +348,8 @@ class Generator():
|
||||||
if len(args) != 1:
|
if len(args) != 1:
|
||||||
raise InvalidArguments('Generator requires one and only one positional argument')
|
raise InvalidArguments('Generator requires one and only one positional argument')
|
||||||
|
|
||||||
if hasattr(args[0], 'target'):
|
if hasattr(args[0], 'held_object'):
|
||||||
exe = args[0].target
|
exe = args[0].held_object
|
||||||
if not isinstance(exe, Executable):
|
if not isinstance(exe, Executable):
|
||||||
raise InvalidArguments('First generator argument must be an executable.')
|
raise InvalidArguments('First generator argument must be an executable.')
|
||||||
elif hasattr(args[0], 'ep'):
|
elif hasattr(args[0], 'ep'):
|
||||||
|
|
|
@ -311,12 +311,23 @@ class Man(InterpreterObject):
|
||||||
def get_sources(self):
|
def get_sources(self):
|
||||||
return self.sources
|
return self.sources
|
||||||
|
|
||||||
|
class GeneratedObjectsHolder(InterpreterObject):
|
||||||
|
def __init__(self, held_object):
|
||||||
|
super().__init__()
|
||||||
|
self.held_object = held_object
|
||||||
|
|
||||||
class BuildTargetHolder(InterpreterObject):
|
class BuildTargetHolder(InterpreterObject):
|
||||||
def __init__(self, targetttype, name, subdir, is_cross, sources, objects, environment, kwargs):
|
def __init__(self, targetttype, name, subdir, is_cross, sources, objects, environment, kwargs):
|
||||||
self.target = targetttype(name, subdir, is_cross, sources, objects, environment, kwargs)
|
super().__init__()
|
||||||
|
self.held_object = targetttype(name, subdir, is_cross, sources, objects, environment, kwargs)
|
||||||
|
self.methods.update({'extract_objects' : self.extract_objects_method})
|
||||||
|
|
||||||
def is_cross(self):
|
def is_cross(self):
|
||||||
return self.target.is_cross()
|
return self.held_object.is_cross()
|
||||||
|
|
||||||
|
def extract_objects_method(self, args, kwargs):
|
||||||
|
gobjs = self.held_object.extract_objects(args)
|
||||||
|
return GeneratedObjectsHolder(gobjs)
|
||||||
|
|
||||||
class ExecutableHolder(BuildTargetHolder):
|
class ExecutableHolder(BuildTargetHolder):
|
||||||
def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs):
|
def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs):
|
||||||
|
@ -849,7 +860,7 @@ class Interpreter():
|
||||||
if ' ' in k:
|
if ' ' in k:
|
||||||
raise InterpreterException('Env var key must not have spaces in it.')
|
raise InterpreterException('Env var key must not have spaces in it.')
|
||||||
env[k] = val
|
env[k] = val
|
||||||
t = Test(args[0], args[1].target, par, cmd_args, env)
|
t = Test(args[0], args[1].held_object, par, cmd_args, env)
|
||||||
self.build.tests.append(t)
|
self.build.tests.append(t)
|
||||||
mlog.debug('Adding test "', mlog.bold(args[0]), '".', sep='')
|
mlog.debug('Adding test "', mlog.bold(args[0]), '".', sep='')
|
||||||
|
|
||||||
|
@ -953,6 +964,8 @@ class Interpreter():
|
||||||
return args.get_value()
|
return args.get_value()
|
||||||
if isinstance(args, str):
|
if isinstance(args, str):
|
||||||
return args
|
return args
|
||||||
|
if isinstance(args, InterpreterObject):
|
||||||
|
return args
|
||||||
result = []
|
result = []
|
||||||
for a in args:
|
for a in args:
|
||||||
if isinstance(a, list):
|
if isinstance(a, list):
|
||||||
|
@ -992,7 +1005,7 @@ class Interpreter():
|
||||||
raise InvalidCode('Tried to create target "%s", but a target of that name already exists.' % name)
|
raise InvalidCode('Tried to create target "%s", but a target of that name already exists.' % name)
|
||||||
self.check_sources_exist(os.path.join(self.environment.source_dir, self.subdir), sources)
|
self.check_sources_exist(os.path.join(self.environment.source_dir, self.subdir), sources)
|
||||||
l = targetclass(name, self.subdir, is_cross, sources, objs, self.environment, kwargs)
|
l = targetclass(name, self.subdir, is_cross, sources, objs, self.environment, kwargs)
|
||||||
self.build.targets[name] = l.target
|
self.build.targets[name] = l.held_object
|
||||||
if self.environment.is_cross_build() and l.is_cross:
|
if self.environment.is_cross_build() and l.is_cross:
|
||||||
txt = ' cross build '
|
txt = ' cross build '
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
int func() {
|
||||||
|
return 42;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
int func();
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
return func() == 42 ? 0 : 1;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
project('object extraction', 'c')
|
||||||
|
|
||||||
|
lib = shared_library('somelib', 'lib.c')
|
||||||
|
obj = lib.extract_objects('lib.c')
|
||||||
|
|
||||||
|
e = executable('main', 'main.c', objects : obj)
|
||||||
|
test('extraction test', e)
|
Loading…
Reference in New Issue