diff --git a/data/syntax-highlighting/vim/ftdetect/meson.vim b/data/syntax-highlighting/vim/ftdetect/meson.vim index 3233c58750dc..28e3a29c8df5 100644 --- a/data/syntax-highlighting/vim/ftdetect/meson.vim +++ b/data/syntax-highlighting/vim/ftdetect/meson.vim @@ -1,3 +1,4 @@ au BufNewFile,BufRead meson.build set filetype=meson +au BufNewFile,BufRead meson.options set filetype=meson au BufNewFile,BufRead meson_options.txt set filetype=meson au BufNewFile,BufRead *.wrap set filetype=dosini diff --git a/docs/markdown/snippets/meson_options.md b/docs/markdown/snippets/meson_options.md new file mode 100644 index 000000000000..f9d582ac9236 --- /dev/null +++ b/docs/markdown/snippets/meson_options.md @@ -0,0 +1,7 @@ +## Support for reading options from meson.options + +Support has been added for reading options from `meson.options` instead of +`meson_options.txt`. These are equivalent, but not using the `.txt` extension +for a build file has a few advantages, chief among them many tools and text +editors expect a file with the `.txt` extension to be plain text files, not +build scripts. diff --git a/docs/yaml/functions/dependency.yaml b/docs/yaml/functions/dependency.yaml index 2d9e3665638b..85255b9f143e 100644 --- a/docs/yaml/functions/dependency.yaml +++ b/docs/yaml/functions/dependency.yaml @@ -82,7 +82,7 @@ kwargs: since: 0.38.0 description: | An array of default option values - that override those set in the subproject's `meson_options.txt` + that override those set in the subproject's `meson.options` (like `default_options` in [[project]], they only have effect when Meson is run for the first time, and command line arguments override any default options in build files) diff --git a/docs/yaml/functions/subproject.yaml b/docs/yaml/functions/subproject.yaml index 4d19a31785e6..14a778dd85e3 100644 --- a/docs/yaml/functions/subproject.yaml +++ b/docs/yaml/functions/subproject.yaml @@ -9,7 +9,7 @@ description: | `${MESON_SOURCE_ROOT}/subprojects/foo`. - `default_options` *(since 0.37.0)*: an array of default option values - that override those set in the subproject's `meson_options.txt` + that override those set in the subproject's `meson.options` (like `default_options` in `project`, they only have effect when Meson is run for the first time, and command line arguments override any default options in build files). *(since 0.54.0)*: `default_library` @@ -45,7 +45,7 @@ kwargs: since: 0.37.0 description: | An array of default option values - that override those set in the subproject's `meson_options.txt` + that override those set in the subproject's `meson.options` (like `default_options` in [[project]], they only have effect when Meson is run for the first time, and command line arguments override any default options in build files). *(since 0.54.0)*: `default_library` diff --git a/man/meson.1 b/man/meson.1 index 7e7f486b1c0a..5a4aa6e1ea73 100644 --- a/man/meson.1 +++ b/man/meson.1 @@ -105,7 +105,7 @@ print all top level targets (executables, libraries, etc) print the source files of the given target .TP \fB\-\-buildsystem\-files\fR -print all files that make up the build system (meson.build, meson_options.txt etc) +print all files that make up the build system (meson.build, meson.options, meson_options.txt etc) .TP \fB\-\-tests\fR print all unit tests diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py index 98f03fdfc44c..e811f11dbd8a 100644 --- a/mesonbuild/ast/introspection.py +++ b/mesonbuild/ast/introspection.py @@ -76,7 +76,6 @@ def __init__(self, self.environment = env self.subproject_dir = subproject_dir self.coredata = self.environment.get_coredata() - self.option_file = os.path.join(self.source_root, self.subdir, 'meson_options.txt') self.backend = backend self.default_options = {OptionKey('backend'): self.backend} self.project_data = {} # type: T.Dict[str, T.Any] @@ -113,9 +112,12 @@ def func_project(self, node: BaseNode, args: T.List[TYPE_nvar], kwargs: T.Dict[s proj_vers = 'undefined' self.project_data = {'descriptive_name': proj_name, 'version': proj_vers} - if os.path.exists(self.option_file): + optfile = os.path.join(self.source_root, self.subdir, 'meson.options') + if not os.path.exists(optfile): + optfile = os.path.join(self.source_root, self.subdir, 'meson_options.txt') + if os.path.exists(optfile): oi = optinterpreter.OptionInterpreter(self.subproject) - oi.process(self.option_file) + oi.process(optfile) self.coredata.update_project_options(oi.options) def_opts = self.flatten_args(kwargs.get('default_options', [])) diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py index e4195e25dfcb..b5cf83aca06b 100644 --- a/mesonbuild/backend/xcodebackend.py +++ b/mesonbuild/backend/xcodebackend.py @@ -1025,6 +1025,7 @@ def write_tree(self, objects_dict, tree_node, children_array, current_subdir): group_id = self.write_group_target_entry(objects_dict, target) children_array.add_item(group_id) potentials = [os.path.join(current_subdir, 'meson.build'), + os.path.join(current_subdir, 'meson.options'), os.path.join(current_subdir, 'meson_options.txt')] for bf in potentials: i = self.fileref_ids.get(bf, None) diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index a033c4f3c502..72bc8e22758c 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -23,8 +23,9 @@ from .. import envconfig from ..wrap import wrap, WrapMode from .. import mesonlib -from ..mesonlib import (MesonBugException, HoldableObject, FileMode, MachineChoice, OptionKey, - listify, extract_as_list, has_path_sep, PerMachine) +from ..mesonlib import (MesonBugException, MesonException, HoldableObject, + FileMode, MachineChoice, OptionKey, listify, + extract_as_list, has_path_sep, PerMachine) from ..programs import ExternalProgram, NonExistingExternalProgram from ..dependencies import Dependency from ..depfile import DepFile @@ -290,7 +291,6 @@ def __init__( # be different for dependencies provided by wrap files. self.subproject_directory_name = subdir.split(os.path.sep)[-1] self.subproject_dir = subproject_dir - self.option_file = os.path.join(self.source_root, self.subdir, 'meson_options.txt') self.relaxations = relaxations or set() if not mock and ast is None: self.load_root_meson_file() @@ -1174,11 +1174,27 @@ def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str if kwargs['meson_version']: self.handle_meson_version(kwargs['meson_version'], node) - if os.path.exists(self.option_file): + # Load "meson.options" before "meson_options.txt", and produce a warning if + # it is being used with an old version. I have added check that if both + # exist the warning isn't raised + option_file = os.path.join(self.source_root, self.subdir, 'meson.options') + old_option_file = os.path.join(self.source_root, self.subdir, 'meson_options.txt') + + if os.path.exists(option_file): + if os.path.exists(old_option_file): + if os.path.samefile(option_file, old_option_file): + mlog.debug("Not warning about meson.options with version minimum < 1.1 because meson_options.txt also exists") + else: + raise MesonException("meson.options and meson_options.txt both exist, but are not the same file.") + else: + FeatureNew.single_use('meson.options file', '1.1', self.subproject, 'Use meson_options.txt instead') + else: + option_file = old_option_file + if os.path.exists(option_file): oi = optinterpreter.OptionInterpreter(self.subproject) - oi.process(self.option_file) + oi.process(option_file) self.coredata.update_project_options(oi.options) - self.add_build_def_file(self.option_file) + self.add_build_def_file(option_file) # Do not set default_options on reconfigure otherwise it would override # values previously set from command line. That means that changing diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 68820d6d99d0..184231317e3f 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -329,12 +329,12 @@ def add_keys(options: 'cdata.KeyedOptionDictType', section: str) -> None: return optlist def find_buildsystem_files_list(src_dir: str) -> T.List[str]: + build_files = frozenset({'meson.build', 'meson.options', 'meson_options.txt'}) # I feel dirty about this. But only slightly. - filelist = [] # type: T.List[str] + filelist: T.List[str] = [] for root, _, files in os.walk(src_dir): - for f in files: - if f in {'meson.build', 'meson_options.txt'}: - filelist.append(os.path.relpath(os.path.join(root, f), src_dir)) + filelist.extend(os.path.relpath(os.path.join(root, f), src_dir) + for f in build_files.intersection(files)) return filelist def list_buildsystem_files(builddata: build.Build, interpreter: Interpreter) -> T.List[str]: diff --git a/test cases/warning/9 meson.options/meson.build b/test cases/warning/9 meson.options/meson.build new file mode 100644 index 000000000000..59c3872e26a6 --- /dev/null +++ b/test cases/warning/9 meson.options/meson.build @@ -0,0 +1,3 @@ +project('options too old', meson_version : '>= 0.63') + +subproject('no-warn') diff --git a/test cases/warning/9 meson.options/meson.options b/test cases/warning/9 meson.options/meson.options new file mode 100644 index 000000000000..b84ee83fcccc --- /dev/null +++ b/test cases/warning/9 meson.options/meson.options @@ -0,0 +1 @@ +option('foo', type : 'string') diff --git a/test cases/warning/9 meson.options/subprojects/no-warn/meson.build b/test cases/warning/9 meson.options/subprojects/no-warn/meson.build new file mode 100644 index 000000000000..f86fbf77417f --- /dev/null +++ b/test cases/warning/9 meson.options/subprojects/no-warn/meson.build @@ -0,0 +1 @@ +project('has both no warn', meson_version : '>= 0.63') diff --git a/test cases/warning/9 meson.options/subprojects/no-warn/meson.options b/test cases/warning/9 meson.options/subprojects/no-warn/meson.options new file mode 100644 index 000000000000..b84ee83fcccc --- /dev/null +++ b/test cases/warning/9 meson.options/subprojects/no-warn/meson.options @@ -0,0 +1 @@ +option('foo', type : 'string') diff --git a/test cases/warning/9 meson.options/subprojects/no-warn/meson_options.txt b/test cases/warning/9 meson.options/subprojects/no-warn/meson_options.txt new file mode 120000 index 000000000000..7b28df279f07 --- /dev/null +++ b/test cases/warning/9 meson.options/subprojects/no-warn/meson_options.txt @@ -0,0 +1 @@ +meson.options \ No newline at end of file diff --git a/test cases/warning/9 meson.options/test.json b/test cases/warning/9 meson.options/test.json new file mode 100644 index 000000000000..f711924458e5 --- /dev/null +++ b/test cases/warning/9 meson.options/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "WARNING: Project targets '>= 0.63' but uses feature introduced in '1.1': meson.options file. Use meson_options.txt instead" + } + ] +} diff --git a/unittests/failuretests.py b/unittests/failuretests.py index 54a6c582c9e9..ce58f3f2bc09 100644 --- a/unittests/failuretests.py +++ b/unittests/failuretests.py @@ -78,7 +78,9 @@ def setUp(self): super().setUp() self.srcdir = os.path.realpath(tempfile.mkdtemp()) self.mbuild = os.path.join(self.srcdir, 'meson.build') - self.moptions = os.path.join(self.srcdir, 'meson_options.txt') + self.moptions = os.path.join(self.srcdir, 'meson.options') + if not os.path.exists(self.moptions): + self.moptions = os.path.join(self.srcdir, 'meson_options.txt') def tearDown(self): super().tearDown()