Fix introspection and make it possible to have top level targets with the same name in subprojects. Fixes #222.

This commit is contained in:
Jussi Pakkanen 2015-08-12 14:04:41 +03:00
parent e3873e89d1
commit 05d929d542
8 changed files with 45 additions and 14 deletions

View File

@ -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)

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -0,0 +1,6 @@
#include<stdio.h>
int main(int argc, char **argv) {
printf("I'm a main project bar.\n");
return 0;
}

View File

@ -0,0 +1,5 @@
project('toplevel bar', 'c')
subproject('foo')
executable('bar', 'bar.c')

View File

@ -0,0 +1,6 @@
#include<stdio.h>
int main(int argc, char **argv) {
printf("I'm a subproject bar.\n");
return 0;
}

View File

@ -0,0 +1,3 @@
project('subfoo', 'c')
executable('bar', 'bar.c')