@ -434,18 +434,23 @@ class NinjaBackend(backends.Backend):
self . introspection_data = { }
self . created_llvm_ir_rule = PerMachine ( False , False )
def create_target_alias ( self , to_target ) :
# We need to use aliases for targets that might be used as directory
# names to workaround a Ninja bug that breaks `ninja -t clean`.
# This is used for 'reserved' targets such as 'test', 'install',
# 'benchmark', etc, and also for RunTargets.
# https://github.com/mesonbuild/meson/issues/1644
if not to_target . startswith ( ' meson- ' ) :
raise AssertionError ( f ' Invalid usage of create_target_alias with { to_target !r} ' )
from_target = to_target [ len ( ' meson- ' ) : ]
elem = NinjaBuildElement ( self . all_outputs , from_target , ' phony ' , to_target )
def create_phony_target ( self , all_outputs , dummy_outfile , rulename , phony_infilename , implicit_outs = None ) :
'''
We need to use aliases for targets that might be used as directory
names to workaround a Ninja bug that breaks ` ninja - t clean ` .
This is used for ' reserved ' targets such as ' test ' , ' install ' ,
' benchmark ' , etc , and also for RunTargets .
https : / / github . com / mesonbuild / meson / issues / 1644
'''
if dummy_outfile . startswith ( ' meson- ' ) :
raise AssertionError ( f ' Invalid usage of create_phony_target with { dummy_outfile !r} ' )
to_name = f ' meson- { dummy_outfile } '
elem = NinjaBuildElement ( all_outputs , dummy_outfile , ' phony ' , to_name )
self . add_build ( elem )
return NinjaBuildElement ( all_outputs , to_name , rulename , phony_infilename , implicit_outs )
def detect_vs_dep_prefix ( self , tempfilename ) :
''' VS writes its dependency in a locale dependent format.
Detect the search prefix to use . '''
@ -1050,13 +1055,10 @@ class NinjaBackend(backends.Backend):
env = target_env ,
verbose = True )
cmd_type = f ' (wrapped by meson { reason } ) ' if reason else ' '
internal_target_name = f ' meson- { target_name } '
elem = NinjaBuildElement ( self . all_outputs , internal_target_name , ' CUSTOM_COMMAND ' , [ ] )
elem = self . create_phony_target ( self . all_outputs , target_name , ' CUSTOM_COMMAND ' , [ ] )
elem . add_item ( ' COMMAND ' , meson_exe_cmd )
elem . add_item ( ' description ' , f ' Running external command { target . name } { cmd_type } ' )
elem . add_item ( ' pool ' , ' console ' )
# Alias that runs the target defined above with the name the user specified
self . create_target_alias ( internal_target_name )
deps = self . unwrap_dep_list ( target )
deps + = self . get_custom_target_depend_files ( target )
elem . add_dep ( deps )
@ -1084,55 +1086,43 @@ class NinjaBackend(backends.Backend):
( [ ' --use_llvm_cov ' ] if use_llvm_cov else [ ] ) )
def generate_coverage_rules ( self , gcovr_exe : T . Optional [ str ] , gcovr_version : T . Optional [ str ] ) :
e = NinjaBuildElemen t( self . all_outputs , ' meson- coverage' , ' CUSTOM_COMMAND ' , ' PHONY ' )
e = self . create_phony_targe t( self . all_outputs , ' coverage ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
self . generate_coverage_command ( e , [ ] )
e . add_item ( ' description ' , ' Generates coverage reports ' )
self . add_build ( e )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-coverage ' )
self . generate_coverage_legacy_rules ( gcovr_exe , gcovr_version )
def generate_coverage_legacy_rules ( self , gcovr_exe : T . Optional [ str ] , gcovr_version : T . Optional [ str ] ) :
e = NinjaBuildElemen t( self . all_outputs , ' meson- coverage-html' , ' CUSTOM_COMMAND ' , ' PHONY ' )
e = self . create_phony_targe t( self . all_outputs , ' coverage-html ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
self . generate_coverage_command ( e , [ ' --html ' ] )
e . add_item ( ' description ' , ' Generates HTML coverage report ' )
self . add_build ( e )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-coverage-html ' )
if gcovr_exe :
e = NinjaBuildElemen t( self . all_outputs , ' meson- coverage-xml' , ' CUSTOM_COMMAND ' , ' PHONY ' )
e = self . create_phony_targe t( self . all_outputs , ' coverage-xml ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
self . generate_coverage_command ( e , [ ' --xml ' ] )
e . add_item ( ' description ' , ' Generates XML coverage report ' )
self . add_build ( e )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-coverage-xml ' )
e = NinjaBuildElemen t( self . all_outputs , ' meson- coverage-text' , ' CUSTOM_COMMAND ' , ' PHONY ' )
e = self . create_phony_target ( self . all_outputs , ' coverage-text ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
self . generate_coverage_command ( e , [ ' --text ' ] )
e . add_item ( ' description ' , ' Generates text coverage report ' )
self . add_build ( e )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-coverage-text ' )
if mesonlib . version_compare ( gcovr_version , ' >=4.2 ' ) :
e = NinjaBuildElemen t( self . all_outputs , ' meson- coverage-sonarqube' , ' CUSTOM_COMMAND ' , ' PHONY ' )
e = self . create_phony_targe t( self . all_outputs , ' coverage-sonarqube ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
self . generate_coverage_command ( e , [ ' --sonarqube ' ] )
e . add_item ( ' description ' , ' Generates Sonarqube XML coverage report ' )
self . add_build ( e )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-coverage-sonarqube ' )
def generate_install ( self ) :
self . create_install_data_files ( )
elem = NinjaBuildElemen t( self . all_outputs , ' meson- install' , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem = self . create_phony_targe t( self . all_outputs , ' install ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem . add_dep ( ' all ' )
elem . add_item ( ' DESC ' , ' Installing files. ' )
elem . add_item ( ' COMMAND ' , self . environment . get_build_command ( ) + [ ' install ' , ' --no-rebuild ' ] )
elem . add_item ( ' pool ' , ' console ' )
self . add_build ( elem )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-install ' )
def generate_tests ( self ) :
self . serialize_tests ( )
@ -1141,25 +1131,21 @@ class NinjaBackend(backends.Backend):
cmd + = [ ' --no-stdsplit ' ]
if self . environment . coredata . get_option ( OptionKey ( ' errorlogs ' ) ) :
cmd + = [ ' --print-errorlogs ' ]
elem = NinjaBuildElemen t( self . all_outputs , ' meson- test' , ' CUSTOM_COMMAND ' , [ ' all ' , ' PHONY ' ] )
elem = self . create_phony_targe t( self . all_outputs , ' test ' , ' CUSTOM_COMMAND ' , [ ' all ' , ' PHONY ' ] )
elem . add_item ( ' COMMAND ' , cmd )
elem . add_item ( ' DESC ' , ' Running all tests. ' )
elem . add_item ( ' pool ' , ' console ' )
self . add_build ( elem )
# Alias that runs the above-defined meson-test target
self . create_target_alias ( ' meson-test ' )
# And then benchmarks.
cmd = self . environment . get_build_command ( True ) + [
' test ' , ' --benchmark ' , ' --logbase ' ,
' benchmarklog ' , ' --num-processes=1 ' , ' --no-rebuild ' ]
elem = NinjaBuildElemen t( self . all_outputs , ' meson- benchmark' , ' CUSTOM_COMMAND ' , [ ' all ' , ' PHONY ' ] )
elem = self . create_phony_targe t( self . all_outputs , ' benchmark ' , ' CUSTOM_COMMAND ' , [ ' all ' , ' PHONY ' ] )
elem . add_item ( ' COMMAND ' , cmd )
elem . add_item ( ' DESC ' , ' Running benchmark suite. ' )
elem . add_item ( ' pool ' , ' console ' )
self . add_build ( elem )
# Alias that runs the above-defined meson-benchmark target
self . create_target_alias ( ' meson-benchmark ' )
def generate_rules ( self ) :
self . rules = [ ]
@ -3170,33 +3156,27 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
mlog . debug ( " Library versioning disabled because we do not have symlink creation privileges. " )
def generate_custom_target_clean ( self , trees : T . List [ str ] ) - > str :
e = NinjaBuildElemen t( self . all_outputs , ' meson- clean-ctlist' , ' CUSTOM_COMMAND ' , ' PHONY ' )
e = self . create_phony_targe t( self . all_outputs , ' clean-ctlist ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
d = CleanTrees ( self . environment . get_build_dir ( ) , trees )
d_file = os . path . join ( self . environment . get_scratch_dir ( ) , ' cleantrees.dat ' )
e . add_item ( ' COMMAND ' , self . environment . get_build_command ( ) + [ ' --internal ' , ' cleantrees ' , d_file ] )
e . add_item ( ' description ' , ' Cleaning custom target directories ' )
self . add_build ( e )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-clean-ctlist ' )
# Write out the data file passed to the script
with open ( d_file , ' wb ' ) as ofile :
pickle . dump ( d , ofile )
return ' clean-ctlist '
def generate_gcov_clean ( self ) :
gcno_elem = NinjaBuildElemen t( self . all_outputs , ' meson- clean-gcno' , ' CUSTOM_COMMAND ' , ' PHONY ' )
gcno_elem = self . create_phony_targe t( self . all_outputs , ' clean-gcno ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
gcno_elem . add_item ( ' COMMAND ' , mesonlib . get_meson_command ( ) + [ ' --internal ' , ' delwithsuffix ' , ' . ' , ' gcno ' ] )
gcno_elem . add_item ( ' description ' , ' Deleting gcno files ' )
self . add_build ( gcno_elem )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-clean-gcno ' )
gcda_elem = NinjaBuildElemen t( self . all_outputs , ' meson- clean-gcda' , ' CUSTOM_COMMAND ' , ' PHONY ' )
gcda_elem = self . create_phony_target ( self . all_outputs , ' clean-gcda ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
gcda_elem . add_item ( ' COMMAND ' , mesonlib . get_meson_command ( ) + [ ' --internal ' , ' delwithsuffix ' , ' . ' , ' gcda ' ] )
gcda_elem . add_item ( ' description ' , ' Deleting gcda files ' )
self . add_build ( gcda_elem )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-clean-gcda ' )
def get_user_option_args ( self ) :
cmds = [ ]
@ -3209,13 +3189,11 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
return sorted ( cmds )
def generate_dist ( self ) :
elem = NinjaBuildElemen t( self . all_outputs , ' meson- dist' , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem = self . create_phony_targe t( self . all_outputs , ' dist ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem . add_item ( ' DESC ' , ' Creating source packages ' )
elem . add_item ( ' COMMAND ' , self . environment . get_build_command ( ) + [ ' dist ' ] )
elem . add_item ( ' pool ' , ' console ' )
self . add_build ( elem )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-dist ' )
def generate_scanbuild ( self ) :
if not environment . detect_scanbuild ( ) :
@ -3225,12 +3203,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
cmd = self . environment . get_build_command ( ) + \
[ ' --internal ' , ' scanbuild ' , self . environment . source_dir , self . environment . build_dir ] + \
self . environment . get_build_command ( ) + self . get_user_option_args ( )
elem = NinjaBuildElemen t( self . all_outputs , ' meson- scan-build' , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem = self . create_phony_targe t( self . all_outputs , ' scan-build ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem . add_item ( ' COMMAND ' , cmd )
elem . add_item ( ' pool ' , ' console ' )
self . add_build ( elem )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-scan-build ' )
def generate_clangtool ( self , name , extra_arg = None ) :
target_name = ' clang- ' + name
@ -3248,11 +3224,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
cmd = self . environment . get_build_command ( ) + \
[ ' --internal ' , ' clang ' + name , self . environment . source_dir , self . environment . build_dir ] + \
extra_args
elem = NinjaBuildElement ( self . all_outputs , ' meson- ' + target_name , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem = self . create_phony_target ( self . all_outputs , target_name , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem . add_item ( ' COMMAND ' , cmd )
elem . add_item ( ' pool ' , ' console ' )
self . add_build ( elem )
self . create_target_alias ( ' meson- ' + target_name )
def generate_clangformat ( self ) :
if not environment . detect_clangformat ( ) :
@ -3276,12 +3251,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
return
cmd = self . environment . get_build_command ( ) + \
[ ' --internal ' , ' tags ' , tool , self . environment . source_dir ]
elem = NinjaBuildElement ( self . all_outputs , ' meson- ' + target_name , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem = self . create_phony_target ( self . all_outputs , target_name , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem . add_item ( ' COMMAND ' , cmd )
elem . add_item ( ' pool ' , ' console ' )
self . add_build ( elem )
# Alias that runs the target defined above
self . create_target_alias ( ' meson- ' + target_name )
# For things like scan-build and other helper tools we might have.
def generate_utils ( self ) :
@ -3292,12 +3265,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
self . generate_tags ( ' ctags ' , ' ctags ' )
self . generate_tags ( ' cscope ' , ' cscope ' )
cmd = self . environment . get_build_command ( ) + [ ' --internal ' , ' uninstall ' ]
elem = NinjaBuildElemen t( self . all_outputs , ' meson- uninstall' , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem = self . create_phony_targe t( self . all_outputs , ' uninstall ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem . add_item ( ' COMMAND ' , cmd )
elem . add_item ( ' pool ' , ' console ' )
self . add_build ( elem )
# Alias that runs the target defined above
self . create_target_alias ( ' meson-uninstall ' )
def generate_ending ( self ) :
targetlist = [ ]
@ -3309,11 +3280,9 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
elem = NinjaBuildElement ( self . all_outputs , ' all ' , ' phony ' , targetlist )
self . add_build ( elem )
elem = NinjaBuildElemen t( self . all_outputs , ' meson- clean' , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem = self . create_phony_targe t( self . all_outputs , ' clean ' , ' CUSTOM_COMMAND ' , ' PHONY ' )
elem . add_item ( ' COMMAND ' , self . ninja_command + [ ' -t ' , ' clean ' ] )
elem . add_item ( ' description ' , ' Cleaning ' )
# Alias that runs the above-defined meson-clean target
self . create_target_alias ( ' meson-clean ' )
# If we have custom targets in this project, add all their outputs to
# the list that is passed to the `cleantrees.py` script. The script