aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/backend
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/backend')
-rw-r--r--mesonbuild/backend/backends.py42
-rw-r--r--mesonbuild/backend/ninjabackend.py21
-rw-r--r--mesonbuild/backend/vs2010backend.py5
-rw-r--r--mesonbuild/backend/xcodebackend.py7
4 files changed, 63 insertions, 12 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 209c977..19f50ad 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -34,6 +34,18 @@ class InstallData():
self.install_scripts = []
self.install_subdirs = []
+class ExecutableSerialisation():
+ def __init__(self, name, fname, cmd_args, env, is_cross, exe_wrapper,
+ workdir, extra_paths):
+ self.name = name
+ self.fname = fname
+ self.cmd_args = cmd_args
+ self.env = env
+ self.is_cross = is_cross
+ self.exe_runner = exe_wrapper
+ self.workdir = workdir
+ self.extra_paths = extra_paths
+
class TestSerialisation:
def __init__(self, name, suite, fname, is_cross, exe_wrapper, is_parallel, cmd_args, env,
should_fail, valgrind_args, timeout, workdir, extra_paths):
@@ -154,6 +166,35 @@ class Backend():
raise MesonException('Unknown data type in object list.')
return obj_list
+ def serialise_executable(self, exe, cmd_args, workdir, env={}):
+ import uuid
+ # Can't just use exe.name here; it will likely be run more than once
+ scratch_file = 'meson_exe_{0}_{1}.dat'.format(exe.name,
+ str(uuid.uuid4())[:8])
+ exe_data = os.path.join(self.environment.get_scratch_dir(), scratch_file)
+ with open(exe_data, 'wb') as f:
+ if isinstance(exe, dependencies.ExternalProgram):
+ exe_fullpath = exe.fullpath
+ else:
+ exe_fullpath = [os.path.join(self.environment.get_build_dir(),
+ self.get_target_filename(exe))]
+ is_cross = self.environment.is_cross_build() and \
+ self.environment.cross_info.need_cross_compiler() and \
+ self.environment.cross_info.need_exe_wrapper()
+ if is_cross:
+ exe_wrapper = self.environment.cross_info.config['binaries'].get('exe_wrapper', None)
+ else:
+ exe_wrapper = None
+ if mesonlib.is_windows():
+ extra_paths = self.determine_windows_extra_paths(exe)
+ else:
+ extra_paths = []
+ es = ExecutableSerialisation(exe.name, exe_fullpath, cmd_args, env,
+ is_cross, exe_wrapper, workdir,
+ extra_paths)
+ pickle.dump(es, f)
+ return exe_data
+
def serialise_tests(self):
test_data = os.path.join(self.environment.get_scratch_dir(), 'meson_test_setup.dat')
datafile = open(test_data, 'wb')
@@ -163,6 +204,7 @@ class Backend():
datafile = open(benchmark_data, 'wb')
self.write_benchmark_file(datafile)
datafile.close()
+ return (test_data, benchmark_data)
def has_source_suffix(self, target, suffix):
for s in target.get_sources():
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 9ec10f5..5a21a6c 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -341,6 +341,7 @@ int dummy;
def generate_custom_target(self, target, outfile):
(srcs, ofilenames, cmd) = self.eval_custom_target_command(target)
deps = []
+ desc = 'Generating {0} with a {1} command.'
for i in target.get_dependencies():
# FIXME, should not grab element at zero but rather expand all.
if isinstance(i, list):
@@ -364,9 +365,23 @@ int dummy;
tmp = [tmp]
for fname in tmp:
elem.add_dep(os.path.join(self.get_target_dir(d), fname))
+ # Windows doesn't have -rpath, so for EXEs that need DLLs built within
+ # the project, we need to set PATH so the DLLs are found. We use
+ # a serialized executable wrapper for that and check if the
+ # CustomTarget command needs extra paths first.
+ if mesonlib.is_windows() and \
+ self.determine_windows_extra_paths(target.command[0]):
+ exe_data = self.serialise_executable(target.command[0], cmd[1:],
+ # All targets are built from the build dir
+ self.environment.get_build_dir())
+ cmd = [sys.executable, self.environment.get_build_command(),
+ '--internal', 'exe', exe_data]
+ cmd_type = 'meson_exe.py custom'
+ else:
+ cmd_type = 'custom'
elem.add_item('COMMAND', cmd)
- elem.add_item('description', 'Generating %s with a custom command.' % target.name)
+ elem.add_item('description', desc.format(target.name, cmd_type))
elem.write(outfile)
self.processed_targets[target.name + target.type_suffix()] = True
@@ -582,10 +597,9 @@ int dummy;
elem.write(outfile)
def generate_tests(self, outfile):
- self.serialise_tests()
+ (test_data, benchmark_data) = self.serialise_tests()
valgrind = environment.find_valgrind()
script_root = self.environment.get_script_dir()
- test_data = os.path.join(self.environment.get_scratch_dir(), 'meson_test_setup.dat')
cmd = [ sys.executable, self.environment.get_build_command(), '--internal', 'test' ]
if not self.environment.coredata.get_builtin_option('stdsplit'):
cmd += ['--no-stdsplit']
@@ -608,7 +622,6 @@ int dummy;
# And then benchmarks.
benchmark_script = os.path.join(script_root, 'meson_benchmark.py')
- benchmark_data = os.path.join(self.environment.get_scratch_dir(), 'meson_benchmark_setup.dat')
cmd = [sys.executable, self.environment.get_build_command(), '--internal', 'benchmark', benchmark_data]
elem = NinjaBuildElement(self.all_outputs, 'benchmark', 'CUSTOM_COMMAND', ['all', 'PHONY'])
elem.add_item('COMMAND', cmd)
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 09bc8bb..82d0dc9 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -788,7 +788,6 @@ if %%errorlevel%% neq 0 goto :VCEnd'''
ET.SubElement(midl, 'ProxyFileName').text = '%(Filename)_p.c'
postbuild = ET.SubElement(action, 'PostBuildEvent')
ET.SubElement(postbuild, 'Message')
- test_data = os.path.join(self.environment.get_scratch_dir(), 'meson_test_setup.dat')
test_command = [sys.executable,
self.environment.get_build_command(),
'--internal',
@@ -802,14 +801,12 @@ endlocal & call :cmErrorLevel %%errorlevel%% & goto :cmDone
exit /b %%1
:cmDone
if %%errorlevel%% neq 0 goto :VCEnd'''
+ test_data = self.serialise_tests()[0]
ET.SubElement(postbuild, 'Command').text =\
cmd_templ % ('" "'.join(test_command), test_data)
ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets')
tree = ET.ElementTree(root)
tree.write(ofname, encoding='utf-8', xml_declaration=True)
- datafile = open(test_data, 'wb')
- self.serialise_tests()
- datafile.close()
# ElementTree can not do prettyprinting so do it manually
#doc = xml.dom.minidom.parse(ofname)
#open(ofname, 'w').write(doc.toprettyxml())
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index 6bda826..0ce90ce 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -64,7 +64,7 @@ class XCodeBackend(backends.Backend):
def generate(self, interp):
self.interpreter = interp
- self.serialise_tests()
+ test_data = self.serialise_tests()[0]
self.generate_filemap()
self.generate_buildmap()
self.generate_buildstylemap()
@@ -92,7 +92,7 @@ class XCodeBackend(backends.Backend):
self.generate_pbx_group()
self.generate_pbx_native_target()
self.generate_pbx_project()
- self.generate_pbx_shell_build_phase()
+ self.generate_pbx_shell_build_phase(test_data)
self.generate_pbx_sources_build_phase()
self.generate_pbx_target_dependency()
self.generate_xc_build_configuration()
@@ -480,7 +480,7 @@ class XCodeBackend(backends.Backend):
self.write_line('};')
self.ofile.write('/* End PBXProject section */\n')
- def generate_pbx_shell_build_phase(self):
+ def generate_pbx_shell_build_phase(self, test_data):
self.ofile.write('\n/* Begin PBXShellScriptBuildPhase section */\n')
self.write_line('%s = {' % self.test_command_id)
self.indent_level += 1
@@ -496,7 +496,6 @@ class XCodeBackend(backends.Backend):
self.write_line('shellPath = /bin/sh;')
script_root = self.environment.get_script_dir()
test_script = os.path.join(script_root, 'meson_test.py')
- test_data = os.path.join(self.environment.get_scratch_dir(), 'meson_test_setup.dat')
cmd = [sys.executable, test_script, test_data, '--wd', self.environment.get_build_dir()]
cmdstr = ' '.join(["'%s'" % i for i in cmd])
self.write_line('shellScript = "%s";' % cmdstr)