From d57dd1092e84e08ee15d7063b6c56bd6d864f2e1 Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Mon, 18 Mar 2019 16:16:56 +0000 Subject: [PATCH 1/4] load_configs: generalise the search path Instead of hard-coding the fact that load_configs() searches for files under meson/native, pass in the subdirectory allowing the cross-file code to use the same logic. --- mesonbuild/coredata.py | 6 +++--- mesonbuild/environment.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index fba90fa36..6e60917d1 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -211,8 +211,8 @@ class UserFeatureOption(UserComboOption): return self.value == 'auto' -def load_configs(filenames): - """Load native files.""" +def load_configs(filenames, subdir): + """Load configuration files from a named subdirectory.""" def gen(): for f in filenames: f = os.path.expanduser(os.path.expandvars(f)) @@ -225,7 +225,7 @@ def load_configs(filenames): 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', 'native', f) + path_to_try = os.path.join(path, 'meson', subdir, f) if os.path.isfile(path_to_try): yield path_to_try break diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 58adb0696..92a00dd7b 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -408,7 +408,7 @@ class Environment: if self.coredata.config_files is not None: config = MesonConfigFile.from_config_parser( - coredata.load_configs(self.coredata.config_files)) + coredata.load_configs(self.coredata.config_files, 'native')) self.binaries.build = BinaryTable(config.get('binaries', {})) self.paths.build = Directories(**config.get('paths', {})) From 65e59c84a198062f21ab68fdae41b3e5de8d8480 Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Mon, 18 Mar 2019 17:27:57 +0000 Subject: [PATCH 2/4] mesonbuild: allow multiple --cross-file options Just like --native-file, allow multiple --cross-file options. This is mostly unifying the logic between cross_files and config_files. --- .../markdown/snippets/multiple-cross-files.md | 3 ++ mesonbuild/backend/backends.py | 3 +- mesonbuild/coredata.py | 52 +++---------------- mesonbuild/environment.py | 5 +- mesonbuild/msetup.py | 4 +- mesonbuild/munstable_coredata.py | 5 +- 6 files changed, 20 insertions(+), 52 deletions(-) create mode 100644 docs/markdown/snippets/multiple-cross-files.md diff --git a/docs/markdown/snippets/multiple-cross-files.md b/docs/markdown/snippets/multiple-cross-files.md new file mode 100644 index 000000000..de229be19 --- /dev/null +++ b/docs/markdown/snippets/multiple-cross-files.md @@ -0,0 +1,3 @@ +## Multipe cross files can be specified + +`--cross-file` can be passed multiple times, with the configuration files overlaying the same way as `--native-file`. diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 4d35d223d..5b270d3d3 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -788,8 +788,7 @@ class Backend: deps = [os.path.join(self.build_to_src, df) for df in self.interpreter.get_build_def_files()] if self.environment.is_cross_build(): - deps.append(os.path.join(self.build_to_src, - self.environment.coredata.cross_file)) + deps.extend(self.environment.coredata.cross_files) deps.append('meson-private/coredata.dat') if os.path.exists(os.path.join(self.environment.get_source_dir(), 'meson_options.txt')): deps.append(os.path.join(self.build_to_src, 'meson_options.txt')) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 6e60917d1..cb50961bd 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -265,7 +265,7 @@ class CoreData: self.compiler_options = PerMachine({}, {}, {}) self.base_options = {} self.external_preprocess_args = PerMachine({}, {}, {}) # CPPFLAGS only - self.cross_file = self.__load_cross_file(options.cross_file) + self.cross_files = self.__load_config_files(options.cross_file) self.compilers = OrderedDict() self.cross_compilers = OrderedDict() self.deps = OrderedDict() @@ -276,57 +276,19 @@ class CoreData: @staticmethod def __load_config_files(filenames): + # Need to try and make the passed filenames absolute because when the + # files are parsed later we'll have chdir()d. if not filenames: return [] filenames = [os.path.abspath(os.path.expanduser(os.path.expanduser(f))) for f in filenames] return filenames - @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: - Windows: - - Error - *: - - $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 - - Non-Windows follows the Linux path and will honor XDG_* if set. This - simplifies the implementation somewhat. - """ - 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.isfile(path_to_try): - return path_to_try - if sys.platform != 'win32': - 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.isfile(path_to_try): - return path_to_try - raise MesonException('Cannot find specified cross file: ' + filename) - - raise MesonException('Cannot find specified cross file: ' + filename) - def libdir_cross_fixup(self): # By default set libdir to "lib" when cross compiling since # getting the "system default" is always wrong on multiarch # platforms as it gets a value like lib/x86_64-linux-gnu. - if self.cross_file is not None: + if self.cross_files: self.builtins['libdir'].value = 'lib' def sanitize_prefix(self, prefix): @@ -642,8 +604,8 @@ def read_cmd_line_file(build_dir, options): options.cmd_line_options = d properties = config['properties'] - if options.cross_file is None: - options.cross_file = properties.get('cross_file', None) + if not options.cross_file: + options.cross_file = ast.literal_eval(properties.get('cross_file', '[]')) if not options.native_file: # This will be a string in the form: "['first', 'second', ...]", use # literal_eval to get it into the list of strings. @@ -654,7 +616,7 @@ def write_cmd_line_file(build_dir, options): config = CmdLineFileParser() properties = {} - if options.cross_file is not None: + if options.cross_file: properties['cross_file'] = options.cross_file if options.native_file: properties['native_file'] = options.native_file diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 92a00dd7b..d0dccf44c 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -412,8 +412,9 @@ class Environment: self.binaries.build = BinaryTable(config.get('binaries', {})) self.paths.build = Directories(**config.get('paths', {})) - if self.coredata.cross_file is not None: - config = MesonConfigFile.parse_datafile(self.coredata.cross_file) + if self.coredata.cross_files: + config = MesonConfigFile.from_config_parser( + coredata.load_configs(self.coredata.cross_files, 'cross')) self.properties.host = Properties(config.get('properties', {}), False) self.binaries.host = BinaryTable(config.get('binaries', {}), False) if 'host_machine' in config: diff --git a/mesonbuild/msetup.py b/mesonbuild/msetup.py index 023afdbb0..6e8ca836a 100644 --- a/mesonbuild/msetup.py +++ b/mesonbuild/msetup.py @@ -29,7 +29,9 @@ from .mesonlib import MesonException def add_arguments(parser): coredata.register_builtin_arguments(parser) - parser.add_argument('--cross-file', default=None, + parser.add_argument('--cross-file', + default=[], + action='append', help='File describing cross compilation environment.') parser.add_argument('--native-file', default=[], diff --git a/mesonbuild/munstable_coredata.py b/mesonbuild/munstable_coredata.py index 78f3f3455..913f94214 100644 --- a/mesonbuild/munstable_coredata.py +++ b/mesonbuild/munstable_coredata.py @@ -81,8 +81,9 @@ def run(options): print('Last seen PKGCONFIG enviroment variable value: ' + v) elif k == 'version': print('Meson version: ' + v) - elif k == 'cross_file': - print('Cross File: ' + (v or 'None')) + elif k == 'cross_files': + if v: + print('Cross File: ' + ' '.join(v)) elif k == 'config_files': if v: print('Native File: ' + ' '.join(v)) From 1a2b5d3b536c7d997adb43d47b7cc1249a36b3db Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Mon, 18 Mar 2019 16:18:09 +0000 Subject: [PATCH 3/4] run_unittest: update for cross_file being a list --- run_unittests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run_unittests.py b/run_unittests.py index 0b2164fe6..24dda8b31 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -612,7 +612,7 @@ class InternalTests(unittest.TestCase): configfile.flush() configfile.close() opts = get_fake_options() - opts.cross_file = configfilename + opts.cross_file = (configfilename,) env = get_fake_env(opts=opts) detected_value = env.need_exe_wrapper() os.unlink(configfilename) @@ -627,7 +627,7 @@ class InternalTests(unittest.TestCase): config.write(configfile) configfile.close() opts = get_fake_options() - opts.cross_file = configfilename + opts.cross_file = (configfilename,) env = get_fake_env(opts=opts) forced_value = env.need_exe_wrapper() os.unlink(configfilename) From a87b51f75cd81d89214c3ba6d36a3645b641b5aa Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Thu, 14 Mar 2019 16:56:52 +0000 Subject: [PATCH 4/4] Add test case for multiple cross files --- run_unittests.py | 19 +++++++++++++++++++ .../unit/57 native file override/crossfile2 | 4 ++++ 2 files changed, 23 insertions(+) create mode 100644 test cases/unit/57 native file override/crossfile2 diff --git a/run_unittests.py b/run_unittests.py index 24dda8b31..44129dcb7 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -5871,6 +5871,25 @@ class CrossFileTests(BasePlatformTests): '-Ddef_sharedstatedir=sharedstatebar', '-Ddef_sysconfdir=sysconfbar']) + def test_cross_file_dirs_chain(self): + # crossfile2 overrides crossfile overrides nativefile + testcase = os.path.join(self.unit_test_dir, '57 native file override') + self.init(testcase, default_args=False, + extra_args=['--native-file', os.path.join(testcase, 'nativefile'), + '--cross-file', os.path.join(testcase, 'crossfile'), + '--cross-file', os.path.join(testcase, 'crossfile2'), + '-Ddef_bindir=binbar2', + '-Ddef_datadir=databar', + '-Ddef_includedir=includebar', + '-Ddef_infodir=infobar', + '-Ddef_libdir=libbar', + '-Ddef_libexecdir=libexecbar', + '-Ddef_localedir=localebar', + '-Ddef_localstatedir=localstatebar', + '-Ddef_mandir=manbar', + '-Ddef_sbindir=sbinbar', + '-Ddef_sharedstatedir=sharedstatebar', + '-Ddef_sysconfdir=sysconfbar']) class TAPParserTests(unittest.TestCase): def assert_test(self, events, **kwargs): diff --git a/test cases/unit/57 native file override/crossfile2 b/test cases/unit/57 native file override/crossfile2 new file mode 100644 index 000000000..70946c9e7 --- /dev/null +++ b/test cases/unit/57 native file override/crossfile2 @@ -0,0 +1,4 @@ +[paths] +bindir = 'binbar2' + +; vim: ft=dosini