aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorMartin Kelly <mkelly@xevo.com>2017-09-06 15:21:50 -0700
committerJussi Pakkanen <jpakkane@gmail.com>2017-10-31 01:04:38 +0200
commit02bea7d5bf5c98c586e59e60357fc5ca11826172 (patch)
tree45657b5848ce1a30ff30451dc360e3ba3f39ee0a /mesonbuild
parent68af8449d8576e27fb0390340f149f3001e8ea5f (diff)
downloadmeson-02bea7d5bf5c98c586e59e60357fc5ca11826172.zip
meson-02bea7d5bf5c98c586e59e60357fc5ca11826172.tar.gz
meson-02bea7d5bf5c98c586e59e60357fc5ca11826172.tar.bz2
namespace run_targets by subproject
Currently, run_target does not get namespaced for each subproject, unlike executable and others. This means that two subprojects sharing the same run_target name cause meson to crash. Fix this by moving the subproject namespacing logic from the BuildTarget class to the Target class.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/backend/ninjabackend.py13
-rw-r--r--mesonbuild/build.py35
-rw-r--r--mesonbuild/interpreter.py17
-rw-r--r--mesonbuild/modules/__init__.py20
-rw-r--r--mesonbuild/modules/gnome.py26
-rw-r--r--mesonbuild/modules/i18n.py8
-rw-r--r--mesonbuild/modules/qt.py2
7 files changed, 62 insertions, 59 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index bb281e1..c633daf 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -534,7 +534,7 @@ int dummy;
elem.add_item('COMMAND', cmd)
elem.add_item('description', desc.format(target.name, cmd_type))
elem.write(outfile)
- self.processed_targets[target.name + target.type_suffix()] = True
+ self.processed_targets[target.get_id()] = True
def generate_run_target(self, target, outfile):
cmd = self.environment.get_build_command() + ['--internal', 'commandrunner']
@@ -552,7 +552,12 @@ int dummy;
arg_strings.append(os.path.join(self.environment.get_build_dir(), relfname))
else:
raise AssertionError('Unreachable code in generate_run_target: ' + str(i))
- elem = NinjaBuildElement(self.all_outputs, 'meson-' + target.name, 'CUSTOM_COMMAND', [])
+ if target.subproject != '':
+ subproject_prefix = '{}@@'.format(target.subproject)
+ else:
+ subproject_prefix = ''
+ target_name = 'meson-{}{}'.format(subproject_prefix, target.name)
+ elem = NinjaBuildElement(self.all_outputs, target_name, 'CUSTOM_COMMAND', [])
cmd += [self.environment.get_source_dir(),
self.environment.get_build_dir(),
target.subdir] + self.environment.get_build_command()
@@ -588,8 +593,8 @@ int dummy;
elem.add_item('pool', 'console')
elem.write(outfile)
# Alias that runs the target defined above with the name the user specified
- self.create_target_alias('meson-' + target.name, outfile)
- self.processed_targets[target.name + target.type_suffix()] = True
+ self.create_target_alias(target_name, outfile)
+ self.processed_targets[target.get_id()] = True
def generate_coverage_rules(self, outfile):
e = NinjaBuildElement(self.all_outputs, 'meson-coverage', 'CUSTOM_COMMAND', 'PHONY')
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 2840f29..12f4bdb 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -279,7 +279,7 @@ class EnvironmentVariables:
return env
class Target:
- def __init__(self, name, subdir, build_by_default):
+ def __init__(self, name, subdir, subproject, build_by_default):
if '/' in name or '\\' in name:
# Fix failing test 53 when this becomes an error.
mlog.warning('''Target "%s" has a path separator in its name.
@@ -287,6 +287,7 @@ This is not supported, it can cause unexpected failures and will become
a hard error in the future.''' % name)
self.name = name
self.subdir = subdir
+ self.subproject = subproject
self.build_by_default = build_by_default
self.install = False
self.build_always = False
@@ -298,6 +299,15 @@ a hard error in the future.''' % name)
def get_subdir(self):
return self.subdir
+ def get_id(self):
+ # This ID must also be a valid file name on all OSs.
+ # It should also avoid shell metacharacters for obvious
+ # reasons.
+ base = self.name + self.type_suffix()
+ if self.subproject == '':
+ return base
+ return self.subproject + '@@' + base
+
def process_kwargs(self, kwargs):
if 'build_by_default' in kwargs:
self.build_by_default = kwargs['build_by_default']
@@ -320,8 +330,7 @@ a hard error in the future.''' % name)
class BuildTarget(Target):
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
- super().__init__(name, subdir, True)
- self.subproject = subproject # Can not be calculated from subdir as subproject dirname can be changed per project.
+ super().__init__(name, subdir, subproject, True)
self.is_cross = is_cross
unity_opt = environment.coredata.get_builtin_option('unity')
self.is_unity = unity_opt == 'on' or (unity_opt == 'subprojects' and subproject != '')
@@ -374,15 +383,6 @@ class BuildTarget(Target):
if environment.is_cross_build() and not self.is_cross and self.install:
raise InvalidArguments('Tried to install a natively built target in a cross build.')
- def get_id(self):
- # This ID must also be a valid file name on all OSs.
- # It should also avoid shell metacharacters for obvious
- # reasons.
- base = self.name + self.type_suffix()
- if self.subproject == '':
- return base
- return self.subproject + '@@' + base
-
def check_unknown_kwargs(self, kwargs):
# Override this method in derived classes that have more
# keywords.
@@ -1511,8 +1511,8 @@ class CustomTarget(Target):
'override_options': True,
}
- def __init__(self, name, subdir, kwargs, absolute_paths=False):
- super().__init__(name, subdir, False)
+ def __init__(self, name, subdir, subproject, kwargs, absolute_paths=False):
+ super().__init__(name, subdir, subproject, False)
self.dependencies = []
self.extra_depends = []
self.depend_files = [] # Files that this target depends on but are not on the command line.
@@ -1689,8 +1689,8 @@ class CustomTarget(Target):
raise NotImplementedError
class RunTarget(Target):
- def __init__(self, name, command, args, dependencies, subdir):
- super().__init__(name, subdir, False)
+ def __init__(self, name, command, args, dependencies, subdir, subproject):
+ super().__init__(name, subdir, subproject, False)
self.command = command
self.args = args
self.dependencies = dependencies
@@ -1702,9 +1702,6 @@ class RunTarget(Target):
repr_str = "<{0} {1}: {2}>"
return repr_str.format(self.__class__.__name__, self.get_id(), self.command)
- def get_id(self):
- return self.name + self.type_suffix()
-
def get_dependencies(self):
return self.dependencies
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index dd23070..b25aecd 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -606,9 +606,9 @@ class CustomTargetHolder(TargetHolder):
raise InterpreterException('Cannot delete a member of a CustomTarget')
class RunTargetHolder(InterpreterObject, ObjectHolder):
- def __init__(self, name, command, args, dependencies, subdir):
+ def __init__(self, name, command, args, dependencies, subdir, subproject):
InterpreterObject.__init__(self)
- ObjectHolder.__init__(self, build.RunTarget(name, command, args, dependencies, subdir))
+ ObjectHolder.__init__(self, build.RunTarget(name, command, args, dependencies, subdir, subproject))
def __repr__(self):
r = '<{} {}: {}>'
@@ -1060,10 +1060,10 @@ class CompilerHolder(InterpreterObject):
return []
ModuleState = namedtuple('ModuleState', [
- 'build_to_src', 'subdir', 'current_lineno', 'environment', 'project_name',
- 'project_version', 'backend', 'compilers', 'targets', 'data', 'headers',
- 'man', 'global_args', 'project_args', 'build_machine', 'host_machine',
- 'target_machine'])
+ 'build_to_src', 'subproject', 'subdir', 'current_lineno', 'environment',
+ 'project_name', 'project_version', 'backend', 'compilers', 'targets',
+ 'data', 'headers', 'man', 'global_args', 'project_args', 'build_machine',
+ 'host_machine', 'target_machine'])
class ModuleHolder(InterpreterObject, ObjectHolder):
def __init__(self, modname, module, interpreter):
@@ -1085,6 +1085,7 @@ class ModuleHolder(InterpreterObject, ObjectHolder):
state = ModuleState(
build_to_src=os.path.relpath(self.interpreter.environment.get_source_dir(),
self.interpreter.environment.get_build_dir()),
+ subproject=self.interpreter.subproject,
subdir=self.interpreter.subdir,
current_lineno=self.interpreter.current_lineno,
environment=self.interpreter.environment,
@@ -2303,7 +2304,7 @@ to directly access options of other subprojects.''')
if len(args) != 1:
raise InterpreterException('custom_target: Only one positional argument is allowed, and it must be a string name')
name = args[0]
- tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, kwargs), self)
+ tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, self.subproject, kwargs), self)
self.add_target(name, tg.held_object)
return tg
@@ -2346,7 +2347,7 @@ to directly access options of other subprojects.''')
cleaned_deps.append(d)
command = cleaned_args[0]
cmd_args = cleaned_args[1:]
- tg = RunTargetHolder(name, command, cmd_args, cleaned_deps, self.subdir)
+ tg = RunTargetHolder(name, command, cmd_args, cleaned_deps, self.subdir, self.subproject)
self.add_target(name, tg.held_object)
return tg
diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py
index 364bc45..bf513fd 100644
--- a/mesonbuild/modules/__init__.py
+++ b/mesonbuild/modules/__init__.py
@@ -78,21 +78,21 @@ class ModuleReturnValue:
self.new_objects = new_objects
class GResourceTarget(build.CustomTarget):
- def __init__(self, name, subdir, kwargs):
- super().__init__(name, subdir, kwargs)
+ def __init__(self, name, subdir, subproject, kwargs):
+ super().__init__(name, subdir, subproject, kwargs)
class GResourceHeaderTarget(build.CustomTarget):
- def __init__(self, name, subdir, kwargs):
- super().__init__(name, subdir, kwargs)
+ def __init__(self, name, subdir, subproject, kwargs):
+ super().__init__(name, subdir, subproject, kwargs)
class GirTarget(build.CustomTarget):
- def __init__(self, name, subdir, kwargs):
- super().__init__(name, subdir, kwargs)
+ def __init__(self, name, subdir, subproject, kwargs):
+ super().__init__(name, subdir, subproject, kwargs)
class TypelibTarget(build.CustomTarget):
- def __init__(self, name, subdir, kwargs):
- super().__init__(name, subdir, kwargs)
+ def __init__(self, name, subdir, subproject, kwargs):
+ super().__init__(name, subdir, subproject, kwargs)
class VapiTarget(build.CustomTarget):
- def __init__(self, name, subdir, kwargs):
- super().__init__(name, subdir, kwargs)
+ def __init__(self, name, subdir, subproject, kwargs):
+ super().__init__(name, subdir, subproject, kwargs)
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 01604f2..4d20cc1 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -192,7 +192,7 @@ class GnomeModule(ExtensionModule):
depfile = kwargs['output'] + '.d'
kwargs['depfile'] = depfile
kwargs['command'] = copy.copy(cmd) + ['--dependency-file', '@DEPFILE@']
- target_c = GResourceTarget(name, state.subdir, kwargs)
+ target_c = GResourceTarget(name, state.subdir, state.subproject, kwargs)
if gresource: # Only one target for .gresource files
return ModuleReturnValue(target_c, [target_c])
@@ -210,7 +210,7 @@ class GnomeModule(ExtensionModule):
h_kwargs['install'] = install_header
h_kwargs['install_dir'] = kwargs.get('install_dir',
state.environment.coredata.get_builtin_option('includedir'))
- target_h = GResourceHeaderTarget(args[0] + '_h', state.subdir, h_kwargs)
+ target_h = GResourceHeaderTarget(args[0] + '_h', state.subdir, state.subproject, h_kwargs)
rv = [target_c, target_h]
return ModuleReturnValue(rv, rv)
@@ -612,7 +612,7 @@ class GnomeModule(ExtensionModule):
os.path.join(state.environment.get_datadir(), 'gir-1.0'))
if 'build_by_default' in kwargs:
scankwargs['build_by_default'] = kwargs['build_by_default']
- scan_target = GirTarget(girfile, state.subdir, scankwargs)
+ scan_target = GirTarget(girfile, state.subdir, state.subproject, scankwargs)
typelib_output = '%s-%s.typelib' % (ns, nsversion)
typelib_cmd = [gicompiler, scan_target, '--output', '@OUTPUT@']
@@ -630,7 +630,7 @@ class GnomeModule(ExtensionModule):
os.path.join(state.environment.get_libdir(), 'girepository-1.0'))
if 'build_by_default' in kwargs:
typelib_kwargs['build_by_default'] = kwargs['build_by_default']
- typelib_target = TypelibTarget(typelib_output, state.subdir, typelib_kwargs)
+ typelib_target = TypelibTarget(typelib_output, state.subdir, state.subproject, typelib_kwargs)
rv = [scan_target, typelib_target]
return ModuleReturnValue(rv, rv)
@@ -650,7 +650,7 @@ class GnomeModule(ExtensionModule):
targetname = 'gsettings-compile'
else:
targetname = 'gsettings-compile-' + state.subdir.replace('/', '_')
- target_g = build.CustomTarget(targetname, state.subdir, kwargs)
+ target_g = build.CustomTarget(targetname, state.subdir, state.subproject, kwargs)
return ModuleReturnValue(target_g, [target_g])
@permittedKwargs({'sources', 'media', 'symlink_media', 'languages'})
@@ -705,7 +705,7 @@ This will become a hard error in the future.''')
'--sources=' + source_str,
]
pottarget = build.RunTarget('help-' + project_id + '-pot', potargs[0],
- potargs[1:], [], state.subdir)
+ potargs[1:], [], state.subdir, state.subproject)
poargs = state.environment.get_build_command() + [
'--internal', 'yelphelper', 'update-po',
@@ -715,7 +715,7 @@ This will become a hard error in the future.''')
'--langs=' + '@@'.join(langs),
]
potarget = build.RunTarget('help-' + project_id + '-update-po', poargs[0],
- poargs[1:], [], state.subdir)
+ poargs[1:], [], state.subdir, state.subproject)
rv = [inscript, pottarget, potarget]
return ModuleReturnValue(None, rv)
@@ -788,7 +788,7 @@ This will become a hard error in the future.''')
args += self._unpack_args('--ignore-headers=', 'ignore_headers', kwargs)
args += self._unpack_args('--installdir=', 'install_dir', kwargs, state)
args += self._get_build_args(kwargs, state)
- res = [build.RunTarget(targetname, command[0], command[1:] + args, [], state.subdir)]
+ res = [build.RunTarget(targetname, command[0], command[1:] + args, [], state.subdir, state.subproject)]
if kwargs.get('install', True):
res.append(build.RunScript(command, args))
return ModuleReturnValue(None, res)
@@ -885,7 +885,7 @@ This will become a hard error in the future.''')
}
if 'build_by_default' in kwargs:
custom_kwargs['build_by_default'] = kwargs['build_by_default']
- ct = build.CustomTarget(target_name, state.subdir, custom_kwargs)
+ ct = build.CustomTarget(target_name, state.subdir, state.subproject, custom_kwargs)
return ModuleReturnValue(ct, [ct])
@permittedKwargs({'sources', 'c_template', 'h_template', 'install_header', 'install_dir',
@@ -1101,7 +1101,7 @@ G_END_DECLS'''
'command': cmd
}
custom_kwargs.update(kwargs)
- return build.CustomTarget(output, state.subdir, custom_kwargs,
+ return build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs,
# https://github.com/mesonbuild/meson/issues/973
absolute_paths=True)
@@ -1171,7 +1171,7 @@ G_END_DECLS'''
# Silence any warnings about missing prototypes
custom_kwargs['command'] += ['--include-header', header_file]
custom_kwargs['output'] = output + '.c'
- body = build.CustomTarget(output + '_c', state.subdir, custom_kwargs)
+ body = build.CustomTarget(output + '_c', state.subdir, state.subproject, custom_kwargs)
custom_kwargs['install'] = install_header
if install_dir is not None:
@@ -1180,7 +1180,7 @@ G_END_DECLS'''
cmd += ['--pragma-once']
custom_kwargs['command'] = cmd + ['--header', '@INPUT@']
custom_kwargs['output'] = header_file
- header = build.CustomTarget(output + '_h', state.subdir, custom_kwargs)
+ header = build.CustomTarget(output + '_h', state.subdir, state.subproject, custom_kwargs)
rv = [body, header]
return ModuleReturnValue(rv, rv)
@@ -1316,7 +1316,7 @@ G_END_DECLS'''
# We shouldn't need this locally but we install it
deps_target = self._generate_deps(state, library, vapi_packages, install_dir)
created_values.append(deps_target)
- vapi_target = VapiTarget(vapi_output, state.subdir, custom_kwargs)
+ vapi_target = VapiTarget(vapi_output, state.subdir, state.subproject, custom_kwargs)
# So to try our best to get this to just work we need:
# - link with with the correct library
diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py
index c1dd837..6c02fbb 100644
--- a/mesonbuild/modules/i18n.py
+++ b/mesonbuild/modules/i18n.py
@@ -79,7 +79,7 @@ class I18nModule(ExtensionModule):
command.append(datadirs)
kwargs['command'] = command
- ct = build.CustomTarget(kwargs['output'] + '_merge', state.subdir, kwargs)
+ ct = build.CustomTarget(kwargs['output'] + '_merge', state.subdir, state.subproject, kwargs)
return ModuleReturnValue(ct, [ct])
@permittedKwargs({'po_dir', 'data_dirs', 'type', 'languages', 'args', 'preset', 'install'})
@@ -111,12 +111,12 @@ class I18nModule(ExtensionModule):
potargs.append(datadirs)
if extra_args:
potargs.append(extra_args)
- pottarget = build.RunTarget(packagename + '-pot', potargs[0], potargs[1:], [], state.subdir)
+ pottarget = build.RunTarget(packagename + '-pot', potargs[0], potargs[1:], [], state.subdir, state.subproject)
gmoargs = state.environment.get_build_command() + ['--internal', 'gettext', 'gen_gmo']
if lang_arg:
gmoargs.append(lang_arg)
- gmotarget = build.RunTarget(packagename + '-gmo', gmoargs[0], gmoargs[1:], [], state.subdir)
+ gmotarget = build.RunTarget(packagename + '-gmo', gmoargs[0], gmoargs[1:], [], state.subdir, state.subproject)
updatepoargs = state.environment.get_build_command() + ['--internal', 'gettext', 'update_po', pkg_arg]
if lang_arg:
@@ -125,7 +125,7 @@ class I18nModule(ExtensionModule):
updatepoargs.append(datadirs)
if extra_args:
updatepoargs.append(extra_args)
- updatepotarget = build.RunTarget(packagename + '-update-po', updatepoargs[0], updatepoargs[1:], [], state.subdir)
+ updatepotarget = build.RunTarget(packagename + '-update-po', updatepoargs[0], updatepoargs[1:], [], state.subdir, state.subproject)
targets = [pottarget, gmotarget, updatepotarget]
diff --git a/mesonbuild/modules/qt.py b/mesonbuild/modules/qt.py
index 0b7354f..5800e5c 100644
--- a/mesonbuild/modules/qt.py
+++ b/mesonbuild/modules/qt.py
@@ -110,7 +110,7 @@ class QtBaseModule:
'output': name + '.cpp',
'command': [self.rcc, '-o', '@OUTPUT@', '@INPUT@'],
'depend_files': qrc_deps}
- res_target = build.CustomTarget(name, state.subdir, rcc_kwargs)
+ res_target = build.CustomTarget(name, state.subdir, state.subproject, rcc_kwargs)
sources.append(res_target)
if len(ui_files) > 0:
if not self.uic.found():