2222
2323from  contextlib  import  redirect_stdout 
2424import  collections 
25+ import  dataclasses 
2526import  json 
2627import  os 
2728from  pathlib  import  Path , PurePath 
3132from  . import  build , mesonlib , coredata  as  cdata 
3233from  .ast  import  IntrospectionInterpreter , BUILD_TARGET_FUNCTIONS , AstConditionLevel , AstIDGenerator , AstIndentationGenerator , AstJSONPrinter 
3334from  .backend  import  backends 
35+ from  .dependencies  import  Dependency 
36+ from  . import  environment 
37+ from  .interpreterbase  import  ObjectHolder 
3438from  .mesonlib  import  OptionKey 
3539from  .mparser  import  FunctionNode , ArrayNode , ArgumentNode , StringNode 
3640
@@ -76,10 +80,12 @@ def get_meson_introspection_types(coredata: T.Optional[cdata.CoreData] = None,
7680        ('benchmarks' , IntroCommand ('List all benchmarks' , func = lambda : list_benchmarks (benchmarkdata ))),
7781        ('buildoptions' , IntroCommand ('List all build options' , func = lambda : list_buildoptions (coredata ), no_bd = list_buildoptions_from_source )),
7882        ('buildsystem_files' , IntroCommand ('List files that make up the build system' , func = lambda : list_buildsystem_files (builddata , interpreter ))),
79-         ('dependencies' , IntroCommand ('List external dependencies' , func = lambda : list_deps (coredata ), no_bd = list_deps_from_source )),
83+         ('compilers' , IntroCommand ('List used compilers' , func = lambda : list_compilers (coredata ))),
84+         ('dependencies' , IntroCommand ('List external dependencies' , func = lambda : list_deps (coredata , backend ), no_bd = list_deps_from_source )),
8085        ('scan_dependencies' , IntroCommand ('Scan for dependencies used in the meson.build file' , no_bd = list_deps_from_source )),
8186        ('installed' , IntroCommand ('List all installed files and directories' , func = lambda : list_installed (installdata ))),
8287        ('install_plan' , IntroCommand ('List all installed files and directories with their details' , func = lambda : list_install_plan (installdata ))),
88+         ('machines' , IntroCommand ('Information about host, build, and target machines' , func = lambda : list_machines (builddata ))),
8389        ('projectinfo' , IntroCommand ('Information about projects' , func = lambda : list_projinfo (builddata ), no_bd = list_projinfo_from_source )),
8490        ('targets' , IntroCommand ('List top level targets' , func = lambda : list_targets (builddata , installdata , backend ), no_bd = list_targets_from_source )),
8591        ('tests' , IntroCommand ('List all unit tests' , func = lambda : list_tests (testdata ))),
@@ -250,14 +256,22 @@ def list_targets(builddata: build.Build, installdata: backends.InstallData, back
250256            'name' : target .get_basename (),
251257            'id' : idname ,
252258            'type' : target .get_typename (),
253-             'defined_in' : os .path .normpath (os .path .join (src_dir , target .subdir , 'meson.build' )),
259+             'defined_in' : os .path .normpath (os .path .join (src_dir , target .subdir , environment . build_filename )),
254260            'filename' : [os .path .join (build_dir , outdir , x ) for  x  in  target .get_outputs ()],
255261            'build_by_default' : target .build_by_default ,
256262            'target_sources' : backend .get_introspection_data (idname , target ),
257263            'extra_files' : [os .path .normpath (os .path .join (src_dir , x .subdir , x .fname )) for  x  in  target .extra_files ],
258-             'subproject' : target .subproject  or  None 
264+             'subproject' : target .subproject  or  None ,
265+             'dependencies' : [d .name  for  d  in  getattr (target , 'external_deps' , [])],
259266        }
260267
268+         vs_module_defs  =  getattr (target , 'vs_module_defs' , None )
269+         if  vs_module_defs  is  not   None :
270+             t ['vs_module_defs' ] =  vs_module_defs .relative_name ()
271+         win_subsystem  =  getattr (target , 'win_subsystem' , None )
272+         if  win_subsystem  is  not   None :
273+             t ['win_subsystem' ] =  win_subsystem 
274+ 
261275        if  installdata  and  target .should_install ():
262276            t ['installed' ] =  True 
263277            ifn  =  [install_lookuptable .get (x , [None ]) for  x  in  target .get_outputs ()]
@@ -343,6 +357,23 @@ def list_buildsystem_files(builddata: build.Build, interpreter: Interpreter) ->
343357    filelist  =  [PurePath (src_dir , x ).as_posix () for  x  in  filelist ]
344358    return  filelist 
345359
360+ def  list_compilers (coredata : cdata .CoreData ) ->  T .Dict [str , T .Dict [str , T .Dict [str , str ]]]:
361+     compilers : T .Dict [str , T .Dict [str , T .Dict [str , str ]]] =  {}
362+     for  machine  in  ('host' , 'build' ):
363+         compilers [machine ] =  {}
364+         for  language , compiler  in  getattr (coredata .compilers , machine ).items ():
365+             compilers [machine ][language ] =  {
366+                 'id' : compiler .get_id (),
367+                 'exelist' : compiler .get_exelist (),
368+                 'linker_exelist' : compiler .get_linker_exelist (),
369+                 'file_suffixes' : compiler .file_suffixes ,
370+                 'default_suffix' : compiler .get_default_suffix (),
371+                 'version' : compiler .version ,
372+                 'full_version' : compiler .full_version ,
373+                 'linker_id' : compiler .get_linker_id (),
374+             }
375+     return  compilers 
376+ 
346377def  list_deps_from_source (intr : IntrospectionInterpreter ) ->  T .List [T .Dict [str , T .Union [str , bool ]]]:
347378    result  =  []  # type: T.List[T.Dict[str, T.Union[str, bool]]] 
348379    for  i  in  intr .dependencies :
@@ -356,15 +387,48 @@ def list_deps_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[str,
356387        result  +=  [{k : v  for  k , v  in  i .items () if  k  in  keys }]
357388    return  result 
358389
359- def  list_deps (coredata : cdata .CoreData ) ->  T .List [T .Dict [str , T .Union [str , T .List [str ]]]]:
360-     result  =  []  # type: T.List[T.Dict[str, T.Union[str, T.List[str]]]] 
390+ def  list_deps (coredata : cdata .CoreData , backend : backends .Backend ) ->  T .List [T .Dict [str , T .Union [str , T .List [str ]]]]:
391+     result : T .Dict [str , T .Dict [str , T .Union [str , T .List [str ]]]] =  {}
392+ 
393+     def  _src_to_str (src_file : T .Union [mesonlib .FileOrString , build .CustomTarget , build .StructuredSources , build .CustomTargetIndex , build .GeneratedList ]) ->  T .List [str ]:
394+         if  isinstance (src_file , str ):
395+             return  [src_file ]
396+         if  isinstance (src_file , mesonlib .File ):
397+             return  [src_file .absolute_path (backend .source_dir , backend .build_dir )]
398+         if  isinstance (src_file , (build .CustomTarget , build .CustomTargetIndex , build .GeneratedList )):
399+             return  src_file .get_outputs ()
400+         if  isinstance (src_file , build .StructuredSources ):
401+             return  [f  for  s  in  src_file .as_list () for  f  in  _src_to_str (s )]
402+         raise  mesonlib .MesonBugException (f'Invalid file type { type (src_file )}  .' )
403+ 
404+     def  _create_result (d : Dependency , varname : T .Optional [str ] =  None ) ->  T .Dict [str , T .Any ]:
405+         return  {
406+             'name' : d .name ,
407+             'type' : d .type_name ,
408+             'version' : d .get_version (),
409+             'compile_args' : d .get_compile_args (),
410+             'link_args' : d .get_link_args (),
411+             'include_directories' : [i  for  idirs  in  d .get_include_dirs () for  i  in  idirs .to_string_list (backend .source_dir )],
412+             'sources' : [f  for  s  in  d .get_sources () for  f  in  _src_to_str (s )],
413+             'extra_files' : [f  for  s  in  d .get_extra_files () for  f  in  _src_to_str (s )],
414+             'deps' : [e .name  for  e  in  d .ext_deps ],
415+             'meson_variables' : [varname ] if  varname  else  [],
416+         }
417+ 
361418    for  d  in  coredata .deps .host .values ():
362419        if  d .found ():
363-             result  +=  [{'name' : d .name ,
364-                         'version' : d .get_version (),
365-                         'compile_args' : d .get_compile_args (),
366-                         'link_args' : d .get_link_args ()}]
367-     return  result 
420+             result [d .name ] =  _create_result (d )
421+ 
422+     for  varname , holder  in  backend .interpreter .variables .items ():
423+         if  isinstance (holder , ObjectHolder ):
424+             d  =  holder .held_object 
425+             if  isinstance (d , Dependency ) and  d .found ():
426+                 if  d .name  in  result :
427+                     T .cast (T .List [str ], result [d .name ]['meson_variables' ]).append (varname )
428+                 else :
429+                     result [d .name ] =  _create_result (d , varname )
430+ 
431+     return  list (result .values ())
368432
369433def  get_test_list (testdata : T .List [backends .TestSerialisation ]) ->  T .List [T .Dict [str , T .Union [str , int , T .List [str ], T .Dict [str , str ]]]]:
370434    result  =  []  # type: T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]] 
@@ -396,6 +460,16 @@ def list_tests(testdata: T.List[backends.TestSerialisation]) -> T.List[T.Dict[st
396460def  list_benchmarks (benchdata : T .List [backends .TestSerialisation ]) ->  T .List [T .Dict [str , T .Union [str , int , T .List [str ], T .Dict [str , str ]]]]:
397461    return  get_test_list (benchdata )
398462
463+ def  list_machines (builddata : build .Build ) ->  T .Dict [str , T .Dict [str , T .Union [str , bool ]]]:
464+     machines : T .Dict [str , T .Dict [str , T .Union [str , bool ]]] =  {}
465+     for  m  in  ('host' , 'build' , 'target' ):
466+         machine  =  getattr (builddata .environment .machines , m )
467+         machines [m ] =  dataclasses .asdict (machine )
468+         machines [m ]['is_64_bit' ] =  machine .is_64_bit 
469+         machines [m ]['exe_suffix' ] =  machine .get_exe_suffix ()
470+         machines [m ]['object_suffix' ] =  machine .get_object_suffix ()
471+     return  machines 
472+ 
399473def  list_projinfo (builddata : build .Build ) ->  T .Dict [str , T .Union [str , T .List [T .Dict [str , str ]]]]:
400474    result  =  {'version' : builddata .project_version ,
401475              'descriptive_name' : builddata .project_name ,
0 commit comments