@ -374,6 +374,9 @@ int dummy;
# because we need `header_deps` to be fully generated in the above loop.
for src in generated_source_files :
src_list . append ( src )
if self . environment . is_llvm_ir ( src ) :
obj_list . append ( self . generate_llvm_ir_compile ( target , outfile , src ) )
continue
obj_list . append ( self . generate_single_compile ( target , outfile , src , True ,
header_deps = header_deps ) )
@ -409,7 +412,9 @@ int dummy;
for f , src in target_sources . items ( ) :
if not self . environment . is_header ( src ) :
src_list . append ( src )
if is_unity and self . get_target_source_can_unity ( target , src ) :
if self . environment . is_llvm_ir ( src ) :
obj_list . append ( self . generate_llvm_ir_compile ( target , outfile , src ) )
elif is_unity and self . get_target_source_can_unity ( target , src ) :
abs_src = os . path . join ( self . environment . get_build_dir ( ) ,
src . rel_to_builddir ( self . build_to_src ) )
unity_src . append ( abs_src )
@ -1365,6 +1370,36 @@ rule FORTRAN_DEP_HACK
'''
outfile . write ( template % cmd )
def generate_llvm_ir_compile_rule ( self , compiler , is_cross , outfile ) :
if getattr ( self , ' created_llvm_ir_rule ' , False ) :
return
rule = ' rule llvm_ir {} _COMPILER \n ' . format ( ' _CROSS ' if is_cross else ' ' )
args = [ ' ' . join ( [ ninja_quote ( i ) for i in compiler . get_exelist ( ) ] ) ,
' ' . join ( self . get_cross_info_lang_args ( compiler , is_cross ) ) ,
' ' . join ( compiler . get_output_args ( ' $out ' ) ) ,
' ' . join ( compiler . get_compile_only_args ( ) ) ]
if mesonlib . is_windows ( ) :
command_template = ' command = {} @$out.rsp \n ' \
' rspfile = $out.rsp \n ' \
' rspfile_content = {} $ARGS {} {} $in \n '
else :
command_template = ' command = {} {} $ARGS {} {} $in \n '
command = command_template . format ( * args )
description = ' description = Compiling LLVM IR object $in. \n '
outfile . write ( rule )
outfile . write ( command )
outfile . write ( description )
outfile . write ( ' \n ' )
self . created_llvm_ir_rule = True
def get_cross_info_lang_args ( self , lang , is_cross ) :
if is_cross :
try :
return self . environment . cross_info . config [ ' properties ' ] [ lang + ' _args ' ]
except KeyError :
pass
return [ ]
def generate_compile_rule_for ( self , langname , compiler , qstr , is_cross , outfile ) :
if langname == ' java ' :
if not is_cross :
@ -1399,12 +1434,7 @@ rule FORTRAN_DEP_HACK
if d != ' $out ' and d != ' $in ' :
d = qstr % d
quoted_depargs . append ( d )
cross_args = [ ]
if is_cross :
try :
cross_args = self . environment . cross_info . config [ ' properties ' ] [ langname + ' _args ' ]
except KeyError :
pass
cross_args = self . get_cross_info_lang_args ( langname , is_cross )
if mesonlib . is_windows ( ) :
command_template = ''' command = %s @$out.rsp
rspfile = $ out . rsp
@ -1477,6 +1507,8 @@ rule FORTRAN_DEP_HACK
qstr = quote_char + " %s " + quote_char
for compiler in self . build . compilers :
langname = compiler . get_language ( )
if compiler . get_id ( ) == ' clang ' :
self . generate_llvm_ir_compile_rule ( compiler , False , outfile )
self . generate_compile_rule_for ( langname , compiler , qstr , False , outfile )
self . generate_pch_rule_for ( langname , compiler , qstr , False , outfile )
if self . environment . is_cross_build ( ) :
@ -1488,6 +1520,8 @@ rule FORTRAN_DEP_HACK
cclist = self . build . compilers
for compiler in cclist :
langname = compiler . get_language ( )
if compiler . get_id ( ) == ' clang ' :
self . generate_llvm_ir_compile_rule ( compiler , True , outfile )
self . generate_compile_rule_for ( langname , compiler , qstr , True , outfile )
self . generate_pch_rule_for ( langname , compiler , qstr , True , outfile )
outfile . write ( ' \n ' )
@ -1680,9 +1714,39 @@ rule FORTRAN_DEP_HACK
def get_link_debugfile_args ( self , linker , target , outname ) :
return linker . get_link_debugfile_args ( outname )
def generate_llvm_ir_compile ( self , target , outfile , src ) :
compiler = get_compiler_for_source ( target . compilers . values ( ) , src )
commands = [ ]
# Compiler args for compiling this target
commands + = compilers . get_base_compile_args ( self . environment . coredata . base_options ,
compiler )
if isinstance ( src , ( RawFilename , File ) ) :
src_filename = src . fname
elif os . path . isabs ( src ) :
src_filename = os . path . basename ( src )
else :
src_filename = src
obj_basename = src_filename . replace ( ' / ' , ' _ ' ) . replace ( ' \\ ' , ' _ ' )
rel_obj = os . path . join ( self . get_target_private_dir ( target ) , obj_basename )
rel_obj + = ' . ' + self . environment . get_object_suffix ( )
commands + = self . get_compile_debugfile_args ( compiler , target , rel_obj )
if isinstance ( src , RawFilename ) :
rel_src = src . fname
elif isinstance ( src , File ) :
rel_src = src . rel_to_builddir ( self . build_to_src )
else :
raise InvalidArguments ( ' Invalid source type: {!r} ' . format ( src ) )
# Write the Ninja build command
compiler_name = ' llvm_ir {} _COMPILER ' . format ( ' _CROSS ' if target . is_cross else ' ' )
element = NinjaBuildElement ( self . all_outputs , rel_obj , compiler_name , rel_src )
commands = self . dedup_arguments ( commands )
element . add_item ( ' ARGS ' , commands )
element . write ( outfile )
return rel_obj
def generate_single_compile ( self , target , outfile , src , is_generated = False , header_deps = [ ] , order_deps = [ ] ) :
"""
Compiles C / C + + , ObjC / ObjC + + , and D sources
Compiles C / C + + , ObjC / ObjC + + , Fortran , and D sources
"""
if isinstance ( src , str ) and src . endswith ( ' .h ' ) :
raise AssertionError ( ' BUG: sources should not contain headers ' )