aboutsummaryrefslogtreecommitdiff
path: root/ninjabackend.py
diff options
context:
space:
mode:
Diffstat (limited to 'ninjabackend.py')
-rw-r--r--ninjabackend.py129
1 files changed, 82 insertions, 47 deletions
diff --git a/ninjabackend.py b/ninjabackend.py
index b2d5d00..01223ab 100644
--- a/ninjabackend.py
+++ b/ninjabackend.py
@@ -109,8 +109,8 @@ class NinjaBuildElement():
class NinjaBackend(backends.Backend):
- def __init__(self, build, interp):
- super().__init__(build, interp)
+ def __init__(self, build):
+ super().__init__(build)
self.source_suffix_in_objs = True
self.ninja_filename = 'build.ninja'
self.fortran_deps = {}
@@ -122,7 +122,8 @@ class NinjaBackend(backends.Backend):
raise MesonException('Multiple producers for Ninja target "%s". Please rename your targets.' % n)
self.all_outputs[n] = True
- def generate(self):
+ def generate(self, interp):
+ self.interpreter = interp
outfilename = os.path.join(self.environment.get_build_dir(), self.ninja_filename)
tempfilename = outfilename + '~'
outfile = open(tempfilename, 'w')
@@ -205,7 +206,7 @@ class NinjaBackend(backends.Backend):
for gensource in target.get_generated_sources():
if isinstance(gensource, build.CustomTarget):
for src in gensource.output:
- src = os.path.join(gensource.subdir, src)
+ src = os.path.join(self.get_target_dir(gensource), src)
if self.environment.is_source(src) and not self.environment.is_header(src):
if is_unity:
unity_deps.append(os.path.join(self.environment.get_build_dir(), RawFilename(src)))
@@ -222,13 +223,13 @@ class NinjaBackend(backends.Backend):
else:
for src in gensource.get_outfilelist():
if self.environment.is_object(src):
- obj_list.append(os.path.join(self.get_target_private_dir(target), src))
+ obj_list.append(os.path.join(self.get_target_private_dir_abs(target), src))
elif not self.environment.is_header(src):
if is_unity:
if '/' in src:
rel_src = src
else:
- rel_src = os.path.join(self.get_target_private_dir(target), src)
+ rel_src = os.path.join(self.get_target_private_dir_abs(target), src)
unity_deps.append(rel_src)
abs_src = os.path.join(self.environment.get_build_dir(), rel_src)
unity_src.append(abs_src)
@@ -275,15 +276,14 @@ class NinjaBackend(backends.Backend):
if not tname in self.processed_targets:
self.generate_target(t, outfile)
- def hackety_hack(self, hack):
- if isinstance(hack, list):
- return hack[0]
- return hack
-
def generate_custom_target(self, target, outfile):
- ofilenames = [os.path.join(target.subdir, i) for i in target.output]
- # FIXME, should not grab element at zero but rather expand all.
- deps = [os.path.join(i.get_subdir(), self.hackety_hack(i.get_filename())) for i in target.get_dependencies()]
+ ofilenames = [os.path.join(self.get_target_dir(target), i) for i in target.output]
+ deps = []
+ for i in target.get_dependencies():
+ # FIXME, should not grab element at zero but rather expand all.
+ if isinstance(i, list):
+ i = i[0]
+ deps.append(os.path.join(self.get_target_dir(i), i.get_filename()[0]))
srcs = []
for i in target.sources:
if isinstance(i, str):
@@ -299,9 +299,14 @@ class NinjaBackend(backends.Backend):
if not isinstance(tmp, list):
tmp = [tmp]
for fname in tmp:
- elem.add_dep(os.path.join(d.get_subdir(), fname))
+ elem.add_dep(os.path.join(self.get_target_dir(d), fname))
cmd = []
for i in target.command:
+ if isinstance(i, build.CustomTarget):
+ # GIR scanner will attempt to execute this binary but
+ # it assumes that it is in path, so always give it a full path.
+ tmp = i.get_filename()[0]
+ i = os.path.join(self.get_target_dir(i), tmp)
for (j, src) in enumerate(srcs):
i = i.replace('@INPUT%d@' % j, src)
for (j, res) in enumerate(ofilenames):
@@ -311,7 +316,21 @@ class NinjaBackend(backends.Backend):
elif i == '@OUTPUT@':
cmd += ofilenames
else:
+ if '@OUTDIR@' in i:
+ i = i.replace('@OUTDIR@', self.get_target_dir(target))
+ elif '@PRIVATE_OUTDIR_' in i:
+ match = re.search('@PRIVATE_OUTDIR_(ABS_)?([a-zA-Z@:]*)@', i)
+ source = match.group(0)
+ if match.group(1) is None:
+ lead_dir = ''
+ else:
+ lead_dir = self.environment.get_build_dir()
+ target_id = match.group(2)
+ i = i.replace(source,
+ os.path.join(lead_dir,
+ self.get_target_dir(self.build.targets[target_id])))
cmd.append(i)
+
elem.add_item('COMMAND', cmd)
elem.add_item('description', 'Generating %s with a custom command.' % target.name)
elem.write(outfile)
@@ -505,7 +524,6 @@ class NinjaBackend(backends.Backend):
d.man.append(i)
def generate_data_install(self, d):
- dataroot = self.environment.get_datadir()
data = self.build.get_data()
for de in data:
subdir = de.get_install_dir()
@@ -597,7 +615,7 @@ class NinjaBackend(backends.Backend):
def generate_jar_target(self, target, outfile):
fname = target.get_filename()
subdir = target.get_subdir()
- outname_rel = os.path.join(subdir, fname)
+ outname_rel = os.path.join(self.get_target_dir(target), fname)
src_list = target.get_sources()
class_list = []
compiler = self.get_compiler_for_source(src_list[0])
@@ -610,13 +628,13 @@ class NinjaBackend(backends.Backend):
if main_class != '':
e = 'e'
for src in src_list:
- class_list.append(self.generate_single_java_compile(subdir, src, target, compiler, outfile))
+ class_list.append(self.generate_single_java_compile(src, target, compiler, outfile))
jar_rule = 'java_LINKER'
commands = [c+m+e+f]
if e != '':
commands.append(main_class)
commands.append(self.get_target_filename(target))
- commands += ['-C', self.get_target_private_dir(target)]
+ commands += ['-C', self.get_target_private_dir_abs(target)]
commands += class_list
elem = NinjaBuildElement(outname_rel, jar_rule, [])
elem.add_dep([os.path.join(self.get_target_private_dir(target), i) for i in class_list])
@@ -649,8 +667,7 @@ class NinjaBackend(backends.Backend):
def generate_cs_target(self, target, outfile):
buildtype = self.environment.coredata.buildtype
fname = target.get_filename()
- subdir = target.get_subdir()
- outname_rel = os.path.join(subdir, fname)
+ outname_rel = os.path.join(self.get_target_dir(target), fname)
src_list = target.get_sources()
compiler = self.get_compiler_for_source(src_list[0])
assert(compiler.get_language() == 'cs')
@@ -669,8 +686,9 @@ class NinjaBackend(backends.Backend):
deps += resource_deps
commands += compiler.get_output_args(outname_rel)
for l in target.link_targets:
- commands += compiler.get_link_args(l.get_filename())
- deps.append(l.get_filename())
+ lname = os.path.join(self.get_target_dir(l), l.get_filename())
+ commands += compiler.get_link_args(lname)
+ deps.append(lname)
if '-g' in commands:
outputs = [outname_rel, outname_rel + '.mdb']
else:
@@ -681,13 +699,13 @@ class NinjaBackend(backends.Backend):
self.check_outputs(elem)
elem.write(outfile)
- def generate_single_java_compile(self, subdir, src, target, compiler, outfile):
+ def generate_single_java_compile(self, src, target, compiler, outfile):
args = []
args += compiler.get_buildtype_args(self.environment.coredata.buildtype)
args += compiler.get_output_args(self.get_target_private_dir(target))
rel_src = src.rel_to_builddir(self.build_to_src)
plain_class_path = src.fname[:-4] + 'class'
- rel_obj = os.path.join(self.get_target_private_dir(target), plain_class_path)
+ rel_obj = os.path.join(self.get_target_private_dir_abs(target), plain_class_path)
element = NinjaBuildElement(rel_obj, compiler.get_language() + '_COMPILER', rel_src)
element.add_item('ARGS', args)
element.write(outfile)
@@ -709,7 +727,7 @@ class NinjaBackend(backends.Backend):
if not s.endswith('.vala'):
continue
vapibase = os.path.basename(s.fname)[:-4] + 'vapi'
- rel_vapi = os.path.join(self.get_target_private_dir(target), vapibase)
+ rel_vapi = os.path.join(self.get_target_private_dir_abs(target), vapibase)
args = ['--fast-vapi=' + rel_vapi]
rel_s = s.rel_to_builddir(self.build_to_src)
element = NinjaBuildElement(rel_vapi, valac.get_language() + '_COMPILER', rel_s)
@@ -740,7 +758,7 @@ class NinjaBackend(backends.Backend):
for s in src:
if not s.endswith('.vala'):
continue
- args = ['-d', self.get_target_private_dir(target)]
+ args = ['-d', self.get_target_private_dir_abs(target)]
sc = os.path.basename(s.fname)[:-4] + 'c'
args += ['-C']
vapi_order_deps = []
@@ -750,7 +768,7 @@ class NinjaBackend(backends.Backend):
(vapibase, rel_vapi) = vapi_info
args += ['--use-fast-vapi=' + rel_vapi]
vapi_order_deps.append(rel_vapi)
- relsc = os.path.join(self.get_target_private_dir(target), sc)
+ relsc = os.path.join(self.get_target_private_dir_abs(target), sc)
rel_s = s.rel_to_builddir(self.build_to_src)
args += ['--deps', relsc + '.d']
if self.environment.coredata.werror:
@@ -1114,17 +1132,17 @@ rule FORTRAN_DEP_HACK
extra_dependencies = [os.path.join(self.build_to_src, i) for i in genlist.extra_depends]
for i in range(len(infilelist)):
if len(generator.outputs) == 1:
- sole_output = os.path.join(self.get_target_private_dir(target), outfilelist[i])
+ sole_output = os.path.join(self.get_target_private_dir_abs(target), outfilelist[i])
else:
sole_output = ''
curfile = infilelist[i]
infilename = os.path.join(self.build_to_src, curfile)
outfiles = genlist.get_outputs_for(curfile)
- outfiles = [os.path.join(self.get_target_private_dir(target), of) for of in outfiles]
+ outfiles = [os.path.join(self.get_target_private_dir_abs(target), of) for of in outfiles]
args = [x.replace("@INPUT@", infilename).replace('@OUTPUT@', sole_output)\
for x in base_args]
- args = self.replace_outputs(args, self.get_target_private_dir(target), outfilelist)
- relout = os.path.join(target.subdir, target.get_basename() + target.type_suffix())
+ args = self.replace_outputs(args, self.get_target_private_dir_abs(target), outfilelist)
+ relout = self.get_target_private_dir(target)
args = [x.replace("@SOURCE_DIR@", self.build_to_src).replace("@BUILD_DIR@", relout)
for x in args]
cmdlist = exe_arr + args
@@ -1169,7 +1187,7 @@ rule FORTRAN_DEP_HACK
def get_fortran_deps(self, compiler, src, target):
mod_files = []
usere = re.compile(r"\s*use\s+(\w+)", re.IGNORECASE)
- dirname = self.get_target_private_dir(target)
+ dirname = self.get_target_private_dir_abs(target)
tdeps= self.fortran_deps[target.get_basename()]
for line in open(src):
usematch = usere.match(line)
@@ -1219,7 +1237,7 @@ rule FORTRAN_DEP_HACK
if '/' in src:
rel_src = src
else:
- rel_src = os.path.join(self.get_target_private_dir(target), src)
+ rel_src = os.path.join(self.get_target_private_dir_abs(target), src)
abs_src = os.path.join(self.environment.get_source_dir(), rel_src)
else:
if isinstance(src, File):
@@ -1247,7 +1265,7 @@ rule FORTRAN_DEP_HACK
pch_dep = []
else:
arr = []
- i = os.path.join(self.get_target_private_dir(target), compiler.get_pch_name(pchlist[0]))
+ i = os.path.join(self.get_target_private_dir_abs(target), compiler.get_pch_name(pchlist[0]))
arr.append(i)
pch_dep = arr
for i in target.get_include_dirs():
@@ -1259,6 +1277,14 @@ rule FORTRAN_DEP_HACK
sargs = compiler.get_include_args(srctreedir)
commands += bargs
commands += sargs
+ custom_target_include_dirs = []
+ for i in target.generated:
+ if isinstance(i, build.CustomTarget):
+ 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)
if self.environment.coredata.use_pch:
commands += self.get_pch_include_args(compiler, target)
crstr = ''
@@ -1277,14 +1303,14 @@ rule FORTRAN_DEP_HACK
depelem = NinjaBuildElement(modfile, 'FORTRAN_DEP_HACK', rel_obj)
depelem.write(outfile)
self.check_outputs(depelem)
- commands += compiler.get_module_outdir_args(self.get_target_private_dir(target))
+ commands += compiler.get_module_outdir_args(self.get_target_private_dir_abs(target))
element = NinjaBuildElement(rel_obj, compiler_name, rel_src)
for d in header_deps:
if isinstance(d, RawFilename):
d = d.fname
elif not '/' in d:
- d = os.path.join(self.get_target_private_dir(target), d)
+ d = os.path.join(self.get_target_private_dir_abs(target), d)
element.add_dep(d)
for d in extra_deps:
element.add_dep(d)
@@ -1292,7 +1318,7 @@ rule FORTRAN_DEP_HACK
if isinstance(d, RawFilename):
d = d.fname
elif not '/' in d :
- d = os.path.join(self.get_target_private_dir(target), d)
+ d = os.path.join(self.get_target_private_dir_abs(target), d)
element.add_orderdep(d)
element.add_orderdep(pch_dep)
element.add_orderdep(extra_orderdeps)
@@ -1307,13 +1333,13 @@ rule FORTRAN_DEP_HACK
# Fortran is a bit weird (again). When you link against a library, just compiling a source file
# requires the mod files that are output when single files are built. To do this right we would need to
# scan all inputs and write out explicit deps for each file. That is stoo slow and too much effort so
- # instead just have an ordered dependendy on the library. This ensures all reqquired mod files are created.
+ # instead just have an ordered dependendy on the library. This ensures all required mod files are created.
# The real deps are then detected via dep file generation from the compiler. This breaks on compilers that
# produce incorrect dep files but such is life.
def get_fortran_orderdeps(self, target, compiler):
if compiler.language != 'fortran':
return []
- return [os.path.join(lt.subdir, lt.filename) for lt in target.link_targets]
+ return [os.path.join(self.get_target_dir(lt), lt.filename) for lt in target.link_targets]
def generate_msvc_pch_command(self, target, compiler, pch):
if len(pch) != 2:
@@ -1321,7 +1347,7 @@ rule FORTRAN_DEP_HACK
header = pch[0]
source = pch[1]
pchname = compiler.get_pch_name(header)
- dst = os.path.join(self.get_target_private_dir(target), pchname)
+ dst = os.path.join(self.get_target_private_dir_abs(target), pchname)
commands = []
commands += self.generate_basic_compiler_args(target, compiler)
@@ -1334,7 +1360,7 @@ rule FORTRAN_DEP_HACK
def generate_gcc_pch_command(self, target, compiler, pch):
commands = []
commands += self.generate_basic_compiler_args(target, compiler)
- dst = os.path.join(self.get_target_private_dir(target),
+ dst = os.path.join(self.get_target_private_dir_abs(target),
os.path.split(pch)[-1] + '.' + compiler.get_pch_suffix())
dep = dst + '.' + compiler.get_depfile_suffix()
return (commands, dep, dst, []) # Gcc does not create an object file during pch generation.
@@ -1372,7 +1398,7 @@ rule FORTRAN_DEP_HACK
def generate_shsym(self, outfile, target):
target_name = self.get_target_filename(target)
- targetdir = self.get_target_private_dir(target)
+ targetdir = self.get_target_private_dir_abs(target)
symname = os.path.join(targetdir, target_name + '.symbols')
elem = NinjaBuildElement(symname, 'SHSYM', target_name)
if self.environment.is_cross_build() and self.environment.cross_info.need_cross_compiler():
@@ -1432,7 +1458,7 @@ rule FORTRAN_DEP_HACK
for dep in d.get_external_deps():
commands += dep.get_link_args()
commands += linker.build_rpath_args(self.environment.get_build_dir(),\
- target.get_rpaths(), target.install_rpath)
+ self.determine_rpath_dirs(target), target.install_rpath)
if self.environment.coredata.coverage:
commands += linker.get_coverage_link_args()
commands += extra_args
@@ -1445,9 +1471,18 @@ rule FORTRAN_DEP_HACK
self.check_outputs(elem)
return elem
+ def determine_rpath_dirs(self, target):
+ link_deps = target.get_all_link_deps()
+ result = []
+ for ld in link_deps:
+ prospective = self.get_target_dir(ld)
+ if not prospective in result:
+ result.append(prospective)
+ return result
+
def get_dependency_filename(self, t):
if isinstance(t, build.SharedLibrary):
- return os.path.join(self.get_target_private_dir(t), self.get_target_filename(t) + '.symbols')
+ return os.path.join(self.get_target_private_dir_abs(t), self.get_target_filename(t) + '.symbols')
return self.get_target_filename(t)
def generate_shlib_aliases(self, target, outdir):
@@ -1471,7 +1506,7 @@ rule FORTRAN_DEP_HACK
gcno_elem.add_item('COMMAND', [sys.executable, clean_script, '.', 'gcno'])
gcno_elem.add_item('description', 'Deleting gcno files')
gcno_elem.write(outfile)
- self.check_outputs(elem, gcno_elem)
+ self.check_outputs(gcno_elem, gcno_elem)
gcda_elem = NinjaBuildElement('clean-gcda', 'CUSTOM_COMMAND', 'PHONY')
script_root = self.environment.get_script_dir()
@@ -1501,7 +1536,7 @@ rule FORTRAN_DEP_HACK
plainname = os.path.split(src)[1]
basename = plainname.split('.')[0]
outname = rule.name_templ.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname)
- outfilename = os.path.join(self.get_target_private_dir(target), outname)
+ outfilename = os.path.join(self.get_target_private_dir_abs(target), outname)
infilename = os.path.join(self.build_to_src, target.get_source_subdir(), src)
elem = NinjaBuildElement(outfilename, rule.name, infilename)
elem.write(outfile)