From 05d929d542890df227584740cb33fa22334fdb4b Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Wed, 12 Aug 2015 14:04:41 +0300 Subject: Fix introspection and make it possible to have top level targets with the same name in subprojects. Fixes #222. --- build.py | 28 +++++++++++++++------- interpreter.py | 4 ++-- mesonintrospect.py | 5 ++-- ninjabackend.py | 2 +- .../90 identical target name in subproject/bar.c | 6 +++++ .../meson.build | 5 ++++ .../subprojects/foo/bar.c | 6 +++++ .../subprojects/foo/meson.build | 3 +++ 8 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 test cases/common/90 identical target name in subproject/bar.c create mode 100644 test cases/common/90 identical target name in subproject/meson.build create mode 100644 test cases/common/90 identical target name in subproject/subprojects/foo/bar.c create mode 100644 test cases/common/90 identical target name in subproject/subprojects/foo/meson.build diff --git a/build.py b/build.py index 9e3a782..80fb2ca 100644 --- a/build.py +++ b/build.py @@ -139,9 +139,10 @@ class ExtractedObjects(): self.srclist = srclist class BuildTarget(): - def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs): + def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs): self.name = name self.subdir = subdir + self.subproject = subproject # Can not be calculated from subdir as subproject dirname can be changed per project. self.is_cross = is_cross self.sources = [] self.objects = [] @@ -165,6 +166,9 @@ class BuildTarget(): raise InvalidArguments('Build target %s has no sources.' % name) self.validate_sources() + def get_id(self): + return self.subproject + ':' + self.name + self.type_suffix() + def check_unknown_kwargs(self, kwargs): # Override this method in derived classes that have more # keywords. @@ -578,8 +582,8 @@ class GeneratedList(): return self.generator class Executable(BuildTarget): - def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs): - super().__init__(name, subdir, is_cross, sources, objects, environment, kwargs) + def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs): + super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs) self.prefix = '' self.suffix = environment.get_exe_suffix() suffix = environment.get_exe_suffix() @@ -594,8 +598,8 @@ class Executable(BuildTarget): return "@exe" class StaticLibrary(BuildTarget): - def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs): - super().__init__(name, subdir, is_cross, sources, objects, environment, kwargs) + def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs): + super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs) if len(self.sources) > 0 and self.sources[0].endswith('.cs'): raise InvalidArguments('Static libraries not supported for C#.') self.prefix = environment.get_static_lib_prefix() @@ -612,10 +616,10 @@ class StaticLibrary(BuildTarget): return "@sta" class SharedLibrary(BuildTarget): - def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs): + def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs): self.version = None self.soversion = None - super().__init__(name, subdir, is_cross, sources, objects, environment, kwargs); + super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs); if len(self.sources) > 0 and self.sources[0].endswith('.cs'): self.suffix = 'dll' self.prefix = 'lib' @@ -704,6 +708,9 @@ class CustomTarget: mlog.log(mlog.bold('Warning:'), 'Unknown keyword arguments in target %s: %s' % (self.name, ', '.join(unknowns))) + def get_id(self): + return self.name + self.type_suffix() + def process_kwargs(self, kwargs): self.sources = kwargs.get('input', []) if not isinstance(self.sources, list): @@ -811,6 +818,9 @@ class RunTarget: self.args = args self.subdir = subdir + def get_id(self): + return self.name + self.type_suffix() + def get_basename(self): return self.name @@ -836,8 +846,8 @@ class RunTarget: return "@run" class Jar(BuildTarget): - def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs): - super().__init__(name, subdir, is_cross, sources, objects, environment, kwargs); + def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs): + super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs); for s in self.sources: if not s.endswith('.java'): raise InvalidArguments('Jar source %s is not a java file.' % s) diff --git a/interpreter.py b/interpreter.py index b368d80..78cbf86 100644 --- a/interpreter.py +++ b/interpreter.py @@ -1663,7 +1663,7 @@ class Interpreter(): % name) # To permit an executable and a shared library to have the # same name, such as "foo.exe" and "libfoo.a". - idname = name + tobj.type_suffix() + idname = tobj.get_id() if idname in self.build.targets: raise InvalidCode('Tried to create target "%s", but a target of that name already exists.' % name) self.build.targets[idname] = tobj @@ -1704,7 +1704,7 @@ class Interpreter(): else: mlog.debug('Unknown target type:', str(targetholder)) raise RuntimeError('Unreachable code') - target = targetclass(name, self.subdir, is_cross, sources, objs, self.environment, kwargs) + target = targetclass(name, self.subdir, self.subproject, is_cross, sources, objs, self.environment, kwargs) l = targetholder(target) self.add_target(name, l.held_object) self.global_args_frozen = True diff --git a/mesonintrospect.py b/mesonintrospect.py index 5ddc7f5..1c0c7b0 100755 --- a/mesonintrospect.py +++ b/mesonintrospect.py @@ -41,9 +41,10 @@ parser.add_argument('args', nargs='+') def list_targets(coredata, builddata): tlist = [] - for target in builddata.get_targets().values(): + for (idname, target) in builddata.get_targets().items(): t = {} t['name'] = target.get_basename() + t['id'] = idname fname = target.get_filename() if isinstance(fname, list): fname = [os.path.join(target.subdir, x) for x in fname] @@ -78,7 +79,7 @@ def list_target_files(target_name, coredata, builddata): except KeyError: print("Unknown target %s." % target_name) sys.exit(1) - sources = [os.path.join(subdir, i) for i in sources] + sources = [os.path.join(i.subdir, i.fname) for i in sources] print(json.dumps(sources)) def list_buildoptions(coredata, builddata): diff --git a/ninjabackend.py b/ninjabackend.py index 1aea454..7364f87 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -162,7 +162,7 @@ class NinjaBackend(backends.Backend): self.generate_custom_target(target, outfile) if isinstance(target, build.RunTarget): self.generate_run_target(target, outfile) - name = target.get_basename() + target.type_suffix() + name = target.get_id() gen_src_deps = [] if name in self.processed_targets: return diff --git a/test cases/common/90 identical target name in subproject/bar.c b/test cases/common/90 identical target name in subproject/bar.c new file mode 100644 index 0000000..864869b --- /dev/null +++ b/test cases/common/90 identical target name in subproject/bar.c @@ -0,0 +1,6 @@ +#include + +int main(int argc, char **argv) { + printf("I'm a main project bar.\n"); + return 0; +} diff --git a/test cases/common/90 identical target name in subproject/meson.build b/test cases/common/90 identical target name in subproject/meson.build new file mode 100644 index 0000000..ddb5caf --- /dev/null +++ b/test cases/common/90 identical target name in subproject/meson.build @@ -0,0 +1,5 @@ +project('toplevel bar', 'c') + +subproject('foo') + +executable('bar', 'bar.c') diff --git a/test cases/common/90 identical target name in subproject/subprojects/foo/bar.c b/test cases/common/90 identical target name in subproject/subprojects/foo/bar.c new file mode 100644 index 0000000..106005e --- /dev/null +++ b/test cases/common/90 identical target name in subproject/subprojects/foo/bar.c @@ -0,0 +1,6 @@ +#include + +int main(int argc, char **argv) { + printf("I'm a subproject bar.\n"); + return 0; +} diff --git a/test cases/common/90 identical target name in subproject/subprojects/foo/meson.build b/test cases/common/90 identical target name in subproject/subprojects/foo/meson.build new file mode 100644 index 0000000..03dd9f3 --- /dev/null +++ b/test cases/common/90 identical target name in subproject/subprojects/foo/meson.build @@ -0,0 +1,3 @@ +project('subfoo', 'c') + +executable('bar', 'bar.c') -- cgit v1.1