aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2013-11-05 01:47:09 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2013-11-05 01:47:09 +0200
commit8f5d93b4d4a1b2eaca8ed42162506e1a5e326666 (patch)
tree668bf87538450e6f14fea55682bc57a2032fc0e8
parent337b14e6029d9a68398b5170ebd992f59e5aeeb0 (diff)
downloadmeson-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.py13
-rw-r--r--build.py55
-rw-r--r--interpreter.py23
-rw-r--r--test cases/common/25 object extraction/lib.c3
-rw-r--r--test cases/common/25 object extraction/main.c5
-rw-r--r--test cases/common/25 object extraction/meson.build7
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()
diff --git a/build.py b/build.py
index 4ce6b03..932733b 100644
--- a/build.py
+++ b/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'):
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)