diff options
| -rw-r--r-- | docs/markdown/snippets/executable-suffixes.md | 14 | ||||
| -rw-r--r-- | docs/yaml/functions/executable.yaml | 3 | ||||
| -rw-r--r-- | mesonbuild/build.py | 14 | ||||
| -rw-r--r-- | mesonbuild/interpreter/interpreter.py | 8 | ||||
| -rw-r--r-- | test cases/unit/119 executable suffix/main.c | 1 | ||||
| -rw-r--r-- | test cases/unit/119 executable suffix/meson.build | 3 | ||||
| -rw-r--r-- | unittests/allplatformstests.py | 10 |
7 files changed, 49 insertions, 4 deletions
diff --git a/docs/markdown/snippets/executable-suffixes.md b/docs/markdown/snippets/executable-suffixes.md new file mode 100644 index 000000000..44471e9dd --- /dev/null +++ b/docs/markdown/snippets/executable-suffixes.md @@ -0,0 +1,14 @@ +## Target names for executables now take into account suffixes. + +In previous versions of meson, a `meson.build` file like this: + +``` +exectuable('foo', 'main.c') +exectuable('foo', 'main.c', name_suffix: 'bar') +``` + +would result in a configure error because meson internally used +the same id for both executables. This build file is now allowed +since meson takes into account the `bar` suffix when generating the +second executable. This allows for executables with the same basename +but different suffixes to be built in the same subdirectory. diff --git a/docs/yaml/functions/executable.yaml b/docs/yaml/functions/executable.yaml index 380759457..abbc5feee 100644 --- a/docs/yaml/functions/executable.yaml +++ b/docs/yaml/functions/executable.yaml @@ -10,6 +10,9 @@ description: | The returned object also has methods that are documented in [[@exe]]. + *Since 1.3.0* executable names can be the same across multiple targets as + long as they each have a different `name_suffix`. + warnings: - The `link_language` kwarg was broken until 0.55.0 diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 4c07d9691..d1888d7b2 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -634,8 +634,11 @@ class Target(HoldableObject, metaclass=abc.ABCMeta): return my_id def get_id(self) -> str: + name = self.name + if getattr(self, 'name_suffix_set', False): + name += '.' + self.suffix return self.construct_id_from_path( - self.subdir, self.name, self.type_suffix()) + self.subdir, name, self.type_suffix()) def process_kwargs_base(self, kwargs: T.Dict[str, T.Any]) -> None: if 'build_by_default' in kwargs: @@ -2013,7 +2016,14 @@ class Executable(BuildTarget): and self.environment.coredata.get_option(OptionKey("debug")) ) if create_debug_file: - self.debug_filename = self.name + '.pdb' + # If the target is has a standard exe extension (i.e. 'foo.exe'), + # then the pdb name simply becomes 'foo.pdb'. If the extension is + # something exotic, then include that in the name for uniqueness + # reasons (e.g. 'foo_com.pdb'). + name = self.name + if getattr(self, 'suffix', 'exe') != 'exe': + name += '_' + self.suffix + self.debug_filename = name + '.pdb' def process_kwargs(self, kwargs): super().process_kwargs(kwargs) diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 05581afeb..0b6ccef22 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -3169,8 +3169,12 @@ class Interpreter(InterpreterBase, HoldableObject): # To permit an executable and a shared library to have the # same name, such as "foo.exe" and "libfoo.a". idname = tobj.get_id() - if idname in self.build.targets: - raise InvalidCode(f'Tried to create target "{name}", but a target of that name already exists.') + for t in self.build.targets.values(): + if t.get_id() == idname: + raise InvalidCode(f'Tried to create target "{name}", but a target of that name already exists.') + if isinstance(tobj, build.Executable) and isinstance(t, build.Executable) and t.name == tobj.name: + FeatureNew.single_use('multiple executables with the same name but different suffixes', + '1.3.0', self.subproject, location=self.current_node) if isinstance(tobj, build.BuildTarget): self.add_languages(tobj.missing_languages, True, tobj.for_machine) diff --git a/test cases/unit/119 executable suffix/main.c b/test cases/unit/119 executable suffix/main.c new file mode 100644 index 000000000..78f2de106 --- /dev/null +++ b/test cases/unit/119 executable suffix/main.c @@ -0,0 +1 @@ +int main(void) { return 0; } diff --git a/test cases/unit/119 executable suffix/meson.build b/test cases/unit/119 executable suffix/meson.build new file mode 100644 index 000000000..8f952260c --- /dev/null +++ b/test cases/unit/119 executable suffix/meson.build @@ -0,0 +1,3 @@ +project('exectuable suffix', 'c') +foo = executable('foo', 'main.c') +foo_bin = executable('foo', 'main.c', name_suffix: 'bin') diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index 4ee0de469..030b216d7 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -2039,6 +2039,16 @@ class AllPlatformTests(BasePlatformTests): original = get_opt() self.assertDictEqual(original, expected) + def test_executable_names(self): + testdir = os.path.join(self.unit_test_dir, '119 executable suffix') + self.init(testdir) + self.build() + exe1 = os.path.join(self.builddir, 'foo' + exe_suffix) + exe2 = os.path.join(self.builddir, 'foo.bin') + self.assertPathExists(exe1) + self.assertPathExists(exe2) + self.assertNotEqual(exe1, exe2) + def opt_has(self, name, value): res = self.introspect('--buildoptions') found = False |
