aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends.py32
-rw-r--r--build.py20
-rw-r--r--compilers.py2
-rw-r--r--coredata.py6
-rw-r--r--interpreter.py37
-rwxr-xr-xmeson.py17
-rwxr-xr-xmesonconf.py6
-rw-r--r--modules/gnome.py14
-rw-r--r--ninjabackend.py129
-rwxr-xr-xrun_tests.py12
-rw-r--r--test cases/common/57 custom target chain/meson.build14
-rw-r--r--test cases/common/61 custom target source output/meson.build2
-rw-r--r--test cases/common/65 multiple generators/meson.build10
-rw-r--r--test cases/common/65 multiple generators/subdir/meson.build2
-rwxr-xr-xtest cases/common/78 ctarget dependency/gen2.py6
-rw-r--r--test cases/common/78 ctarget dependency/meson.build2
-rw-r--r--test cases/frameworks/7 gnome/gir/meson.build4
-rw-r--r--vs2010backend.py15
-rw-r--r--xcodebackend.py7
19 files changed, 202 insertions, 135 deletions
diff --git a/backends.py b/backends.py
index 8d71314..0fc8646 100644
--- a/backends.py
+++ b/backends.py
@@ -37,10 +37,9 @@ class TestSerialisation:
# This class contains the basic functionality that is needed by all backends.
# Feel free to move stuff in and out of it as you see fit.
class Backend():
- def __init__(self, build, interp):
+ def __init__(self, build):
self.build = build
self.environment = build.environment
- self.interpreter = interp
self.processed_targets = {}
self.dep_rules = {}
self.build_to_src = os.path.relpath(self.environment.get_source_dir(),
@@ -69,12 +68,18 @@ class Backend():
return filename
def get_target_dir(self, target):
- dirname = target.get_subdir()
+ if self.environment.coredata.layout == 'mirror':
+ dirname = target.get_subdir()
+ else:
+ dirname = 'meson-out'
os.makedirs(os.path.join(self.environment.get_build_dir(), dirname), exist_ok=True)
return dirname
def get_target_private_dir(self, target):
- dirname = os.path.join(self.get_target_dir(target), target.get_basename() + target.type_suffix())
+ return os.path.join(self.get_target_dir(target), target.get_basename() + target.type_suffix())
+
+ def get_target_private_dir_abs(self, target):
+ dirname = self.get_target_private_dir(target)
os.makedirs(os.path.join(self.environment.get_build_dir(), dirname), exist_ok=True)
return dirname
@@ -87,7 +92,7 @@ class Backend():
language = comp.get_language()
suffix = '.' + comp.get_default_suffix()
if language not in langlist:
- outfilename = os.path.join(self.get_target_private_dir(target), target.name + '-unity' + suffix)
+ outfilename = os.path.join(self.get_target_private_dir_abs(target), target.name + '-unity' + suffix)
outfileabs = os.path.join(self.environment.get_build_dir(), outfilename)
outfileabs_tmp = outfileabs + '.tmp'
abs_files.append(outfileabs)
@@ -167,7 +172,7 @@ class Backend():
def determine_ext_objs(self, extobj, proj_dir_to_build_root=''):
result = []
- targetdir = self.get_target_private_dir(extobj.target)
+ targetdir = self.get_target_private_dir_abs(extobj.target)
suffix = '.' + self.environment.get_object_suffix()
for osrc in extobj.srclist:
osrc_base = osrc.fname
@@ -187,7 +192,7 @@ class Backend():
def get_pch_include_args(self, compiler, target):
args = []
- pchpath = self.get_target_private_dir(target)
+ pchpath = self.get_target_private_dir_abs(target)
includeargs = compiler.get_include_args(pchpath)
for lang in ['c', 'cpp']:
p = target.get_pch(lang)
@@ -223,7 +228,7 @@ class Backend():
# Fortran rquires extra include directives.
if compiler.language == 'fortran':
for lt in target.link_targets:
- priv_dir = os.path.join(lt.subdir, lt.get_basename() + lt.type_suffix())
+ priv_dir = os.path.join(self.get_target_dir(lt), lt.get_basename() + lt.type_suffix())
incflag = compiler.get_include_args(priv_dir)
commands += incflag
return commands
@@ -254,8 +259,15 @@ class Backend():
if not isinstance(target, build.Executable):
print(target)
return []
- prospectives = target.get_transitive_rpaths()
- return [os.path.join(self.environment.get_build_dir(), i) for i in prospectives if len(i) > 0]
+ prospectives = target.get_transitive_link_deps()
+ result = []
+ for ld in prospectives:
+ if ld == '' or ld == '.':
+ continue
+ dirseg = os.path.join(self.environment.get_build_dir(), self.get_target_dir())
+ if dirseg not in result:
+ result.append(dirseg)
+ return result
def write_test_file(self, datafile):
arr = []
diff --git a/build.py b/build.py
index f1ce15d..6d6c013 100644
--- a/build.py
+++ b/build.py
@@ -267,13 +267,13 @@ class BuildTarget():
def extract_all_objects(self):
return ExtractedObjects(self, self.sources)
- def get_rpaths(self):
- return self.get_transitive_rpaths()
+ def get_all_link_deps(self):
+ return self.get_transitive_link_deps()
- def get_transitive_rpaths(self):
+ def get_transitive_link_deps(self):
result = []
for i in self.link_targets:
- result += i.get_rpaths()
+ result += i.get_all_link_deps()
return result
def get_custom_install_dir(self):
@@ -648,8 +648,8 @@ class SharedLibrary(BuildTarget):
def get_import_filename(self):
return self.prefix + self.name + '.' + self.importsuffix
- def get_rpaths(self):
- return [self.subdir] + self.get_transitive_rpaths()
+ def get_all_link_deps(self):
+ return [self] + self.get_transitive_link_deps()
def get_filename(self):
'''Works on all platforms except OSX, which does its own thing.'''
@@ -744,13 +744,7 @@ class CustomTarget:
final_cmd += c.get_command()
elif isinstance(c, BuildTarget) or isinstance(c, CustomTarget):
self.dependencies.append(c)
- # GIR scanner will attempt to execute this binary but
- # it assumes that it is in path, so always give it a full path.
- tmp = c.get_filename()
- if isinstance(tmp, str):
- tmp =[tmp]
- totarget = [os.path.join('.', c.get_subdir(), i) for i in tmp]
- final_cmd += totarget
+ final_cmd.append(c)
elif isinstance(c, list):
# Hackety hack, only supports one level of flattening. Should really
# work to arbtrary depth.
diff --git a/compilers.py b/compilers.py
index 24853e1..df8fc2f 100644
--- a/compilers.py
+++ b/compilers.py
@@ -202,6 +202,8 @@ class CCompiler():
return []
def get_include_args(self, path):
+ if path == '':
+ path = '.'
return ['-I' + path]
def get_std_shared_lib_link_args(self):
diff --git a/coredata.py b/coredata.py
index 2a7b2ce..793cd47 100644
--- a/coredata.py
+++ b/coredata.py
@@ -30,7 +30,8 @@ builtin_options = {'buildtype': True,
'localedir' : True,
'werror' : True,
'warning_level': True,
- }
+ 'layout' : True,
+ }
# This class contains all data that must persist over multiple
# invocations of Meson. It is roughly the same thing as
@@ -58,6 +59,7 @@ class CoreData():
self.coverage = options.coverage
self.warning_level = options.warning_level
self.werror = options.werror
+ self.layout = options.layout
self.user_options = {}
self.external_args = {} # These are set from "the outside" with e.g. mesonconf
self.external_link_args = {}
@@ -98,6 +100,8 @@ class CoreData():
return self.mandir
if optname == 'localedir':
return self.localedir
+ if optname == 'layout':
+ return self.layout
raise RuntimeError('Tried to get unknown builtin option %s' % optname)
def load(filename):
diff --git a/interpreter.py b/interpreter.py
index 2d86454..5da6d8b 100644
--- a/interpreter.py
+++ b/interpreter.py
@@ -449,15 +449,22 @@ class GeneratedObjectsHolder(InterpreterObject):
self.held_object = held_object
class BuildTargetHolder(InterpreterObject):
- def __init__(self, target):
+ def __init__(self, target, interp):
super().__init__()
self.held_object = target
+ self.interpreter = interp
self.methods.update({'extract_objects' : self.extract_objects_method,
- 'extract_all_objects' : self.extract_all_objects_method})
+ 'extract_all_objects' : self.extract_all_objects_method,
+ 'get_id': self.get_id_method,
+ 'outdir' : self.outdir_method,
+ })
def is_cross(self):
return self.held_object.is_cross()
+ def outdir_method(self, args, kwargs):
+ return self.interpreter.backend.get_target_dir(self.held_object)
+
def extract_objects_method(self, args, kwargs):
gobjs = self.held_object.extract_objects(args)
return GeneratedObjectsHolder(gobjs)
@@ -466,21 +473,24 @@ class BuildTargetHolder(InterpreterObject):
gobjs = self.held_object.extract_all_objects()
return GeneratedObjectsHolder(gobjs)
+ def get_id_method(self, args, kwargs):
+ return self.held_object.get_id()
+
class ExecutableHolder(BuildTargetHolder):
- def __init__(self, target):
- super().__init__(target)
+ def __init__(self, target, interp):
+ super().__init__(target, interp)
class StaticLibraryHolder(BuildTargetHolder):
- def __init__(self, target):
- super().__init__(target)
+ def __init__(self, target, interp):
+ super().__init__(target, interp)
class SharedLibraryHolder(BuildTargetHolder):
- def __init__(self, target):
- super().__init__(target)
+ def __init__(self, target, interp):
+ super().__init__(target, interp)
class JarHolder(BuildTargetHolder):
- def __init__(self, target):
- super().__init__(target)
+ def __init__(self, target, interp):
+ super().__init__(target, interp)
class CustomTargetHolder(InterpreterObject):
def __init__(self, object_to_hold):
@@ -806,8 +816,9 @@ class MesonMain(InterpreterObject):
class Interpreter():
- def __init__(self, build, subproject='', subdir='', subproject_dir='subprojects'):
+ def __init__(self, build, backend, subproject='', subdir='', subproject_dir='subprojects'):
self.build = build
+ self.backend = backend
self.subproject = subproject
self.subdir = subdir
self.source_root = build.environment.get_source_dir()
@@ -1176,7 +1187,7 @@ class Interpreter():
os.makedirs(os.path.join(self.build.environment.get_build_dir(), subdir), exist_ok=True)
self.global_args_frozen = True
mlog.log('\nExecuting subproject ', mlog.bold(dirname), '.\n', sep='')
- subi = Interpreter(self.build, dirname, subdir, self.subproject_dir)
+ subi = Interpreter(self.build, self.backend, dirname, subdir, self.subproject_dir)
subi.subprojects = self.subprojects
subi.subproject_stack = self.subproject_stack + [dirname]
@@ -1727,7 +1738,7 @@ class Interpreter():
mlog.debug('Unknown target type:', str(targetholder))
raise RuntimeError('Unreachable code')
target = targetclass(name, self.subdir, self.subproject, is_cross, sources, objs, self.environment, kwargs)
- l = targetholder(target)
+ l = targetholder(target, self)
self.add_target(name, l.held_object)
self.global_args_frozen = True
return l
diff --git a/meson.py b/meson.py
index a17c377..da7b12f 100755
--- a/meson.py
+++ b/meson.py
@@ -28,6 +28,7 @@ parser = argparse.ArgumentParser()
backendlist = ['ninja', 'vs2010', 'xcode']
build_types = ['plain', 'debug', 'debugoptimized', 'release']
+layouts = ['mirror', 'flat']
warning_levels = ['1', '2', '3']
default_warning = '1'
@@ -71,6 +72,8 @@ parser.add_argument('--unity', action='store_true', dest='unity', default=False,
help='unity build')
parser.add_argument('--werror', action='store_true', dest='werror', default=False,\
help='Treat warnings as errors')
+parser.add_argument('--layout', choices=layouts, dest='layout', default='mirror',\
+ help='Build directory layout.')
parser.add_argument('--warnlevel', default=default_warning, dest='warning_level', choices=warning_levels,\
help='Level of compiler warnings to use (larger is more, default is %(default)s)')
parser.add_argument('--cross-file', default=None, dest='cross_file',
@@ -141,24 +144,24 @@ itself as required.'''
else:
mlog.log('Build type:', mlog.bold('native build'))
b = build.Build(env)
- intr = interpreter.Interpreter(b)
- mlog.log('Build machine cpu:', mlog.bold(intr.builtin['build_machine'].cpu_method([], {})))
if env.is_cross_build():
mlog.log('Host machine cpu:', mlog.bold(intr.builtin['host_machine'].cpu_method([], {})))
mlog.log('Target machine cpu:', mlog.bold(intr.builtin['target_machine'].cpu_method([], {})))
- intr.run()
if self.options.backend == 'ninja':
import ninjabackend
- g = ninjabackend.NinjaBackend(b, intr)
+ g = ninjabackend.NinjaBackend(b)
elif self.options.backend == 'vs2010':
import vs2010backend
- g = vs2010backend.Vs2010Backend(b, intr)
+ g = vs2010backend.Vs2010Backend(b)
elif self.options.backend == 'xcode':
import xcodebackend
- g = xcodebackend.XCodeBackend(b, intr)
+ g = xcodebackend.XCodeBackend(b)
else:
raise RuntimeError('Unknown backend "%s".' % self.options.backend)
- g.generate()
+ intr = interpreter.Interpreter(b, g)
+ mlog.log('Build machine cpu:', mlog.bold(intr.builtin['build_machine'].cpu_method([], {})))
+ intr.run()
+ g.generate(intr)
env.generating_finished()
dumpfile = os.path.join(env.get_scratch_dir(), 'build.dat')
pickle.dump(b, open(dumpfile, 'wb'))
diff --git a/mesonconf.py b/mesonconf.py
index 608661e..db526b0 100755
--- a/mesonconf.py
+++ b/mesonconf.py
@@ -18,7 +18,7 @@ import sys, os
import pickle
import argparse
import coredata, optinterpreter
-from meson import build_types, warning_levels
+from meson import build_types, layouts, warning_levels
parser = argparse.ArgumentParser()
@@ -80,6 +80,10 @@ class Conf:
if v not in build_types:
raise ConfException('Invalid build type %s.' % v)
self.coredata.buildtype = v
+ elif k == 'layout':
+ if v not in layouts:
+ raise ConfException('Invalid layout type %s.' % v)
+ self.coredata.layout = v
elif k == 'warnlevel':
if not v in warning_levels:
raise ConfException('Invalid warning level %s.' % v)
diff --git a/modules/gnome.py b/modules/gnome.py
index ac68515..231cbd4 100644
--- a/modules/gnome.py
+++ b/modules/gnome.py
@@ -139,15 +139,15 @@ class GnomeModule:
inc_dirs = kwargs.pop('include_directories')
if not isinstance(inc_dirs, list):
inc_dirs = [inc_dirs]
- for id in inc_dirs:
- if isinstance(id.held_object, build.IncludeDirs):
- scan_command += ['--add-include-path=%s' % inc for inc in id.held_object.get_incdirs()]
+ for ind in inc_dirs:
+ if isinstance(ind.held_object, build.IncludeDirs):
+ scan_command += ['--add-include-path=%s' % inc for inc in ind.held_object.get_incdirs()]
else:
raise MesonException('Gir include dirs should be include_directories()')
if isinstance(girtarget, build.Executable):
scan_command += ['--program', girtarget]
elif isinstance(girtarget, build.SharedLibrary):
- scan_command += ["-L", os.path.join (state.environment.get_build_dir(), girtarget.subdir)]
+ scan_command += ["-L@PRIVATE_OUTDIR_ABS_%s@" % girtarget.get_id()]
libname = girtarget.get_basename()
scan_command += ['--library', libname]
scankwargs = {'output' : girfile,
@@ -163,9 +163,9 @@ class GnomeModule:
typelib_output = '%s-%s.typelib' % (ns, nsversion)
typelib_cmd = ['g-ir-compiler', scan_target, '--output', '@OUTPUT@']
if inc_dirs:
- for id in inc_dirs:
+ for incd in inc_dirs:
typelib_cmd += ['--includedir=%s' % inc for inc in
- id.held_object.get_incdirs()]
+ incd.held_object.get_incdirs()]
if deps:
for dep in deps:
girdir = dep.held_object.get_variable ("girdir")
@@ -248,7 +248,7 @@ class GnomeModule:
cmd += ['--interface-prefix', kwargs.pop('interface_prefix')]
if 'namespace' in kwargs:
cmd += ['--c-namespace', kwargs.pop('namespace')]
- cmd += ['--generate-c-code', os.path.join(state.subdir, namebase), '@INPUT@']
+ cmd += ['--generate-c-code', '@OUTDIR@/' + namebase, '@INPUT@']
outputs = [namebase + '.c', namebase + '.h']
custom_kwargs = {'input' : xml_file,
'output' : outputs,
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)
diff --git a/run_tests.py b/run_tests.py
index 7d5f92f..f6a6a81 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -172,7 +172,7 @@ def run_test_inprocess(testdir):
return (returncode, mystdout.getvalue(), mystderr.getvalue())
-def run_test(testdir, should_succeed):
+def run_test(testdir, extra_args, should_succeed):
global compile_commands
mlog.shutdown() # Close the log file because otherwise Windows wets itself.
shutil.rmtree(test_build_dir)
@@ -182,7 +182,7 @@ def run_test(testdir, should_succeed):
print('Running test: ' + testdir)
gen_start = time.time()
gen_command = [meson_command, '--prefix', '/usr', '--libdir', 'lib', testdir, test_build_dir]\
- + unity_flags + backend_flags
+ + unity_flags + backend_flags + extra_args
(returncode, stdo, stde) = run_configure_inprocess(gen_command)
gen_time = time.time() - gen_start
if not should_succeed:
@@ -255,7 +255,7 @@ def detect_tests_to_run():
all_tests.append(('fortran', gather_tests('test cases/fortran'), False if shutil.which('gfortran') else True))
return all_tests
-def run_tests():
+def run_tests(extra_args):
all_tests = detect_tests_to_run()
logfile = open('meson-test-run.txt', 'w', encoding="utf_8")
junit_root = ET.Element('testsuites')
@@ -290,7 +290,7 @@ def run_tests():
skipped_tests += 1
else:
ts = time.time()
- result = run_test(t, name != 'failing')
+ result = run_test(t, extra_args, name != 'failing')
te = time.time()
conf_time += result.conftime
build_time += result.buildtime
@@ -351,6 +351,8 @@ def generate_prebuilt_object():
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Run the test suite of Meson.")
+ parser.add_argument('extra_args', nargs='*',
+ help='arguments that are passed directly to Meson (remember to have -- before these).')
parser.add_argument('--backend', default=None, dest='backend',
choices = backendlist)
options = parser.parse_args()
@@ -362,7 +364,7 @@ if __name__ == '__main__':
check_format()
pbfile = generate_prebuilt_object()
try:
- run_tests()
+ run_tests(options.extra_args)
except StopException:
pass
os.unlink(pbfile)
diff --git a/test cases/common/57 custom target chain/meson.build b/test cases/common/57 custom target chain/meson.build
index 7bfcddb..f53206e 100644
--- a/test cases/common/57 custom target chain/meson.build
+++ b/test cases/common/57 custom target chain/meson.build
@@ -5,17 +5,15 @@ python = find_program('python3')
comp = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler.py')
comp2 = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler2.py')
infile = '@0@/@1@'.format(meson.current_source_dir(), 'data_source.txt')
-outfile = '@0@/@1@'.format(meson.current_build_dir(), 'data.dat')
-outfile2 = '@0@/@1@'.format(meson.current_build_dir(), 'data2.dat')
mytarget = custom_target('bindat',
-output : 'data.dat',
-command : [python, comp, infile, outfile],
+ output : 'data.dat',
+ command : [python, comp, infile, '@OUTPUT@'],
)
mytarget2 = custom_target('bindat2',
-output : 'data2.dat',
-command : [python, comp2, mytarget, outfile2],
-install : true,
-install_dir : 'subdir'
+ output : 'data2.dat',
+ command : [python, comp2, mytarget, '@OUTPUT@'],
+ install : true,
+ install_dir : 'subdir'
)
diff --git a/test cases/common/61 custom target source output/meson.build b/test cases/common/61 custom target source output/meson.build
index ae65055..f9d039d 100644
--- a/test cases/common/61 custom target source output/meson.build
+++ b/test cases/common/61 custom target source output/meson.build
@@ -2,7 +2,7 @@ project('source generation', 'c')
ct = custom_target('gen',
output : ['mylib.h', 'mylib.c'],
-command : [find_program('generator.py'), meson.current_build_dir()],
+command : [find_program('generator.py'), '@OUTDIR@'],
)
e = executable('prog', 'main.c', ct)
diff --git a/test cases/common/65 multiple generators/meson.build b/test cases/common/65 multiple generators/meson.build
index b6fd038..66f7fa9 100644
--- a/test cases/common/65 multiple generators/meson.build
+++ b/test cases/common/65 multiple generators/meson.build
@@ -4,10 +4,10 @@ comp = find_program('mygen.py')
subdir('subdir')
generated2 = custom_target('generated2',
-output : ['source2.h', 'source2.cpp'],
-input : 'data2.dat',
-command : [comp, '@INPUT0@', meson.current_build_dir()])
+ output : ['source2.h', 'source2.cpp'],
+ input : 'data2.dat',
+ command : [comp, '@INPUT0@', '@OUTDIR@'])
exe = executable('prog', 'main.cpp', generated, generated2,
-include_directories : include_directories('subdir'))
-test('generated test', exe)
+ include_directories : include_directories('subdir'))
+ test('generated test', exe)
diff --git a/test cases/common/65 multiple generators/subdir/meson.build b/test cases/common/65 multiple generators/subdir/meson.build
index 49c6248..2456ecb 100644
--- a/test cases/common/65 multiple generators/subdir/meson.build
+++ b/test cases/common/65 multiple generators/subdir/meson.build
@@ -1,4 +1,4 @@
generated = custom_target('generated',
output : ['source1.h', 'source1.cpp'],
input : 'data.dat',
-command : [comp, '@INPUT0@', meson.current_build_dir()])
+command : [comp, '@INPUT0@', '@OUTDIR@'])
diff --git a/test cases/common/78 ctarget dependency/gen2.py b/test cases/common/78 ctarget dependency/gen2.py
index 3f3595b..3a8be7d 100755
--- a/test cases/common/78 ctarget dependency/gen2.py
+++ b/test cases/common/78 ctarget dependency/gen2.py
@@ -1,9 +1,9 @@
#!/usr/bin/env python3
-import sys
+import sys, os
from glob import glob
-files = glob('*.tmp')
+files = glob(os.path.join(sys.argv[1], '*.tmp'))
assert(len(files) == 1)
-open(sys.argv[1], 'w').write(open(files[0], 'r').read())
+open(sys.argv[2], 'w').write(open(files[0], 'r').read())
diff --git a/test cases/common/78 ctarget dependency/meson.build b/test cases/common/78 ctarget dependency/meson.build
index baed2da..cd11951 100644
--- a/test cases/common/78 ctarget dependency/meson.build
+++ b/test cases/common/78 ctarget dependency/meson.build
@@ -16,5 +16,5 @@ command : [g1, '@INPUT@', '@OUTPUT@'])
custom_target('output',
output : 'output.dat',
-command : [g2, '@OUTPUT@'],
+command : [g2, '@OUTDIR@', '@OUTPUT@'],
depends : c1)
diff --git a/test cases/frameworks/7 gnome/gir/meson.build b/test cases/frameworks/7 gnome/gir/meson.build
index 32884db..287c0d7 100644
--- a/test cases/frameworks/7 gnome/gir/meson.build
+++ b/test cases/frameworks/7 gnome/gir/meson.build
@@ -27,6 +27,6 @@ gnome.generate_gir(
test('gobject introspection/c', girexe)
test('gobject introspection/py', find_program('prog.py'),
- env : ['GI_TYPELIB_PATH=@0@'.format(meson.current_build_dir()),
- 'LD_LIBRARY_PATH=@0@'.format(meson.current_build_dir()),
+ env : ['GI_TYPELIB_PATH=' + girlib.outdir(),
+ 'LD_LIBRARY_PATH=' + girlib.outdir(),
])
diff --git a/vs2010backend.py b/vs2010backend.py
index 268615b..e834584 100644
--- a/vs2010backend.py
+++ b/vs2010backend.py
@@ -19,8 +19,8 @@ import xml.dom.minidom
from coredata import MesonException
class Vs2010Backend(backends.Backend):
- def __init__(self, build, interp):
- super().__init__(build, interp)
+ def __init__(self, build):
+ super().__init__(build)
self.project_file_version = '10.0.30319.1'
# foo.c compiles to foo.obj, not foo.c.obj
self.source_suffix_in_obj = False
@@ -40,17 +40,17 @@ class Vs2010Backend(backends.Backend):
base_args = generator.get_arglist()
for i in range(len(infilelist)):
if len(infilelist) == len(outfilelist):
- 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.environment.get_source_dir(), 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]
all_output_files += outfiles
args = [x.replace("@INPUT@", infilename).replace('@OUTPUT@', sole_output)\
for x in base_args]
- args = [x.replace("@SOURCE_DIR@", self.environment.get_source_dir()).replace("@BUILD_DIR@", self.get_target_private_dir(target))
+ args = [x.replace("@SOURCE_DIR@", self.environment.get_source_dir()).replace("@BUILD_DIR@", self.get_target_private_dir_abs(target))
for x in args]
fullcmd = [exe_file] + args
cbs = ET.SubElement(idgroup, 'CustomBuildStep')
@@ -62,7 +62,8 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(pg, 'CustomBuildBeforeTargets').text = 'ClCompile'
return all_output_files
- def generate(self):
+ def generate(self, interp):
+ self.interpreter = interp
self.generate_pkgconfig_files()
sln_filename = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.sln')
projlist = self.generate_projects()
@@ -221,7 +222,7 @@ class Vs2010Backend(backends.Backend):
clconf = ET.SubElement(compiles, 'ClCompile')
opt = ET.SubElement(clconf, 'Optimization')
opt.text = 'disabled'
- inc_dirs = [proj_to_src_dir, self.get_target_private_dir(target)]
+ inc_dirs = [proj_to_src_dir, self.get_target_private_dir_abs(target)]
cur_dir = target.subdir
if cur_dir == '':
cur_dir= '.'
diff --git a/xcodebackend.py b/xcodebackend.py
index a5df6a5..847b5af 100644
--- a/xcodebackend.py
+++ b/xcodebackend.py
@@ -19,8 +19,8 @@ import uuid, os, sys
from coredata import MesonException
class XCodeBackend(backends.Backend):
- def __init__(self, build, interp):
- super().__init__(build, interp)
+ def __init__(self, build):
+ super().__init__(build)
self.project_uid = self.environment.coredata.guid.replace('-', '')[:24]
self.project_conflist = self.gen_id()
self.indent = ' '
@@ -61,7 +61,8 @@ class XCodeBackend(backends.Backend):
if not text.endswith('\n'):
self.ofile.write('\n')
- def generate(self):
+ def generate(self, interp):
+ self.interpreter = interp
self.serialise_tests()
self.generate_filemap()
self.generate_buildmap()