@ -19,6 +19,7 @@ from .. import build
from . . import mlog
from . . import dependencies
from . . import compilers
from . . compilers import CompilerArgs
from . . mesonlib import File , MesonException , get_compiler_for_source , Popen_safe
from . backends import CleanTrees , InstallData
from . . build import InvalidArguments
@ -1725,7 +1726,7 @@ rule FORTRAN_DEP_HACK
def generate_llvm_ir_compile ( self , target , outfile , src ) :
compiler = get_compiler_for_source ( target . compilers . values ( ) , src )
commands = [ ]
commands = CompilerArgs ( compiler )
# Compiler args for compiling this target
commands + = compilers . get_base_compile_args ( self . environment . coredata . base_options ,
compiler )
@ -1748,11 +1749,40 @@ rule FORTRAN_DEP_HACK
# 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 )
# Convert from GCC-style link argument naming to the naming used by the
# current compiler.
commands = commands . to_native ( )
element . add_item ( ' ARGS ' , commands )
element . write ( outfile )
return rel_obj
def get_source_dir_include_args ( self , target , compiler ) :
curdir = target . get_subdir ( )
tmppath = os . path . normpath ( os . path . join ( self . build_to_src , curdir ) )
return compiler . get_include_args ( tmppath , False )
def get_build_dir_include_args ( self , target , compiler ) :
curdir = target . get_subdir ( )
if curdir == ' ' :
curdir = ' . '
return compiler . get_include_args ( curdir , False )
def get_custom_target_dir_include_args ( self , target , compiler ) :
custom_target_include_dirs = [ ]
for i in target . get_generated_sources ( ) :
# Generator output goes into the target private dir which is
# already in the include paths list. Only custom targets have their
# own target build dir.
if not isinstance ( i , build . CustomTarget ) :
continue
idir = self . get_target_dir ( i )
if idir not in custom_target_include_dirs :
custom_target_include_dirs . append ( idir )
incs = [ ]
for i in custom_target_include_dirs :
incs + = compiler . get_include_args ( i , False )
return incs
def generate_single_compile ( self , target , outfile , src , is_generated = False , header_deps = [ ] , order_deps = [ ] ) :
"""
Compiles C / C + + , ObjC / ObjC + + , Fortran , and D sources
@ -1763,30 +1793,40 @@ rule FORTRAN_DEP_HACK
raise AssertionError ( ' BUG: sources should not contain headers {!r} ' . format ( src . fname ) )
extra_orderdeps = [ ]
compiler = get_compiler_for_source ( target . compilers . values ( ) , src )
commands = [ ]
# The first thing is implicit include directories: source, build and private.
commands + = compiler . get_include_args ( self . get_target_private_dir ( target ) , False )
# Compiler args for compiling this target
# Create an empty commands list, and start adding arguments from
# various sources in the order in which they must override each other
commands = CompilerArgs ( compiler )
# Add compiler args for compiling this target derived from 'base' build
# options passed on the command-line, in default_options, etc.
# These have the lowest priority.
commands + = compilers . get_base_compile_args ( self . environment . coredata . base_options ,
compiler )
# Add the root source and build directories as include dirs
curdir = target . get_subdir ( )
tmppath = os . path . normpath ( os . path . join ( self . build_to_src , curdir ) )
src_inc = compiler . get_include_args ( tmppath , False )
if curdir == ' ' :
curdir = ' . '
build_inc = compiler . get_include_args ( curdir , False )
commands + = build_inc + src_inc
# -I args work differently than other ones. In them the first found
# directory is used whereas for other flags (such as -ffoo -fno-foo) the
# latest one is used. Therefore put the internal include directories
# here before generating the "basic compiler args" so they override args
# coming from e.g. pkg-config .
# The code generated by valac is usually crap and has tons of unused
# variables and such, so disable warnings for Vala C sources.
no_warn_args = ( is_generated == ' vala ' )
# Add compiler args and include paths from several sources; defaults,
# build options, external dependencies, etc.
commands + = self . generate_basic_compiler_args ( target , compiler , no_warn_args )
# Add include dirs from the `include_directories:` kwarg on the target
# and from `include_directories:` of internal deps of the target.
#
# Target include dirs should override internal deps include dirs.
#
# Include dirs from internal deps should override include dirs from
# external deps .
for i in target . get_include_dirs ( ) :
basedir = i . get_curdir ( )
for d in i . get_incdirs ( ) :
# Avoid superfluous '/.' at the end of paths when d is '.'
if d not in ( ' ' , ' . ' ) :
expdir = os . path . join ( basedir , d )
else :
expdir = basedir
srctreedir = os . path . join ( self . build_to_src , expdir )
# Add source subdir first so that the build subdir overrides it
sargs = compiler . get_include_args ( srctreedir , i . is_system )
commands + = sargs
# There may be include dirs where a build directory has not been
# created for some source dir. For example if someone does this:
#
@ -1797,20 +1837,32 @@ rule FORTRAN_DEP_HACK
bargs = compiler . get_include_args ( expdir , i . is_system )
else :
bargs = [ ]
sargs = compiler . get_include_args ( srctreedir , i . is_system )
commands + = bargs
commands + = sargs
for d in i . get_extra_build_dirs ( ) :
commands + = compiler . get_include_args ( d , i . is_system )
commands + = self . generate_basic_compiler_args ( target , compiler ,
# The code generated by valac is usually crap
# and has tons of unused variables and such,
# so disable warnings for Vala C sources.
no_warn_args = ( is_generated == ' vala ' ) )
for d in target . external_deps :
if d . need_threads ( ) :
commands + = compiler . thread_flags ( )
break
# Add per-target compile args, f.ex, `c_args : ['-DFOO']`. We set these
# near the end since these are supposed to override everything else.
commands + = self . escape_extra_args ( compiler ,
target . get_extra_args ( compiler . get_language ( ) ) )
# Add source dir and build dir. Project-specific and target-specific
# include paths must override per-target compile args, include paths
# from external dependencies, internal dependencies, and from
# per-target `include_directories:`
#
# We prefer headers in the build dir and the custom target dir over the
# source dir since, for instance, the user might have an
# srcdir == builddir Autotools build in their source tree. Many
# projects that are moving to Meson have both Meson and Autotools in
# parallel as part of the transition.
commands + = self . get_source_dir_include_args ( target , compiler )
commands + = self . get_custom_target_dir_include_args ( target , compiler )
commands + = self . get_build_dir_include_args ( target , compiler )
# Finally add the private dir for the target to the include path. This
# must override everything else and must be the final path added.
commands + = compiler . get_include_args ( self . get_target_private_dir ( target ) , False )
# FIXME: This file handling is atrocious and broken. We need to
# replace it with File objects used consistently everywhere.
if isinstance ( src , RawFilename ) :
rel_src = src . fname
if os . path . isabs ( src . fname ) :
@ -1835,7 +1887,13 @@ rule FORTRAN_DEP_HACK
rel_obj = os . path . join ( self . get_target_private_dir ( target ) , obj_basename )
rel_obj + = ' . ' + self . environment . get_object_suffix ( )
dep_file = compiler . depfile_for_object ( rel_obj )
# Add MSVC debug file generation compile flags: /Fd /FS
commands + = self . get_compile_debugfile_args ( compiler , target , rel_obj )
# PCH handling
if self . environment . coredata . base_options . get ( ' b_pch ' , False ) :
commands + = self . get_pch_include_args ( compiler , target )
pchlist = target . get_pch ( compiler . language )
else :
pchlist = [ ]
@ -1848,19 +1906,7 @@ rule FORTRAN_DEP_HACK
i = os . path . join ( self . get_target_private_dir ( target ) , compiler . get_pch_name ( pchlist [ 0 ] ) )
arr . append ( i )
pch_dep = arr
custom_target_include_dirs = [ ]
for i in target . get_generated_sources ( ) :
if not isinstance ( i , build . CustomTarget ) :
continue
idir = self . get_target_dir ( i )
if idir not in custom_target_include_dirs :
custom_target_include_dirs . append ( idir )
for i in custom_target_include_dirs :
commands + = compiler . get_include_args ( i , False )
if self . environment . coredata . base_options . get ( ' b_pch ' , False ) :
commands + = self . get_pch_include_args ( compiler , target )
commands + = self . get_compile_debugfile_args ( compiler , target , rel_obj )
crstr = ' '
if target . is_cross :
crstr = ' _CROSS '
@ -1895,7 +1941,9 @@ rule FORTRAN_DEP_HACK
element . add_orderdep ( d )
element . add_orderdep ( pch_dep )
element . add_orderdep ( extra_orderdeps )
commands = self . dedup_arguments ( commands )
# Convert from GCC-style link argument naming to the naming used by the
# current compiler.
commands = commands . to_native ( )
for i in self . get_fortran_orderdeps ( target , compiler ) :
element . add_orderdep ( i )
element . add_item ( ' DEPFILE ' , dep_file )