aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Cross-compilation.md26
-rw-r--r--docs/markdown/snippets/system-wide-cross-files.md20
-rw-r--r--mesonbuild/coredata.py46
-rwxr-xr-xrun_unittests.py46
4 files changed, 134 insertions, 4 deletions
diff --git a/docs/markdown/Cross-compilation.md b/docs/markdown/Cross-compilation.md
index f68b1f5..c1ad317 100644
--- a/docs/markdown/Cross-compilation.md
+++ b/docs/markdown/Cross-compilation.md
@@ -257,3 +257,29 @@ then you can access that using the `meson` object like this:
myvar = meson.get_cross_property('somekey')
# myvar now has the value 'somevalue'
```
+
+## Cross file locations
+
+As of version 0.44.0 meson supports loading cross files from system locations
+on Linux and the BSDs. This will be $XDG_DATA_DIRS/meson/cross, or if
+XDG_DATA_DIRS is undefined, then /usr/local/share/meson/cross and
+/usr/share/meson/cross will be tried in that order, for system wide cross
+files. User local files can be put in $XDG_DATA_HOME/meson/cross, or
+~/.local/share/meson/cross if that is undefined.
+
+The order of locations tried is as follows:
+ - A file relative to the local dir
+ - The user local location
+ - The system wide locations in order
+
+Linux and BSD distributions are encouraged to ship cross files either with
+their cross compiler toolchain packages or as a standalone package, and put
+them in one of the system paths referenced above.
+
+These files can be loaded automatically without adding a path to the cross
+file. For example, if a ~/.local/share/meson/cross contains a file called x86-linux,
+then the following command would start a cross build using that cross files:
+
+```sh
+meson builddir/ --cross-file x86-linux
+```
diff --git a/docs/markdown/snippets/system-wide-cross-files.md b/docs/markdown/snippets/system-wide-cross-files.md
new file mode 100644
index 0000000..66c454f
--- /dev/null
+++ b/docs/markdown/snippets/system-wide-cross-files.md
@@ -0,0 +1,20 @@
+## System wide and user local cross files
+
+Meson has gained the ability to load cross files from predefined locations
+without passing a full path on Linux and the BSD OSes. User local files will be
+loaded from `$XDG_DATA_HOME/meson/cross`, or if XDG_DATA_HOME is undefined,
+`~/.local/share/meson/cross` will be used.
+
+For system wide paths the values of `$XDG_DATA_DIRS` + `/meson/cross` will be used,
+if XDG_DATA_DIRS is undefined then `/usr/local/share/meson/cross:/usr/share/meson/cross`
+will be used instead.
+
+A file relative to the current working directory will be tried first, then the
+user specific path will be tried before the system wide paths.
+
+Assuming that a file x86-linux is located in one of those places a cross build
+can be started with:
+
+```sh
+meson builddir/ --cross-file x86-linux
+```
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 401211a..68b1abf 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -14,6 +14,7 @@
# limitations under the License.
import pickle, os, uuid
+import sys
from pathlib import PurePath
from collections import OrderedDict
from .mesonlib import MesonException, commonpath
@@ -172,10 +173,7 @@ class CoreData:
self.external_preprocess_args = {} # CPPFLAGS only
self.external_args = {} # CPPFLAGS + CFLAGS
self.external_link_args = {} # CFLAGS + LDFLAGS (with MSVC: only LDFLAGS)
- if options.cross_file is not None:
- self.cross_file = os.path.join(os.getcwd(), options.cross_file)
- else:
- self.cross_file = None
+ self.cross_file = self.__load_cross_file(options.cross_file)
self.wrap_mode = options.wrap_mode
self.compilers = OrderedDict()
self.cross_compilers = OrderedDict()
@@ -184,6 +182,46 @@ class CoreData:
# Only to print a warning if it changes between Meson invocations.
self.pkgconf_envvar = os.environ.get('PKG_CONFIG_PATH', '')
+ @staticmethod
+ def __load_cross_file(filename):
+ """Try to load the cross file.
+
+ If the filename is None return None. If the filename is an absolute
+ (after resolving variables and ~), return that absolute path. Next,
+ check if the file is relative to the current source dir. If the path
+ still isn't resolved do the following:
+ Linux + BSD:
+ - $XDG_DATA_HOME/meson/cross (or ~/.local/share/meson/cross if
+ undefined)
+ - $XDG_DATA_DIRS/meson/cross (or
+ /usr/local/share/meson/cross:/usr/share/meson/cross if undefined)
+ - Error
+ *:
+ - Error
+ BSD follows the Linux path and will honor XDG_* if set. This simplifies
+ the implementation somewhat, especially since most BSD users wont set
+ those environment variables.
+ """
+ if filename is None:
+ return None
+ filename = os.path.expanduser(os.path.expandvars(filename))
+ if os.path.isabs(filename):
+ return filename
+ path_to_try = os.path.abspath(filename)
+ if os.path.exists(path_to_try):
+ return path_to_try
+ if sys.platform == 'linux' or 'bsd' in sys.platform.lower():
+ paths = [
+ os.environ.get('XDG_DATA_HOME', os.path.expanduser('~/.local/share')),
+ ] + os.environ.get('XDG_DATA_DIRS', '/usr/local/share:/usr/share').split(':')
+ for path in paths:
+ path_to_try = os.path.join(path, 'meson', 'cross', filename)
+ if os.path.exists(path_to_try):
+ return path_to_try
+ raise MesonException('Cannot find specified cross file: ' + filename)
+
+ raise MesonException('Cannot find specified cross file: ' + filename)
+
def sanitize_prefix(self, prefix):
if not os.path.isabs(prefix):
raise MesonException('prefix value {!r} must be an absolute path'
diff --git a/run_unittests.py b/run_unittests.py
index 8af872e..5b3b3e1 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -19,10 +19,12 @@ import shlex
import subprocess
import re, json
import tempfile
+import textwrap
import os
import shutil
import sys
import unittest
+from unittest import mock
from configparser import ConfigParser
from glob import glob
from pathlib import PurePath
@@ -2223,6 +2225,50 @@ endian = 'little'
self.init(testdir, ['-Db_lto=true'], default_args=False)
self.build('reconfigure')
+ def test_cross_file_system_paths(self):
+ testdir = os.path.join(self.common_test_dir, '1 trivial')
+ cross_content = textwrap.dedent("""\
+ [binaries]
+ c = '/usr/bin/cc'
+ ar = '/usr/bin/ar'
+ strip = '/usr/bin/ar'
+
+ [properties]
+
+ [host_machine]
+ system = 'linux'
+ cpu_family = 'x86'
+ cpu = 'i686'
+ endian = 'little'
+ """)
+
+ with tempfile.TemporaryDirectory() as d:
+ dir_ = os.path.join(d, 'meson', 'cross')
+ os.makedirs(dir_)
+ with tempfile.NamedTemporaryFile('w', dir=dir_, delete=False) as f:
+ f.write(cross_content)
+ name = os.path.basename(f.name)
+
+ with mock.patch.dict(os.environ, {'XDG_DATA_HOME': d}):
+ self.init(testdir, ['--cross-file=' + name], inprocess=True)
+ self.wipe()
+
+ with mock.patch.dict(os.environ, {'XDG_DATA_DIRS': d}):
+ os.environ.pop('XDG_DATA_HOME', None)
+ self.init(testdir, ['--cross-file=' + name], inprocess=True)
+ self.wipe()
+
+ with tempfile.TemporaryDirectory() as d:
+ dir_ = os.path.join(d, '.local', 'share', 'meson', 'cross')
+ os.makedirs(dir_)
+ with tempfile.NamedTemporaryFile('w', dir=dir_, delete=False) as f:
+ f.write(cross_content)
+ name = os.path.basename(f.name)
+
+ with mock.patch('mesonbuild.coredata.os.path.expanduser', lambda x: x.replace('~', d)):
+ self.init(testdir, ['--cross-file=' + name], inprocess=True)
+ self.wipe()
+
class LinuxArmCrossCompileTests(BasePlatformTests):
'''