@ -23,7 +23,7 @@ from . import compilers
from . wrap import wrap , WrapMode
from . import mesonlib
from . mesonlib import FileMode , Popen_safe , get_meson_script
from . dependencies import InternalDependency , Dependency
from . dependencies import InternalDependency , Dependency , ExternalProgram
from . interpreterbase import InterpreterBase
from . interpreterbase import check_stringlist , noPosargs , noKwargs , stringArgs
from . interpreterbase import InterpreterException , InvalidArguments , InvalidCode
@ -72,17 +72,19 @@ class TryRunResultHolder(InterpreterObject):
class RunProcess ( InterpreterObject ) :
def __init__ ( self , command_array , source_dir , build_dir , subdir , mesonintrospect , in_builddir = False ) :
def __init__ ( self , cmd , args , source_dir , build_dir , subdir , mesonintrospect , in_builddir = False ) :
super ( ) . __init__ ( )
pc , self . stdout , self . stderr = self . run_command ( command_array , source_dir , build_dir , subdir , mesonintrospect , in_builddir )
if not isinstance ( cmd , ExternalProgram ) :
raise AssertionError ( ' BUG: RunProcess must be passed an ExternalProgram ' )
pc , self . stdout , self . stderr = self . run_command ( cmd , args , source_dir , build_dir , subdir , mesonintrospect , in_builddir )
self . returncode = pc . returncode
self . methods . update ( { ' returncode ' : self . returncode_method ,
' stdout ' : self . stdout_method ,
' stderr ' : self . stderr_method ,
} )
def run_command ( self , command_array , source_dir , build_dir , subdir , mesonintrospect , in_builddir ) :
cmd_name = command_array [ 0 ]
def run_command ( self , cmd , args , source_dir , build_dir , subdir , mesonintrospect , in_builddir ) :
command_array = cmd . get_command ( ) + args
env = { ' MESON_SOURCE_ROOT ' : source_dir ,
' MESON_BUILD_ROOT ' : build_dir ,
' MESON_SUBDIR ' : subdir ,
@ -94,18 +96,6 @@ class RunProcess(InterpreterObject):
child_env = os . environ . copy ( )
child_env . update ( env )
mlog . debug ( ' Running command: ' , ' ' . join ( command_array ) )
try :
return Popen_safe ( command_array , env = child_env , cwd = cwd )
except FileNotFoundError :
pass
# Was not a command, is a program in path?
exe = shutil . which ( cmd_name )
if exe is not None :
command_array = [ exe ] + command_array [ 1 : ]
return Popen_safe ( command_array , env = child_env , cwd = cwd )
# No? Maybe it is a script in the source tree.
fullpath = os . path . join ( source_dir , subdir , cmd_name )
command_array = [ fullpath ] + command_array [ 1 : ]
try :
return Popen_safe ( command_array , env = child_env , cwd = cwd )
except FileNotFoundError :
@ -250,7 +240,6 @@ class DependencyHolder(InterpreterObject):
def found_method ( self , args , kwargs ) :
if self . held_object . type_name == ' internal ' :
return True
return self . held_object . found ( )
def version_method ( self , args , kwargs ) :
@ -1105,7 +1094,8 @@ class MesonMain(InterpreterObject):
if found . found ( ) :
self . _found_source_scripts [ key ] = found
else :
raise InterpreterException ( ' Script {!r} not found ' . format ( name ) )
m = ' Script or command {!r} not found or not executable '
raise InterpreterException ( m . format ( name ) )
return build . RunScript ( found . get_command ( ) , args )
def add_install_script_method ( self , args , kwargs ) :
@ -1471,31 +1461,36 @@ class Interpreter(InterpreterBase):
cargs = args [ 1 : ]
srcdir = self . environment . get_source_dir ( )
builddir = self . environment . get_build_dir ( )
m = ' must be a string, or the output of find_program(), files(), or ' \
' configure_file(); not {!r} '
if isinstance ( cmd , ExternalProgramHolder ) :
cmd = cmd . get_command ( )
elif isinstance ( cmd , str ) :
cmd = [ cmd ]
elif isinstance ( cmd , mesonlib . File ) :
cmd = [ cmd . absolute_path ( srcdir , builddir ) ]
cmd = cmd . held_object
else :
m = ' First argument must be a string, or the output of ' \
' find_program(), files(), or configure_file(); not {!r} '
raise InterpreterException ( m . format ( cmd ) )
if isinstance ( cmd , mesonlib . File ) :
cmd = cmd . absolute_path ( srcdir , builddir )
elif not isinstance ( cmd , str ) :
raise InterpreterException ( ' First argument ' + m . format ( cmd ) )
# Prefer scripts in the current source directory
search_dir = os . path . join ( srcdir , self . subdir )
prog = ExternalProgram ( cmd , silent = True , search_dir = search_dir )
if not prog . found ( ) :
raise InterpreterException ( ' Program or command {!r} not found '
' or not executable ' . format ( cmd ) )
cmd = prog
expanded_args = [ ]
for a in mesonlib . flatten ( cargs ) :
if isinstance ( a , str ) :
expanded_args . append ( a )
elif isinstance ( a , mesonlib . File ) :
expanded_args . append ( a . absolute_path ( srcdir , builddir ) )
elif isinstance ( a , ExternalProgramHolder ) :
expanded_args . append ( a . held_object . get_path ( ) )
else :
m = ' run_command() arguments must be strings, the output of ' \
' files(), or configure_file(); not {!r} '
raise InterpreterException ( m . format ( a ) )
args = cmd + expanded_args
raise InterpreterException ( ' Arguments ' + m . format ( a ) )
in_builddir = kwargs . get ( ' in_builddir ' , False )
if not isinstance ( in_builddir , bool ) :
raise InterpreterException ( ' in_builddir must be boolean. ' )
return RunProcess ( args , srcdir , builddir , self . subdir ,
return RunProcess ( cmd , expanded_ args, srcdir , builddir , self . subdir ,
get_meson_script ( self . environment , ' mesonintrospect ' ) , in_builddir )
@stringArgs
@ -1851,7 +1846,7 @@ class Interpreter(InterpreterBase):
if progobj . found ( ) :
return progobj
if required and not progobj . found ( ) :
raise InvalidArguments ( ' Program " %s " not found. ' % exename )
raise InvalidArguments ( ' Program " %s " not found or not executable ' % exename )
return progobj
def func_find_library ( self , node , args , kwargs ) :
@ -2427,7 +2422,7 @@ different subdirectory.
exe_wrapper . append ( i )
elif isinstance ( i , dependencies . ExternalProgram ) :
if not i . found ( ) :
raise InterpreterException ( ' Tried to use non-found external ex ecutable. ' )
raise InterpreterException ( ' Tried to use non-found executable. ' )
exe_wrapper + = i . get_command ( )
else :
raise InterpreterException ( ' Exe wrapper can only contain strings or external binaries. ' )