diff options
| -rw-r--r-- | mesonbuild/templates/cpptemplates.py | 11 | ||||
| -rw-r--r-- | mesonbuild/templates/ctemplates.py | 10 | ||||
| -rw-r--r-- | mesonbuild/templates/dlangtemplates.py | 11 | ||||
| -rw-r--r-- | mesonbuild/templates/javatemplates.py | 12 | ||||
| -rw-r--r-- | mesonbuild/templates/sampleimpl.py | 55 | ||||
| -rw-r--r-- | unittests/allplatformstests.py | 51 |
6 files changed, 112 insertions, 38 deletions
diff --git a/mesonbuild/templates/cpptemplates.py b/mesonbuild/templates/cpptemplates.py index cdfbbf8c0..1c742cfaa 100644 --- a/mesonbuild/templates/cpptemplates.py +++ b/mesonbuild/templates/cpptemplates.py @@ -35,9 +35,12 @@ hello_cpp_meson_template = '''project( dependencies = [{dependencies} ] +sources = [{source_files} +] + exe = executable( '{exe_name}', - '{source_name}', + [sources], install : true, dependencies : dependencies, ) @@ -121,9 +124,13 @@ dependencies = [{dependencies} # not the executables that use the library. lib_args = ['-DBUILDING_{utoken}'] +sources = [{source_files} + +] + lib = library( '{lib_name}', - '{source_file}', + [sources], install : true, cpp_shared_args : lib_args, gnu_symbol_visibility : 'hidden', diff --git a/mesonbuild/templates/ctemplates.py b/mesonbuild/templates/ctemplates.py index 559cef91b..c2db1e5e2 100644 --- a/mesonbuild/templates/ctemplates.py +++ b/mesonbuild/templates/ctemplates.py @@ -71,9 +71,12 @@ lib_args = ['-DBUILDING_{utoken}'] dependencies = [{dependencies} ] +sources = [{source_files} +] + lib = library( '{lib_name}', - '{source_file}', + [sources], install : true, c_shared_args : lib_args, gnu_symbol_visibility : 'hidden', @@ -133,9 +136,12 @@ hello_c_meson_template = '''project( dependencies = [{dependencies} ] +sources = [{source_files} +] + exe = executable( '{exe_name}', - '{source_name}', + [sources], dependencies : dependencies, install : true, ) diff --git a/mesonbuild/templates/dlangtemplates.py b/mesonbuild/templates/dlangtemplates.py index db3bdbf16..4ca91a69b 100644 --- a/mesonbuild/templates/dlangtemplates.py +++ b/mesonbuild/templates/dlangtemplates.py @@ -35,9 +35,13 @@ hello_d_meson_template = '''project( dependencies = [{dependencies} ] +sources = [{source_files} + +] + exe = executable( '{exe_name}', - '{source_name}', + [sources], dependencies : dependencies, install : true, ) @@ -84,10 +88,13 @@ lib_d_meson_template = '''project( dependencies = [{dependencies} ] +sources = [{source_files} + +] stlib = static_library( '{lib_name}', - '{source_file}', + [sources], install : true, gnu_symbol_visibility : 'hidden', dependencies : dependencies, diff --git a/mesonbuild/templates/javatemplates.py b/mesonbuild/templates/javatemplates.py index c30c7f7b5..458142e6b 100644 --- a/mesonbuild/templates/javatemplates.py +++ b/mesonbuild/templates/javatemplates.py @@ -35,9 +35,13 @@ hello_java_meson_template = '''project( dependencies = [{dependencies} ] +sources = [{source_files} + +] + exe = jar( '{exe_name}', - '{source_name}', + [sources], main_class : '{exe_name}', dependencies : dependencies, install : true, @@ -86,9 +90,13 @@ lib_java_meson_template = '''project( dependencies = [{dependencies} ] +sources = [{source_files} + +] + jarlib = jar( '{class_name}', - '{source_file}', + [sources], dependencies : dependencies, main_class : '{class_name}', install : true, diff --git a/mesonbuild/templates/sampleimpl.py b/mesonbuild/templates/sampleimpl.py index d033f3c14..00735c498 100644 --- a/mesonbuild/templates/sampleimpl.py +++ b/mesonbuild/templates/sampleimpl.py @@ -3,6 +3,7 @@ # Copyright © 2023-2025 Intel Corporation from __future__ import annotations +from pathlib import Path import abc import os @@ -17,6 +18,7 @@ class SampleImpl(metaclass=abc.ABCMeta): def __init__(self, args: Arguments): self.name = args.name + self.executable_name = args.executable if args.executable else None self.version = args.version self.lowercase_token = re.sub(r'[^a-z0-9]', '_', self.name.lower()) self.uppercase_token = self.lowercase_token.upper() @@ -24,6 +26,7 @@ class SampleImpl(metaclass=abc.ABCMeta): self.meson_version = '1.0.0' self.force = args.force self.dependencies = args.deps.split(',') if args.deps else [] + self.sources: list[Path] = [] @abc.abstractmethod def create_executable(self) -> None: @@ -66,11 +69,18 @@ class SampleImpl(metaclass=abc.ABCMeta): def _format_dependencies(self) -> str: return ''.join(f"\n dependency('{d}')," for d in self.dependencies) + def _format_sources(self) -> str: + return ''.join(f"\n '{x}'," for x in self.sources) + class ClassImpl(SampleImpl): """For Class based languages, like Java and C#""" + def __init__(self, args: Arguments): + super().__init__(args) + self.sources = args.srcfiles if args.srcfiles else [Path(f'{self.capitalized_token}.{self.source_ext}')] + def create_executable(self) -> None: source_name = f'{self.capitalized_token}.{self.source_ext}' if not os.path.exists(source_name): @@ -80,29 +90,32 @@ class ClassImpl(SampleImpl): if self.force or not os.path.exists('meson.build'): with open('meson.build', 'w', encoding='utf-8') as f: f.write(self.exe_meson_template.format(project_name=self.name, - exe_name=self.name, + exe_name=self.executable_name, source_name=source_name, version=self.version, meson_version=self.meson_version, - dependencies=self._format_dependencies())) + dependencies=self._format_dependencies(), + source_files=self._format_sources())) def create_library(self) -> None: lib_name = f'{self.capitalized_token}.{self.source_ext}' test_name = f'{self.capitalized_token}_test.{self.source_ext}' - kwargs = {'utoken': self.uppercase_token, - 'ltoken': self.lowercase_token, - 'class_test': f'{self.capitalized_token}_test', - 'class_name': self.capitalized_token, - 'source_file': lib_name, - 'test_source_file': test_name, - 'test_exe_name': f'{self.lowercase_token}_test', - 'project_name': self.name, - 'lib_name': self.lowercase_token, - 'test_name': self.lowercase_token, - 'version': self.version, - 'meson_version': self.meson_version, - 'dependencies': self._format_dependencies(), - } + kwargs = { + 'utoken': self.uppercase_token, + 'ltoken': self.lowercase_token, + 'class_test': f'{self.capitalized_token}_test', + 'class_name': self.capitalized_token, + 'source_file': lib_name, + 'test_source_file': test_name, + 'test_exe_name': f'{self.lowercase_token}_test', + 'project_name': self.name, + 'lib_name': self.lowercase_token, + 'test_name': self.lowercase_token, + 'version': self.version, + 'meson_version': self.meson_version, + 'dependencies': self._format_dependencies(), + 'source_files': self._format_sources(), + } if not os.path.exists(lib_name): with open(lib_name, 'w', encoding='utf-8') as f: f.write(self.lib_template.format(**kwargs)) @@ -118,6 +131,10 @@ class FileImpl(SampleImpl): """File based languages without headers""" + def __init__(self, args: Arguments): + super().__init__(args) + self.sources = args.srcfiles if args.srcfiles else [Path(f'{self.executable_name}.{self.source_ext}')] + def create_executable(self) -> None: source_name = f'{self.lowercase_token}.{self.source_ext}' if not os.path.exists(source_name): @@ -126,11 +143,12 @@ class FileImpl(SampleImpl): if self.force or not os.path.exists('meson.build'): with open('meson.build', 'w', encoding='utf-8') as f: f.write(self.exe_meson_template.format(project_name=self.name, - exe_name=self.name, + exe_name=self.executable_name, source_name=source_name, version=self.version, meson_version=self.meson_version, - dependencies=self._format_dependencies())) + dependencies=self._format_dependencies(), + source_files=self._format_sources())) def lib_kwargs(self) -> T.Dict[str, str]: """Get Language specific keyword arguments @@ -153,6 +171,7 @@ class FileImpl(SampleImpl): 'version': self.version, 'meson_version': self.meson_version, 'dependencies': self._format_dependencies(), + 'source_files': self._format_sources(), } def create_library(self) -> None: diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index 385b195ea..acf679541 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -2525,7 +2525,7 @@ class AllPlatformTests(BasePlatformTests): for lang in langs: for target_type in ('executable', 'library'): - with self.subTest(f'Language: {lang}; type: {target_type}'): + with self.subTest(f'Language: {lang}; type: {target_type}; fresh: yes'): if is_windows() and lang == 'fortran' and target_type == 'library': # non-Gfortran Windows Fortran compilers do not do shared libraries in a Fortran standard way # see "test cases/fortran/6 dynamic" @@ -2540,17 +2540,44 @@ class AllPlatformTests(BasePlatformTests): workdir=tmpdir) self._run(ninja, workdir=os.path.join(tmpdir, 'builddir')) - # test directory with existing code file - if lang in {'c', 'cpp', 'd'}: - with tempfile.TemporaryDirectory() as tmpdir: - with open(os.path.join(tmpdir, 'foo.' + lang), 'w', encoding='utf-8') as f: - f.write('int main(void) {}') - self._run(self.meson_command + ['init', '-b'], workdir=tmpdir) - elif lang in {'java'}: - with tempfile.TemporaryDirectory() as tmpdir: - with open(os.path.join(tmpdir, 'Foo.' + lang), 'w', encoding='utf-8') as f: - f.write('public class Foo { public static void main() {} }') - self._run(self.meson_command + ['init', '-b'], workdir=tmpdir) + + with self.subTest(f'Language: {lang}; type: {target_type}; fresh: no'): + # test directory with existing code file + if lang in {'c', 'cpp', 'd'}: + with tempfile.TemporaryDirectory() as tmpdir: + with open(os.path.join(tmpdir, 'foo.' + lang), 'w', encoding='utf-8') as f: + f.write('int main(void) {}') + self._run(self.meson_command + ['init', '-b'], workdir=tmpdir) + + # Check for whether we're doing source collection by repeating + # with a bogus file we should pick up (and then fail to compile). + with tempfile.TemporaryDirectory() as tmpdir: + with open(os.path.join(tmpdir, 'bar.' + lang), 'w', encoding='utf-8') as f: + f.write('#error bar') + self._run(self.meson_command + ['init'], workdir=tmpdir) + self._run(self.setup_command + ['--backend=ninja', 'builddir'], + workdir=tmpdir) + with self.assertRaises(subprocess.CalledProcessError): + self._run(ninja, + workdir=os.path.join(tmpdir, 'builddir')) + + elif lang in {'java'}: + with tempfile.TemporaryDirectory() as tmpdir: + with open(os.path.join(tmpdir, 'Foo.' + lang), 'w', encoding='utf-8') as f: + f.write('public class Foo { public static void main() {} }') + self._run(self.meson_command + ['init', '-b'], workdir=tmpdir) + + # Check for whether we're doing source collection by repeating + # with a bogus file we should pick up (and then fail to compile). + with tempfile.TemporaryDirectory() as tmpdir: + with open(os.path.join(tmpdir, 'Bar.' + lang), 'w', encoding='utf-8') as f: + f.write('public class Bar { public private static void main() {} }') + self._run(self.meson_command + ['init'], workdir=tmpdir) + self._run(self.setup_command + ['--backend=ninja', 'builddir'], + workdir=tmpdir) + with self.assertRaises(subprocess.CalledProcessError): + self._run(ninja, + workdir=os.path.join(tmpdir, 'builddir')) def test_compiler_run_command(self): ''' |
