diff options
| author | Luke Elliott <luke.b.elliott@gmail.com> | 2023-08-09 08:39:08 +0100 |
|---|---|---|
| committer | Eli Schwartz <eschwartz93@gmail.com> | 2023-09-26 02:29:25 -0400 |
| commit | b6b68d7ee687682ce529617e8ace48b582d0dbf1 (patch) | |
| tree | 3ebd5e64c02c7717cdef54c8abb23e02c5507c02 | |
| parent | 14ac4e3528bfcf5d12c20020fab7dbf95757e8a8 (diff) | |
| download | meson-b6b68d7ee687682ce529617e8ace48b582d0dbf1.tar.gz | |
vs2010backend: avoid duplicated directory structure in vcxproj.filters
Root the vcxproj.filters at the directory containing the meson.build
defining the target.
Co-authored-by: Joshua Ashton <joshua@froggi.es>
| -rw-r--r-- | mesonbuild/backend/vs2010backend.py | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 943dffa4f..0b6be1c79 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -20,7 +20,7 @@ import xml.dom.minidom import xml.etree.ElementTree as ET import uuid import typing as T -from pathlib import Path, PurePath +from pathlib import Path, PurePath, PureWindowsPath import re from collections import Counter @@ -1809,8 +1809,76 @@ class Vs2010Backend(backends.Backend): # build system as possible. self.add_target_deps(root, target) self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname) + if self.environment.coredata.get_option(OptionKey('layout')) == 'mirror': + self.gen_vcxproj_filters(target, ofname) return True + def gen_vcxproj_filters(self, target, ofname): + # Generate pitchfork of filters based on directory structure. + root = ET.Element('Project', {'ToolsVersion': '4.0', + 'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003'}) + filter_folders = ET.SubElement(root, 'ItemGroup') + filter_items = ET.SubElement(root, 'ItemGroup') + mlog.debug(f'Generating vcxproj filters {target.name}.') + + def relative_to_defined_in(file): + # Get the relative path to file's directory from the location of the meson.build that defines this target. + return os.path.dirname(self.relpath(PureWindowsPath(file.subdir, file.fname), self.get_target_dir(target))) + + found_folders_to_filter = {} + all_files = target.sources + target.extra_files + + # Build a dictionary of all used relative paths (i.e. from the meson.build defining this target) + # for all sources. + for i in all_files: + if not os.path.isabs(i.fname): + dirname = relative_to_defined_in(i) + if dirname: + found_folders_to_filter[dirname] = '' + + # Now walk up each of those relative paths checking for empty intermediate dirs to generate the filter. + for folder in found_folders_to_filter: + dirname = folder + filter = '' + + while dirname: + basename = os.path.basename(dirname) + + if filter == '': + filter = basename + else: + # Use '/' to squash empty dirs. To actually get a '\', use '%255c'. + filter = basename + ('\\' if dirname in found_folders_to_filter else '/') + filter + + dirname = os.path.dirname(dirname) + + # Don't add an empty filter, breaks all other (?) filters. + if filter != '': + found_folders_to_filter[folder] = filter + filter_element = ET.SubElement(filter_folders, 'Filter', {'Include': filter}) + uuid_element = ET.SubElement(filter_element, 'UniqueIdentifier') + uuid_element.text = '{' + str(uuid.uuid4()).upper() + '}' + + sources, headers, objects, _ = self.split_sources(all_files) + down = self.target_to_build_root(target) + + def add_element(type_name, elements): + for i in elements: + if not os.path.isabs(i.fname): + dirname = relative_to_defined_in(i) + + if dirname and dirname in found_folders_to_filter: + relpath = os.path.join(down, i.rel_to_builddir(self.build_to_src)) + target_element = ET.SubElement(filter_items, type_name, {'Include': relpath}) + filter_element = ET.SubElement(target_element, 'Filter') + filter_element.text = found_folders_to_filter[dirname] + + add_element('ClCompile', sources) + add_element('ClInclude', headers) + add_element('Object', objects) + + self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname + '.filters') + def gen_regenproj(self): # To fully adapt the REGEN work for a 'genvslite' solution, to check timestamps, settings, and regenerate the # '[builddir]_vs' solution/vcxprojs, as well as regenerating the accompanying buildtype-suffixed ninja build |
