cmake: Add support for add_custom_target() with a command

The command could have no output, in which case we create a dummy one.
pull/5989/head
Xavier Claessens 5 years ago committed by Daniel Mensinger
parent 6844ad374e
commit daeee32d9b
No known key found for this signature in database
GPG Key ID: 54DD94C131E277D4
  1. 14
      mesonbuild/cmake/data/run_ctgt.py
  2. 16
      mesonbuild/cmake/interpreter.py
  3. 15
      mesonbuild/cmake/traceparser.py

@ -13,13 +13,16 @@ SEPARATOR = ';;;'
parser = argparse.ArgumentParser(description='Wrapper for add_custom_command')
parser.add_argument('-d', '--directory', type=str, metavar='D', required=True, help='Working directory to cwd to')
parser.add_argument('-o', '--outputs', nargs='+', metavar='O', required=True, help='Expected output files')
parser.add_argument('-O', '--original-outputs', nargs='+', metavar='O', required=True, help='Output files expected by CMake')
parser.add_argument('commands', nargs=argparse.REMAINDER, help='A "{}" separated list of commands'.format(SEPARATOR))
parser.add_argument('-O', '--original-outputs', nargs='*', metavar='O', default=[], help='Output files expected by CMake')
parser.add_argument('commands', nargs=argparse.REMAINDER, help='A "{}" seperated list of commands'.format(SEPERATOR))
# Parse
args = parser.parse_args()
if len(args.outputs) != len(args.original_outputs):
dummy_target = None
if len(args.outputs) == 1 and len(args.original_outputs) == 0:
dummy_target = args.outputs[0]
elif len(args.outputs) != len(args.original_outputs):
print('Length of output list and original output list differ')
sys.exit(1)
@ -39,6 +42,11 @@ for i in commands:
subprocess.run(i, cwd=args.directory)
if dummy_target:
with open(dummy_target, 'a'):
os.utime(dummy_target, None)
exit(0)
# Copy outputs
zipped_outputs = zip(args.outputs, args.original_outputs)
for expected, generated in zipped_outputs:

@ -408,7 +408,10 @@ class ConverterCustomTarget:
out_counter = 0 # type: int
def __init__(self, target: CMakeGeneratorTarget):
self.name = 'custom_tgt_{}'.format(ConverterCustomTarget.tgt_counter)
self.name = target.name
if not self.name:
self.name = 'custom_tgt_{}'.format(ConverterCustomTarget.tgt_counter)
ConverterCustomTarget.tgt_counter += 1
self.original_outputs = list(target.outputs)
self.outputs = [os.path.basename(x) for x in self.original_outputs]
self.conflict_map = {}
@ -418,8 +421,6 @@ class ConverterCustomTarget:
self.inputs = []
self.depends = []
ConverterCustomTarget.tgt_counter += 1
def __repr__(self) -> str:
return '<{}: {}>'.format(self.__class__.__name__, self.outputs)
@ -729,6 +730,7 @@ class CMakeInterpreter:
for j in i.artifacts:
output_target_map[os.path.basename(j)] = i
for i in self.custom_targets:
output_target_map[_target_key(i.name)] = i
for j in i.original_outputs:
output_target_map[_generated_file_key(j)] = i
object_libs = []
@ -971,6 +973,11 @@ class CMakeInterpreter:
tgt_var = tgt.name # type: str
# If the custom target does not declare any output, create a dummy
# one that can be used as dependency.
if not tgt.outputs:
tgt.outputs = [tgt.name + '.h']
def resolve_source(x: Any) -> Any:
if isinstance(x, ConverterTarget):
if x.name not in processed:
@ -991,7 +998,8 @@ class CMakeInterpreter:
command = []
command += [id_node(run_script_var)]
command += ['-o', '@OUTPUT@']
command += ['-O'] + tgt.original_outputs
if tgt.original_outputs:
command += ['-O'] + tgt.original_outputs
command += ['-d', tgt.working_dir]
# Generate the commands. Subcommands are separated by ';;;'

@ -52,12 +52,12 @@ class CMakeTarget:
propSTR += " '{}': {}\n".format(i, self.properties[i])
return s.format(self.name, self.type, self.imported, propSTR, self.tline)
class CMakeGeneratorTarget:
def __init__(self):
class CMakeGeneratorTarget(CMakeTarget):
def __init__(self, name):
super().__init__(name, 'CUSTOM', {})
self.outputs = [] # type: List[str]
self.command = [] # type: List[List[str]]
self.working_dir = None # type: Optional[str]
self.depends = [] # type: List[str]
class CMakeTraceParser:
def __init__(self, permissive: bool = False):
@ -237,7 +237,7 @@ class CMakeTraceParser:
else:
self.targets[args[0]] = CMakeTarget(args[0], 'NORMAL', {}, tline=tline)
def _cmake_add_custom_command(self, tline: CMakeTraceLine):
def _cmake_add_custom_command(self, tline: CMakeTraceLine, name=None):
# DOC: https://cmake.org/cmake/help/latest/command/add_custom_command.html
args = list(tline.args) # Make a working copy
@ -252,7 +252,7 @@ class CMakeTraceParser:
'IMPLICIT_DEPENDS', 'WORKING_DIRECTORY', 'COMMENT', 'DEPFILE',
'JOB_POOL', 'VERBATIM', 'APPEND', 'USES_TERMINAL', 'COMMAND_EXPAND_LISTS']
target = CMakeGeneratorTarget()
target = CMakeGeneratorTarget(name)
def handle_output(key: str, target: CMakeGeneratorTarget) -> None:
target.outputs += [key]
@ -297,6 +297,8 @@ class CMakeTraceParser:
target.command = [self._guess_files(x) for x in target.command]
self.custom_targets += [target]
if name:
self.targets[name] = target
def _cmake_add_custom_target(self, tline: CMakeTraceLine):
# DOC: https://cmake.org/cmake/help/latest/command/add_custom_target.html
@ -304,7 +306,8 @@ class CMakeTraceParser:
if len(tline.args) < 1:
return self._gen_exception('add_custom_target', 'requires at least one argument', tline)
self.targets[tline.args[0]] = CMakeTarget(tline.args[0], 'CUSTOM', {}, tline=tline)
# It's pretty much the same as a custom command
self._cmake_add_custom_command(tline, tline.args[0])
def _cmake_set_property(self, tline: CMakeTraceLine) -> None:
# DOC: https://cmake.org/cmake/help/latest/command/set_property.html

Loading…
Cancel
Save