aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/build.py
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2021-10-01 09:10:22 -0700
committerDylan Baker <dylan@pnwbakers.com>2022-03-07 12:33:33 -0800
commit39433762a9af1624be1c581b6f5cdb105b86bcd1 (patch)
tree4391c4936688d7a072d252ba0231e95f6e03fb90 /mesonbuild/build.py
parentda2cdacb28f1326799b6c3e039b4c2ea6cf3c35b (diff)
downloadmeson-39433762a9af1624be1c581b6f5cdb105b86bcd1.zip
meson-39433762a9af1624be1c581b6f5cdb105b86bcd1.tar.gz
meson-39433762a9af1624be1c581b6f5cdb105b86bcd1.tar.bz2
build: Add structured sources
Diffstat (limited to 'mesonbuild/build.py')
-rw-r--r--mesonbuild/build.py55
1 files changed, 55 insertions, 0 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index ecbc1d9..033941c 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -452,8 +452,63 @@ class ExtractedObjects(HoldableObject):
for source in self.get_sources(self.srclist, self.genlist)
]
+
+@dataclass(eq=False, order=False)
+class StructuredSources(HoldableObject):
+
+ """A container for sources in languages that use filesystem hierarchy.
+
+ Languages like Rust and Cython rely on the layout of files in the filesystem
+ as part of the compiler implementation. This structure allows us to
+ represent the required filesystem layout.
+ """
+
+ sources: T.DefaultDict[str, T.List[T.Union[str, File, CustomTarget, CustomTargetIndex, GeneratedList]]] = field(
+ default_factory=lambda: defaultdict(list))
+
+ def __add__(self, other: StructuredSources) -> StructuredSources:
+ sources = self.sources.copy()
+ for k, v in other.sources.items():
+ sources[k].extend(v)
+ return StructuredSources(sources)
+
+ def __bool__(self) -> bool:
+ return bool(self.sources)
+
+ def first_file(self) -> T.Union[str, File, CustomTarget, CustomTargetIndex, GeneratedList]:
+ """Get the first source in the root
+
+ :return: The first source in the root
+ """
+ return self.sources[''][0]
+
+ def as_list(self) -> T.List[T.Union[str, File, CustomTarget, CustomTargetIndex, GeneratedList]]:
+ return list(itertools.chain.from_iterable(self.sources.values()))
+
+ def needs_copy(self, target: BuildTarget) -> bool:
+ """Do we need to create a structure in the build directory.
+
+ This allows us to avoid making copies if the structures exists in the
+ source dir. Which could happen in situations where a generated source
+ only exists in some configurations
+ """
+ p = pathlib.Path(target.subdir)
+ for files in self.sources.values():
+ for f in files:
+ if isinstance(f, str):
+ if not (target.environment.source_dir / p / f).exists():
+ return True
+ elif isinstance(f, File):
+ if f.is_built:
+ return True
+ else:
+ return True
+ return False
+
+
EnvInitValueType = T.Dict[str, T.Union[str, T.List[str]]]
+
class EnvironmentVariables(HoldableObject):
def __init__(self, values: T.Optional[EnvInitValueType] = None,
init_method: Literal['set', 'prepend', 'append'] = 'set', separator: str = os.pathsep) -> None: