Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions mesonbuild/backend/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ def determine_swift_dep_dirs(self, target: build.BuildTarget) -> T.List[str]:
return result

def get_executable_serialisation(
self, cmd: T.Sequence[T.Union[programs.ExternalProgram, build.BuildTarget, build.CustomTarget, File, str]],
self, cmd: T.Sequence[T.Union[programs.Program, build.BuildTarget, build.CustomTarget, build.CustomTargetIndex, File, str]],
workdir: T.Optional[str] = None,
extra_bdeps: T.Optional[T.List[build.BuildTarget]] = None,
capture: T.Optional[str] = None,
Expand All @@ -548,13 +548,15 @@ def get_executable_serialisation(

# XXX: cmd_args either need to be lowered to strings, or need to be checked for non-string arguments, right?
exe, *raw_cmd_args = cmd
if isinstance(exe, programs.ExternalProgram):
if isinstance(exe, build.LocalProgram):
exe = exe.program
if isinstance(exe, programs.Program):
exe_cmd = exe.get_command()
exe_for_machine = exe.for_machine
elif isinstance(exe, build.BuildTarget):
exe_cmd = [self.get_target_filename_abs(exe)]
exe_for_machine = exe.for_machine
elif isinstance(exe, build.CustomTarget):
elif isinstance(exe, (build.CustomTarget, build.CustomTargetIndex)):
# The output of a custom target can either be directly runnable
# or not, that is, a script, a native binary or a cross compiled
# binary when exe wrapper is available and when it is not.
Expand All @@ -571,9 +573,11 @@ def get_executable_serialisation(

cmd_args: T.List[str] = []
for c in raw_cmd_args:
if isinstance(c, programs.ExternalProgram):
if isinstance(c, build.LocalProgram):
c = c.program
if isinstance(c, programs.Program):
cmd_args += c.get_command()
elif isinstance(c, (build.BuildTarget, build.CustomTarget)):
elif isinstance(c, (build.BuildTarget, build.CustomTarget, build.CustomTargetIndex)):
cmd_args.append(self.get_target_filename_abs(c))
elif isinstance(c, mesonlib.File):
cmd_args.append(c.rel_to_builddir(self.environment.source_dir))
Expand Down Expand Up @@ -1124,7 +1128,7 @@ def extract_dll_paths(cls, target: build.BuildTarget) -> T.Set[str]:
return results

def determine_windows_extra_paths(
self, target: T.Union[build.BuildTargetTypes, programs.ExternalProgram, mesonlib.File, str],
self, target: T.Union[build.BuildTargetTypes, programs.Program, mesonlib.File, str],
extra_bdeps: T.Sequence[build.BuildTargetTypes]) -> T.List[str]:
"""On Windows there is no such thing as an rpath.

Expand Down
92 changes: 58 additions & 34 deletions mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ def __init__(self, environment: Environment):
self.stdlibs = PerMachine({}, {})
self.test_setups: T.Dict[str, TestSetup] = {}
self.test_setup_default_name = None
self.find_overrides: T.Dict[str, T.Union['OverrideExecutable', programs.ExternalProgram, programs.OverrideProgram]] = {}
self.find_overrides: T.Dict[str, programs.Program] = {}
self.searched_programs: T.Set[str] = set() # The list of all programs that have been searched for.

# If we are doing a cross build we need two caches, if we're doing a
Expand Down Expand Up @@ -1980,7 +1980,7 @@ def __str__(self) -> str:

class Generator(HoldableObject):
def __init__(self, env: Environment,
exe: T.Union['Executable', programs.ExternalProgram],
exe: T.Union[Executable, programs.Program, CustomTarget, CustomTargetIndex],
arguments: T.List[str],
output: T.List[str],
# how2dataclass
Expand All @@ -1990,10 +1990,14 @@ def __init__(self, env: Environment,
depends: T.Optional[T.List[BuildTargetTypes]] = None,
name: str = 'Generator'):
self.environment = env
self.depends = list(depends or [])
if isinstance(exe, LocalProgram):
# FIXME: Generator does not have depend_files?
self.depends.extend(exe.depends)
exe = exe.program
self.exe = exe
self.depfile = depfile
self.capture = capture
self.depends: T.List[BuildTargetTypes] = depends or []
self.arglist = arguments
self.outputs = output
self.name = name
Expand All @@ -2002,7 +2006,7 @@ def __repr__(self) -> str:
repr_str = "<{0}: {1}>"
return repr_str.format(self.__class__.__name__, self.exe)

def get_exe(self) -> T.Union['Executable', programs.ExternalProgram]:
def get_exe(self) -> T.Union[Executable, programs.ExternalProgram, CustomTarget, CustomTargetIndex]:
return self.exe

def get_base_outnames(self, inname: str) -> T.List[str]:
Expand Down Expand Up @@ -2241,10 +2245,6 @@ def post_init(self) -> None:
def get_default_install_dir(self) -> T.Union[T.Tuple[str, str], T.Tuple[None, None]]:
return self.environment.get_bindir(), '{bindir}'

def description(self):
'''Human friendly description of the executable'''
return self.name

def type_suffix(self):
return "@exe"

Expand All @@ -2267,21 +2267,6 @@ def get_debug_filename(self) -> T.Optional[str]:
def is_linkable_target(self) -> bool:
return self.is_linkwithable

def get_command(self) -> 'ImmutableListProtocol[str]':
"""Provides compatibility with ExternalProgram.

Since you can override ExternalProgram instances with Executables.
"""
return self.outputs

def get_path(self) -> str:
"""Provides compatibility with ExternalProgram."""
return os.path.join(self.subdir, self.filename)

def found(self) -> bool:
"""Provides compatibility with ExternalProgram."""
return True


class StaticLibrary(BuildTarget):
known_kwargs = known_stlib_kwargs
Expand Down Expand Up @@ -2781,11 +2766,15 @@ class CommandBase:
dependencies: T.List[T.Union[BuildTarget, 'CustomTarget']]
subproject: str

def flatten_command(self, cmd: T.Sequence[T.Union[str, File, programs.ExternalProgram, BuildTargetTypes]]) -> \
def flatten_command(self, cmd: T.Sequence[T.Union[str, File, programs.Program, BuildTargetTypes]]) -> \
T.List[T.Union[str, File, BuildTarget, CustomTarget, programs.ExternalProgram]]:
cmd = listify(cmd)
final_cmd: T.List[T.Union[str, File, BuildTarget, 'CustomTarget']] = []
for c in cmd:
if isinstance(c, LocalProgram):
self.dependencies.extend(c.depends)
self.depend_files.extend(c.depend_files)
c = c.program
if isinstance(c, str):
final_cmd.append(c)
elif isinstance(c, File):
Expand Down Expand Up @@ -2851,7 +2840,7 @@ def __init__(self,
environment: Environment,
command: T.Sequence[T.Union[
str, BuildTargetTypes, GeneratedList,
programs.ExternalProgram, File]],
programs.Program, File]],
sources: T.Sequence[T.Union[
str, File, BuildTargetTypes, ExtractedObjects,
GeneratedList, programs.ExternalProgram]],
Expand Down Expand Up @@ -3112,7 +3101,7 @@ class RunTarget(Target, CommandBase):
typename = 'run'

def __init__(self, name: str,
command: T.Sequence[T.Union[str, File, BuildTargetTypes, programs.ExternalProgram]],
command: T.Sequence[T.Union[str, File, BuildTargetTypes, programs.Program]],
dependencies: T.Sequence[AnyTargetType],
subdir: str,
subproject: str,
Expand Down Expand Up @@ -3342,17 +3331,52 @@ def get(self, name: str) -> T.Tuple[T.Union[str, int, bool], T.Optional[str]]:
def keys(self) -> T.Iterator[str]:
return self.values.keys()

class OverrideExecutable(Executable):
def __init__(self, executable: Executable, version: str):
self._executable = executable
self._version = version
class LocalProgram(programs.Program):
''' A wrapper for a program that may have build dependencies.'''
def __init__(self, program: T.Union[programs.ExternalProgram, Executable, CustomTarget, CustomTargetIndex], version: str,
depends: T.Optional[T.List[T.Union[BuildTarget, CustomTarget]]] = None,
depend_files: T.Optional[T.List[File]] = None) -> None:
super().__init__()
if isinstance(program, CustomTarget):
if len(program.outputs) != 1:
raise InvalidArguments('CustomTarget used as LocalProgram must have exactly one output.')
self.name = program.name
self.for_machine = program.for_machine
self.program = program
self.depends = list(depends or [])
self.depend_files = list(depend_files or [])
self.version = version

def __getattr__(self, name: str) -> T.Any:
_executable = object.__getattribute__(self, '_executable')
return getattr(_executable, name)
def found(self) -> bool:
return True

def get_version(self, interpreter: T.Optional[Interpreter] = None) -> str:
return self._version
return self.version

def get_command(self) -> T.List[str]:
if isinstance(self.program, (Executable, CustomTarget, CustomTargetIndex)):
# Only the backend knows the actual path to the build program.
raise MesonBugException('Cannot call get_command() on program that is a build target.')
return self.program.get_command()

def get_path(self) -> str:
if isinstance(self.program, (Executable, CustomTarget, CustomTargetIndex)):
# Only the backend knows the actual path to the build program.
raise MesonBugException('Cannot call get_path() on program that is a build target.')
return self.program.get_path()

def description(self) -> str:
if isinstance(self.program, Executable):
return self.program.name
if isinstance(self.program, (CustomTarget, CustomTargetIndex)):
return self.program.get_filename()
return self.program.description()

def run_program(self) -> T.Optional[programs.ExternalProgram]:
''' Returns an ExternalProgram if it can be run at configure time.'''
if isinstance(self.program, programs.ExternalProgram) and not self.depends:
return self.program
return None

# A bit poorly named, but this represents plain data files to copy
# during install.
Expand Down
4 changes: 1 addition & 3 deletions mesonbuild/interpreter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
'SubprojectHolder',
'DependencyHolder',
'GeneratedListHolder',
'ExternalProgramHolder',
'extract_required_kwarg',

'ArrayHolder',
Expand All @@ -34,8 +33,7 @@
from .interpreterobjects import (ExecutableHolder, BuildTargetHolder, CustomTargetHolder,
CustomTargetIndexHolder, MachineHolder, Test,
ConfigurationDataHolder, SubprojectHolder, DependencyHolder,
GeneratedListHolder, ExternalProgramHolder,
extract_required_kwarg)
GeneratedListHolder, extract_required_kwarg)

from .primitives import (
ArrayHolder,
Expand Down
Loading
Loading