diff options
author | Martin Kelly <mkelly@xevo.com> | 2017-09-06 15:21:50 -0700 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2017-10-31 01:04:38 +0200 |
commit | 02bea7d5bf5c98c586e59e60357fc5ca11826172 (patch) | |
tree | 45657b5848ce1a30ff30451dc360e3ba3f39ee0a /mesonbuild | |
parent | 68af8449d8576e27fb0390340f149f3001e8ea5f (diff) | |
download | meson-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.py | 13 | ||||
-rw-r--r-- | mesonbuild/build.py | 35 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 17 | ||||
-rw-r--r-- | mesonbuild/modules/__init__.py | 20 | ||||
-rw-r--r-- | mesonbuild/modules/gnome.py | 26 | ||||
-rw-r--r-- | mesonbuild/modules/i18n.py | 8 | ||||
-rw-r--r-- | mesonbuild/modules/qt.py | 2 |
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(): |