summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/templates/cpptemplates.py11
-rw-r--r--mesonbuild/templates/ctemplates.py10
-rw-r--r--mesonbuild/templates/dlangtemplates.py11
-rw-r--r--mesonbuild/templates/javatemplates.py12
-rw-r--r--mesonbuild/templates/sampleimpl.py55
-rw-r--r--unittests/allplatformstests.py51
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):
'''