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():
|
||||
if isinstance(obj, str):
|
||||
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:
|
||||
raise MesonException('Unknown data type in object list.')
|
||||
obj_list.append(o)
|
||||
elem = self.generate_link(target, outfile, outname, obj_list)
|
||||
self.generate_shlib_aliases(target, self.get_target_dir(target), outfile, elem)
|
||||
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):
|
||||
for t in target.get_dependencies():
|
||||
tname = t.get_basename()
|
||||
|
|
55
build.py
55
build.py
|
@ -90,6 +90,11 @@ class IncludeDirs():
|
|||
def get_incdirs(self):
|
||||
return self.incdirs
|
||||
|
||||
class ExtractedObjects():
|
||||
def __init__(self, target, srclist):
|
||||
self.target = target
|
||||
self.srclist = srclist
|
||||
|
||||
class BuildTarget():
|
||||
def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs):
|
||||
self.name = name
|
||||
|
@ -114,8 +119,12 @@ class BuildTarget():
|
|||
def process_objectlist(self, objects):
|
||||
assert(isinstance(objects, list))
|
||||
for s in objects:
|
||||
if hasattr(s, 'held_object'):
|
||||
s = s.held_object
|
||||
if isinstance(s, str):
|
||||
self.objects.append(s)
|
||||
elif isinstance(s, ExtractedObjects):
|
||||
self.objects.append(s)
|
||||
else:
|
||||
raise InvalidArguments('Bad object in target %s.' % self.name)
|
||||
|
||||
|
@ -136,22 +145,38 @@ class BuildTarget():
|
|||
def get_original_kwargs(self):
|
||||
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):
|
||||
self.kwargs = copy.copy(kwargs)
|
||||
# This sucks quite badly. Arguments
|
||||
# are holders but they can't be pickled
|
||||
# so unpack those known.
|
||||
if 'deps' in self.kwargs:
|
||||
d = self.kwargs['deps']
|
||||
if not isinstance(d, list):
|
||||
d = [d]
|
||||
newd = []
|
||||
for i in d:
|
||||
if hasattr(i, 'el'):
|
||||
newd.append(i.el)
|
||||
else:
|
||||
newd.append(i)
|
||||
self.kwargs['deps'] = newd
|
||||
self.kwargs['deps'] = self.unpack_holder(self.kwargs['deps'])
|
||||
if 'link_with' in self.kwargs:
|
||||
self.kwargs['link_with'] = self.unpack_holder(self.kwargs['link_with'])
|
||||
|
||||
def extract_objects(self, srclist):
|
||||
obj_src = []
|
||||
for src in srclist:
|
||||
if not isinstance(src, str):
|
||||
raise coredata.MesonException('Extraction arguments must be strings.')
|
||||
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):
|
||||
return self.get_transitive_rpaths()
|
||||
|
@ -172,8 +197,8 @@ class BuildTarget():
|
|||
for linktarget in llist:
|
||||
# Sorry for this hack. Keyword targets are kept in holders
|
||||
# in kwargs. Unpack here without looking at the exact type.
|
||||
if hasattr(linktarget, "target"):
|
||||
linktarget = linktarget.target
|
||||
if hasattr(linktarget, "held_object"):
|
||||
linktarget = linktarget.held_object
|
||||
self.link(linktarget)
|
||||
c_pchlist = kwargs.get('c_pch', [])
|
||||
if not isinstance(c_pchlist, list):
|
||||
|
@ -263,6 +288,8 @@ class BuildTarget():
|
|||
[self.add_external_dep(dep) for dep in args]
|
||||
|
||||
def link(self, target):
|
||||
if hasattr(target, 'held_object'):
|
||||
target = target.held_object
|
||||
if not isinstance(target, StaticLibrary) and \
|
||||
not isinstance(target, SharedLibrary):
|
||||
print(target)
|
||||
|
@ -321,8 +348,8 @@ class Generator():
|
|||
if len(args) != 1:
|
||||
raise InvalidArguments('Generator requires one and only one positional argument')
|
||||
|
||||
if hasattr(args[0], 'target'):
|
||||
exe = args[0].target
|
||||
if hasattr(args[0], 'held_object'):
|
||||
exe = args[0].held_object
|
||||
if not isinstance(exe, Executable):
|
||||
raise InvalidArguments('First generator argument must be an executable.')
|
||||
elif hasattr(args[0], 'ep'):
|
||||
|
|
|
@ -311,12 +311,23 @@ class Man(InterpreterObject):
|
|||
def get_sources(self):
|
||||
return self.sources
|
||||
|
||||
class GeneratedObjectsHolder(InterpreterObject):
|
||||
def __init__(self, held_object):
|
||||
super().__init__()
|
||||
self.held_object = held_object
|
||||
|
||||
class BuildTargetHolder(InterpreterObject):
|
||||
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):
|
||||
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):
|
||||
def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs):
|
||||
|
@ -849,7 +860,7 @@ class Interpreter():
|
|||
if ' ' in k:
|
||||
raise InterpreterException('Env var key must not have spaces in it.')
|
||||
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)
|
||||
mlog.debug('Adding test "', mlog.bold(args[0]), '".', sep='')
|
||||
|
||||
|
@ -953,6 +964,8 @@ class Interpreter():
|
|||
return args.get_value()
|
||||
if isinstance(args, str):
|
||||
return args
|
||||
if isinstance(args, InterpreterObject):
|
||||
return args
|
||||
result = []
|
||||
for a in args:
|
||||
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)
|
||||
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)
|
||||
self.build.targets[name] = l.target
|
||||
self.build.targets[name] = l.held_object
|
||||
if self.environment.is_cross_build() and l.is_cross:
|
||||
txt = ' cross build '
|
||||
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