diff --git a/mesonpy/__init__.py b/mesonpy/__init__.py index 7325d23f..42dd06a8 100644 --- a/mesonpy/__init__.py +++ b/mesonpy/__init__.py @@ -899,13 +899,22 @@ def _run(self, cmd: Sequence[str]) -> None: def _configure(self, reconfigure: bool = False) -> None: """Configure Meson project.""" + if reconfigure: + default_build_options = [] + else: + # default build options, overriding Meson's defaults. + # On reconfigure, the values will persist unless the user explicitly + # passes new values for them. + default_build_options = [ + '-Dbuildtype=release', + '-Db_ndebug=if-release', + '-Db_vscrt=md', + ] + setup_args = [ os.fspath(self._source_dir), os.fspath(self._build_dir), - # default build options - '-Dbuildtype=release', - '-Db_ndebug=if-release', - '-Db_vscrt=md', + *default_build_options, # user build options *self._meson_args['setup'], # pass native file last to have it override the python diff --git a/tests/test_options.py b/tests/test_options.py index 2d0ed00f..e30ac895 100644 --- a/tests/test_options.py +++ b/tests/test_options.py @@ -35,3 +35,23 @@ def test_ndebug(package_purelib_and_platlib, tmp_path, args, expected): ['ninja', '-C', os.fspath(project._build_dir), '-t', 'commands', '../plat.c^'], stdout=subprocess.PIPE, check=True).stdout assert (b'-DNDEBUG' in command) == expected + + +def test_default_options(package_purelib_and_platlib, tmp_path, mocker): + meson = mocker.spy(mesonpy.Project, '_run') + + project = mesonpy.Project(package_purelib_and_platlib, tmp_path) + + mesonpy_default_options = {'-Dbuildtype=release', '-Db_ndebug=if-release', '-Db_vscrt=md'} + # Check if default options were passed + assert mesonpy_default_options.issubset(meson.call_args_list[0][0][1]) + + options = {opt['name']: opt['value'] for opt in project._info('intro-buildoptions')} + + # Check if default options have taken effect + assert options['buildtype'] == 'release' + assert options['b_ndebug'] == 'if-release' + + compilers = project._info('intro-compilers') + if compilers['build']['c']['id'] in {'msvc', 'clang-cl', 'intel-cl'}: + assert options['b_vscrt'] == 'md' diff --git a/tests/test_project.py b/tests/test_project.py index 76267964..870e488d 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -332,6 +332,35 @@ def test_invalid_build_dir(package_pure, tmp_path, mocker): assert '--reconfigure' not in meson.call_args_list[0].args[1] project.build() +def test_reconfigure_preserves_config(package_simple, tmp_path): + # initial configuration + project = mesonpy.Project(package_simple, tmp_path, meson_args={ + 'setup': ['-Dbuildtype=debug', '-Dwarning_level=2'], + }) + + initial_options = {opt['name']: opt['value'] for opt in project._info('intro-buildoptions')} + + assert initial_options['buildtype'] == 'debug' + assert initial_options['debug'] is True + assert initial_options['warning_level'] == '2' + + # reconfiguration with a new option + project = mesonpy.Project(package_simple, tmp_path, meson_args={ + 'setup': ['-Doptimization=2'], + }) + + reconfigure_options = {opt['name']: opt['value'] for opt in project._info('intro-buildoptions')} + + assert reconfigure_options['buildtype'] == 'debug' + assert reconfigure_options['debug'] is True + assert reconfigure_options['warning_level'] == '2' + + assert initial_options != reconfigure_options + + initial_options['optimization'] = '2' + assert initial_options == reconfigure_options + + @pytest.mark.skipif(not os.getenv('CI') or sys.platform != 'win32', reason='requires MSVC') def test_compiler(venv, package_detect_compiler, tmp_path):