diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2013-11-05 01:47:09 +0200 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2013-11-05 01:47:09 +0200 |
commit | 8f5d93b4d4a1b2eaca8ed42162506e1a5e326666 (patch) | |
tree | 668bf87538450e6f14fea55682bc57a2032fc0e8 | |
parent | 337b14e6029d9a68398b5170ebd992f59e5aeeb0 (diff) | |
download | meson-8f5d93b4d4a1b2eaca8ed42162506e1a5e326666.zip meson-8f5d93b4d4a1b2eaca8ed42162506e1a5e326666.tar.gz meson-8f5d93b4d4a1b2eaca8ed42162506e1a5e326666.tar.bz2 |
Can extract objects from targets and use them in other targets.
-rw-r--r-- | backends.py | 13 | ||||
-rw-r--r-- | build.py | 55 | ||||
-rw-r--r-- | interpreter.py | 23 | ||||
-rw-r--r-- | test cases/common/25 object extraction/lib.c | 3 | ||||
-rw-r--r-- | test cases/common/25 object extraction/main.c | 5 | ||||
-rw-r--r-- | test cases/common/25 object extraction/meson.build | 7 |
6 files changed, 86 insertions, 20 deletions
diff --git a/backends.py b/backends.py index 989b658..10c48ed 100644 --- a/backends.py +++ b/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() @@ -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'): diff --git a/interpreter.py b/interpreter.py index a754cdb..6f7d3d3 100644 --- a/interpreter.py +++ b/interpreter.py @@ -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: diff --git a/test cases/common/25 object extraction/lib.c b/test cases/common/25 object extraction/lib.c new file mode 100644 index 0000000..652f4eb --- /dev/null +++ b/test cases/common/25 object extraction/lib.c @@ -0,0 +1,3 @@ +int func() { + return 42; +} diff --git a/test cases/common/25 object extraction/main.c b/test cases/common/25 object extraction/main.c new file mode 100644 index 0000000..394f139 --- /dev/null +++ b/test cases/common/25 object extraction/main.c @@ -0,0 +1,5 @@ +int func(); + +int main(int argc, char **argv) { + return func() == 42 ? 0 : 1; +} diff --git a/test cases/common/25 object extraction/meson.build b/test cases/common/25 object extraction/meson.build new file mode 100644 index 0000000..a039a8c --- /dev/null +++ b/test cases/common/25 object extraction/meson.build @@ -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) |