Skip to content

Commit

Permalink
build: improve the warning for executables with the same name
Browse files Browse the repository at this point in the history
adb1a36 added the feature and also the
usual meson-style warning to users that might be using the feature but
were not targeting a new enough meson version. Well unfortunately the
warning both doesn't actually work (it didn't take different directories
into account) and is also really slow because it creates an O(N^2) loop
for checking this.

Instead, rework this by adding an additional set that stores a tuple
containing the target name and its subdirectory. We only add this tuple
if the target is an executable since it is the only time it will be
relevant. After that, simply check if the name + subdir combination
already exists in the set along with the target being executable. If so,
then we execute FeatureNew which may possibly warn. This is a simply
O(1) lookup which is way faster. Fixes mesonbuild#12404.
  • Loading branch information
Dudemanguy authored and jpakkane committed Oct 25, 2023
1 parent ae7a9b0 commit e9e098b
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
1 change: 1 addition & 0 deletions mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ def __init__(self, environment: environment.Environment):
self.environment = environment
self.projects = {}
self.targets: 'T.OrderedDict[str, T.Union[CustomTarget, BuildTarget]]' = OrderedDict()
self.targetnames: T.Set[T.Tuple[str, str]] = set() # Set of executable names and their subdir
self.global_args: PerMachine[T.Dict[str, T.List[str]]] = PerMachine({}, {})
self.global_link_args: PerMachine[T.Dict[str, T.List[str]]] = PerMachine({}, {})
self.projects_args: PerMachine[T.Dict[str, T.Dict[str, T.List[str]]]] = PerMachine({}, {})
Expand Down
18 changes: 12 additions & 6 deletions mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3163,19 +3163,25 @@ def add_target(self, name: str, tobj: build.Target) -> None:
# To permit an executable and a shared library to have the
# same name, such as "foo.exe" and "libfoo.a".
idname = tobj.get_id()
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)
subdir = tobj.get_subdir()
namedir = (name, subdir)

if idname in self.build.targets:
raise InvalidCode(f'Tried to create target "{name}", but a target of that name already exists.')

if isinstance(tobj, build.Executable) and namedir in self.build.targetnames:
FeatureNew.single_use(f'multiple executables with the same name, "{tobj.name}", but different suffixes in the same directory',
'1.3.0', self.subproject, location=self.current_node)

if isinstance(tobj, build.BuildTarget):
self.add_languages(tobj.missing_languages, True, tobj.for_machine)
tobj.process_compilers_late()
self.add_stdlib_info(tobj)

self.build.targets[idname] = tobj
# Only need to add executables to this set
if isinstance(tobj, build.Executable):
self.build.targetnames.update([namedir])
if idname not in self.coredata.target_guids:
self.coredata.target_guids[idname] = str(uuid.uuid4()).upper()

Expand Down

0 comments on commit e9e098b

Please sign in to comment.