aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOle André Vadla RavnÄs <oleavr@gmail.com>2017-05-22 00:53:41 +0200
committerOle André Vadla RavnÄs <oleavr@gmail.com>2017-05-29 21:05:57 +0200
commitb32c757073c3227a05d770ec56d953f5aac663d0 (patch)
tree8e0fcabd9a4e69d02cf486842ee7b9d8314f63b5
parent0f85d9f66d85a6cca7e57dba6a9590a3bdbac57d (diff)
downloadmeson-b32c757073c3227a05d770ec56d953f5aac663d0.zip
meson-b32c757073c3227a05d770ec56d953f5aac663d0.tar.gz
meson-b32c757073c3227a05d770ec56d953f5aac663d0.tar.bz2
environment: Add needs_exe_wrapper for overriding auto-detection.
This is useful when build_machine appears to be compatible with host_machine, but actually isn't. For example when: - build_machine is macOS and host_machine is the iOS Simulator - the build_machine's libc is glibc but the host_machine libc is uClibc - code relies on kernel features not available on the build_machine
-rw-r--r--docs/markdown/Cross-compilation.md7
-rw-r--r--docs/markdown/Release-notes-for-0.41.0.md9
-rw-r--r--mesonbuild/environment.py3
-rwxr-xr-xrun_unittests.py30
4 files changed, 49 insertions, 0 deletions
diff --git a/docs/markdown/Cross-compilation.md b/docs/markdown/Cross-compilation.md
index c6817eb..b7ef354 100644
--- a/docs/markdown/Cross-compilation.md
+++ b/docs/markdown/Cross-compilation.md
@@ -58,6 +58,13 @@ c_link_args = ['-some_link_arg']
In most cases you don't need the size and alignment settings, Meson will detect all these by compiling and running some sample programs. If your build requires some piece of data that is not listed here, Meson will stop and write an error message describing how to fix the issue. If you need extra compiler arguments to be used during cross compilation you can set them with `[langname]_args = [args]`. Just remember to specify the args as an array and not as a single string (i.e. not as `'-DCROSS=1 -DSOMETHING=3'`).
+One important thing to note, if you did not define an `exe_wrapper` in the previous section, is that Meson will make a best-effort guess at whether it can run the generated binaries on the build machine. It determines whether this is possible by looking at the `system` and `cpu_family` of build vs host. There will however be cases where they do match up, but the build machine is actually not compatible with the host machine. Typically this will happen if the libc used by the build and host machines are incompatible, or the code relies on kernel features not available on the build machine. One concrete example is a macOS build machine producing binaries for an iOS Simulator x86-64 host. They're both `darwin` and the same architecture, but their binaries are not actually compatible. In such cases you may use the `needs_exe_wrapper` property to override the auto-detection:
+
+```ini
+[properties]
+needs_exe_wrapper = true
+```
+
The last bit is the definition of host and target machines. Every cross build definition must have one or both of them. If it had neither, the build would not be a cross build but a native build. You do not need to define the build machine, as all necessary information about it is extracted automatically. The definitions for host and target machines look the same. Here is a sample for host machine.
```ini
diff --git a/docs/markdown/Release-notes-for-0.41.0.md b/docs/markdown/Release-notes-for-0.41.0.md
index 7da9ed7..40f3839 100644
--- a/docs/markdown/Release-notes-for-0.41.0.md
+++ b/docs/markdown/Release-notes-for-0.41.0.md
@@ -61,3 +61,12 @@ Targets for building rust now take a `rust_args` keyword.
Code coverage can be generated for tests by passing the `--cov` argument to
the `run_tests.py` test runner. Note, since multiple processes are used,
coverage must be combined before producing a report (`coverage3 combine`.)
+
+## Cross-config property for overriding whether an exe wrapper is needed
+
+The new `needs_exe_wrapper` property allows overriding auto-detection for
+cases where `build_machine` appears to be compatible with `host_machine`,
+but actually isn't. For example when:
+- `build_machine` is macOS and `host_machine` is the iOS Simulator
+- the `build_machine`'s libc is glibc but the `host_machine` libc is uClibc
+- code relies on kernel features not available on the `build_machine`
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index bf58472..d07bb1d 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -906,6 +906,9 @@ class CrossBuildInfo:
return 'host_machine' in self.config
def need_exe_wrapper(self):
+ value = self.config['properties'].get('needs_exe_wrapper', None)
+ if value is not None:
+ return value
# Can almost always run 32-bit binaries on 64-bit natively if the host
# and build systems are the same. We don't pass any compilers to
# detect_cpu_family() here because we always want to know the OS
diff --git a/run_unittests.py b/run_unittests.py
index e3b7c5c..b85ad8a 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -22,6 +22,7 @@ import os
import shutil
import sys
import unittest
+from configparser import ConfigParser
from glob import glob
from pathlib import PurePath
import mesonbuild.compilers
@@ -323,6 +324,35 @@ class InternalTests(unittest.TestCase):
cmd = ['@OUTPUT@.out', 'ordinary', 'strings']
self.assertRaises(ME, substfunc, cmd, d)
+ def test_needs_exe_wrapper_override(self):
+ config = ConfigParser()
+ config['binaries'] = {
+ 'c': '\'/usr/bin/gcc\'',
+ }
+ config['host_machine'] = {
+ 'system': '\'linux\'',
+ 'cpu_family': '\'arm\'',
+ 'cpu': '\'armv7\'',
+ 'endian': '\'little\'',
+ }
+
+ with tempfile.NamedTemporaryFile(mode='w+') as configfile:
+ config.write(configfile)
+ configfile.flush()
+ detected_value = mesonbuild.environment.CrossBuildInfo(configfile.name).need_exe_wrapper()
+
+ desired_value = not detected_value
+ config['properties'] = {
+ 'needs_exe_wrapper': 'true' if desired_value else 'false'
+ }
+
+ with tempfile.NamedTemporaryFile(mode='w+') as configfile:
+ config.write(configfile)
+ configfile.flush()
+ forced_value = mesonbuild.environment.CrossBuildInfo(configfile.name).need_exe_wrapper()
+
+ self.assertEqual(forced_value, desired_value)
+
class BasePlatformTests(unittest.TestCase):
def setUp(self):